diff options
author | Stefan Kost <ensonic@users.sf.net> | 2010-09-15 18:10:33 +0300 |
---|---|---|
committer | Stefan Kost <ensonic@users.sf.net> | 2010-09-15 18:22:51 +0300 |
commit | bc1c9ac18e2a538f2ce938dc59bd392e741cb61c (patch) | |
tree | cdd27653c534da363bfc009798895748933ff3d1 /ext | |
parent | 5b6550dbd54e91c22ffa85aa4a784287d2af2a89 (diff) | |
download | gstreamer-plugins-bad-bc1c9ac18e2a538f2ce938dc59bd392e741cb61c.tar.gz |
metadata: remove metadata plugin
This plugins functionality is replaced by utility libraries in base for exif
and xmp. Jpeg images can use this via jpegformat plugin.
Fixes #486659
Diffstat (limited to 'ext')
35 files changed, 0 insertions, 12744 deletions
diff --git a/ext/Makefile.am b/ext/Makefile.am index 9af726a8d..3893c6274 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -202,12 +202,6 @@ else MPEG2ENC_DIR= endif -if USE_METADATA -METADATA_DIR=metadata -else -METADATA_DIR= -endif - if USE_MIMIC MIMIC_DIR=mimic else @@ -421,7 +415,6 @@ SUBDIRS=\ $(LIBMMS_DIR) \ $(MODPLUG_DIR) \ $(MPEG2ENC_DIR) \ - $(METADATA_DIR) \ $(MIMIC_DIR) \ $(MPLEX_DIR) \ $(MUSEPACK_DIR) \ @@ -476,7 +469,6 @@ DIST_SUBDIRS = \ dts \ divx \ modplug \ - metadata \ mimic \ mpeg2enc \ mplex \ diff --git a/ext/metadata/.gitignore b/ext/metadata/.gitignore deleted file mode 100644 index 08f5ed37d..000000000 --- a/ext/metadata/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -Makefile -Makefile.in -*.o -*.lo -*.la -.deps -.libs diff --git a/ext/metadata/Makefile.am b/ext/metadata/Makefile.am deleted file mode 100644 index 43f36fd1a..000000000 --- a/ext/metadata/Makefile.am +++ /dev/null @@ -1,39 +0,0 @@ -plugin_LTLIBRARIES = libgstmetadata.la - -libgstmetadata_la_SOURCES = gstmetadata.c \ - gstmetadatademux.c \ - metadata.c \ - metadataparsejpeg.c \ - metadatamuxjpeg.c \ - metadataparsepng.c \ - metadatamuxpng.c \ - metadataexif.c \ - metadataiptc.c \ - metadataxmp.c \ - metadataparseutil.c \ - metadatatypes.c \ - gstmetadatamux.c \ - metadatatags.c \ - gstbasemetadata.c - -libgstmetadata_la_CFLAGS = $(METADATA_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) -libgstmetadata_la_LIBADD = $(METADATA_LIBS) -lgsttag-@GST_MAJORMINOR@ $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS) -libgstmetadata_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -libgstmetadata_la_LIBTOOLFLAGS = --tag=disable-static - -noinst_HEADERS = gstmetadatademux.h \ - metadata.h \ - metadataparsejpeg.h \ - metadatamuxjpeg.h \ - metadataparsepng.h \ - metadatamuxpng.h \ - metadataexif.h \ - metadataiptc.h \ - metadataxmp.h \ - metadataparseutil.h \ - metadatatags.h \ - metadatatypes.h \ - gstmetadatamux.h \ - gstbasemetadata.h - -EXTRA_DIST = metadata_mapping.htm diff --git a/ext/metadata/README b/ext/metadata/README deleted file mode 100644 index 8afd33c7b..000000000 --- a/ext/metadata/README +++ /dev/null @@ -1,106 +0,0 @@ -### design proposal for metadata mux and parser ### - -## use cases ## - -1- Create metadata - -[ App send tag events to the pipeline ] - || /\ - || || - || jpegenc send tag messages like (width, height and compression info) - || || - \/ || -+---------+ +---------+ +-------------+ +----------+ -| v4l2src | -> | jpegenc | -> | metadatamux | -> | filesink | -+---------+ +---------+ +-------------+ +----------+ - -* elements like videoscale should also send (width and height tags) -* should metadatamux get info from caps (width and height) and use if not receive a event with such tags? - - -2- View metadata - -+---------+ +---------------+ +---------+ +-------------+ -| filesrc | -> | metadataparse | -> | jpegdec | -> | xvimagesink | -+---------+ +---------------+ +---------+ +-------------+ - -or - - +--> whole chunk send as event to next element - | -+---------+ +---------------+ +----------+ -| filesrc | -> | metadataparse | -> | fakesink | -+---------+ +---------------+ +----------+ - || - \/ - 1- individual tags send as messages (what about not mapped tags??) - 2- whole chunk send as message (probably the application will ignore this) - -* in any case metadataparse strips out metadata chunks (different from current implementation) - - -3- Modify (add, change, delete tags) - - +--> whole chunk send as event to next element -- ... --+ - | | - | V -+---------+ +---------------+ +-------------+ +----------+ -| filesrc | -> | metadataparse | --------------- ... --------------> | metadatamux | -> | filesink | -+---------+ +---------------+ +-------------+ +----------+ - /\ || - || \/ - || 1- individual tags send as messages (what about not mapped tags??) ==============\\ - || 2- whole chunk send as message (probably the application will ignore this) || - || || -[ App send tag events to the pipeline ] <=======================================================// - -* metadataparse strips out metadata chunks (different from current implementation) -* application receives individual tag messages (what about not mapped ones?) - * the application only send events back to the pipeline for the tags the application wants to modify or keep. - The tags not sent will not be included in metadata chunks -* the metadatamux modify the whole chunk event received before to just keep the individual tags sent by application -* the metadatamux could have a property to say if it should remove or keep tags not sent by application. - -Obs: By looking at the proposed design (1- view and 2- modify) seems that the metadataparse and metadatamux should not know about mapped tags. - Only the application map the tags to/from metadata specific format. This is because, if you notice, only tags sent by application will be keep - on new file. - - -4- Convert (for example from jpeg to png) - - +--> whole chunk send as event to next element -- ... --+ - | | - | V -+---------+ +---------------+ +-------------+ +----------+ -| filesrc | -> | metadataparse | -> | jpegdec | -> ... -> | pngenc | -> | metadatamux | -> | filesink | -+---------+ +---------------+ +-------------+ +----------+ - /\ || - || \/ - || 1- individual tags send as messages (what about not mapped tags??) ==============\\ - || 2- whole chunk send as message (probably the application will ignore this) || - || || -[ App send tag events to the pipeline ] <=======================================================// - -* in this case the application set the metadatamux property to always keep the tags by default (application don't not need to send tag events) -* metadatamux needs additional smartness to check what tags still does make sense (some from original jpeg may not make sense anymore) -* if the image is resized, the videoscale should send messages to the application with new width (in the same way pngenc should also) and the - application could send width and height tag events to the pipeline -* should metadatamux get info from caps (width and height) and use if not receive a event with such tags? - - -Testing -GST_DEBUG="*:2,metadata*:4" -gst-launch videotestsrc num-buffers=1 ! jpegenc ! taginject tags="geo-location-latitude=66.1,geo-location-longitude=22.5,geo-location-elevation=10.3" ! metadatamux ! filesink location="meta_test_ppp.jpeg" -gst-launch videotestsrc num-buffers=1 ! jpegenc ! taginject tags="geo-location-latitude=66.1,geo-location-longitude=22.5,geo-location-elevation=-10.3" ! metadatamux ! filesink location="meta_test_ppn.jpeg" -gst-launch videotestsrc num-buffers=1 ! jpegenc ! taginject tags="geo-location-latitude=66.1,geo-location-longitude=-22.5,geo-location-elevation=10.3" ! metadatamux ! filesink location="meta_test_pnp.jpeg" -gst-launch videotestsrc num-buffers=1 ! jpegenc ! taginject tags="geo-location-latitude=66.1,geo-location-longitude=-22.5,geo-location-elevation=-10.3" ! metadatamux ! filesink location="meta_test_pnn.jpeg" -gst-launch videotestsrc num-buffers=1 ! jpegenc ! taginject tags="geo-location-latitude=-66.1,geo-location-longitude=22.5,geo-location-elevation=10.3" ! metadatamux ! filesink location="meta_test_npp.jpeg" -gst-launch videotestsrc num-buffers=1 ! jpegenc ! taginject tags="geo-location-latitude=-66.1,geo-location-longitude=22.5,geo-location-elevation=-10.3" ! metadatamux ! filesink location="meta_test_npn.jpeg" -gst-launch videotestsrc num-buffers=1 ! jpegenc ! taginject tags="geo-location-latitude=-66.1,geo-location-longitude=-22.5,geo-location-elevation=10.3" ! metadatamux ! filesink location="meta_test_nnp.jpeg" -gst-launch videotestsrc num-buffers=1 ! jpegenc ! taginject tags="geo-location-latitude=-66.1,geo-location-longitude=-22.5,geo-location-elevation=-10.3" ! metadatamux ! filesink location="meta_test_nnn.jpeg" - -exiv2 -pt pr meta_test_ppp.jpeg | grep "Exif.GPSInfo" -exif meta_test_ppp.jpeg - -gst-launch -t filesrc location="meta_test_ppp.jpeg" ! metadatademux ! fakesink - diff --git a/ext/metadata/TODO b/ext/metadata/TODO deleted file mode 100644 index db258da30..000000000 --- a/ext/metadata/TODO +++ /dev/null @@ -1,56 +0,0 @@ - -This file contains a list of things to be done as well some open issues (questions) related to design/implementation. - -INFO: - -1- To see the list of tags current mapped: - http://webcvs.freedesktop.org/gstreamer/gst-plugins-bad/ext/metadata/metadata_mapping.htm?view=co - -TODO: - -1- Add more individual tags to XMP, EXIF and IPTC -2- Get properties like 'width' and 'height' from caps -3- Review the code (in order to move to gst-plugins-good) -4- Document how the plugin works (atchitecture and interaction beteween modules) -5- Improve the test application (to save also in png and to make it possible to set the metadata elements properties) -6- Implement GDateTime support in GLib to be used by GStreamer (http://bugzilla.gnome.org/show_bug.cgi?id=50076) -7- Use a standard GStreamer Data-Time type to map our Data-time tags -8- Make the correct merge mode for multiple value tags (bag and seq) like dc:creator, ... - -OPEN ISSUES: - -1- What is (How) the best way to delete some tag? -2- How to change metadata when the orignal image was modified. - ex: file.jpeg has XMP, then we do filesrc ! metadataparse ! jpegdec ! pngenc ! metadatamux ! files - is the metadata still valid? which fields are no valid anymore? -3- In EXIF, how to make sure we are compliant with the specification when adding some tag? For example, we are not considerinb what are mandatory (or optional) IFDs for tags. -4- Add GST_TYPE_FRACTION support for GStreamer TAGS -5- currently, in JPEG files, if there is a Photoshop segment, everything inside it but IPTC will be lost. From the point of view of implementation it is easy, but I still don't now how to solve from the point of view of "designing". Anyway I think it is not so important. -6- language is not considered in XMP (How to do it with GStreamer?) -7- Add a helper function that convert from value to string. For example, -aperture-size is 2.7 and the app wants to show "f/2.7", 'contrast' is a range -and the app wants to show as "Normal", "Soft", "Hard". For the time being it is -up to the APP to make this conversion. - -LINKS IN BUGZILA - -1- to move to good - http://bugzilla.gnome.org/show_bug.cgi?id=513182 -2- Proposal of new tags - http://bugzilla.gnome.org/show_bug.cgi?id=482947 - http://bugzilla.gnome.org/show_bug.cgi?id=481169 -3- Discussion about the architecture - http://bugzilla.gnome.org/show_bug.cgi?id=486659 - -KNOWN BUGS - -bugs in libexif: - -1- https://sourceforge.net/tracker/?func=detail&atid=112272&aid=1884609&group_id=12272 - - a- EXIF_TAG_ISO_SPEED_RATINGS should be in EXIF_IFD_EXIF - b- EXIF_TAG_ISO_SPEED_RATINGS is not inserted anyway - -2- EXIF_TAG_FLASH can't be written from the scratch - -3- GST_TAG_CAPTURE_COLOR_SPACE can't be written from the scratch diff --git a/ext/metadata/gstbasemetadata.c b/ext/metadata/gstbasemetadata.c deleted file mode 100644 index 28579313f..000000000 --- a/ext/metadata/gstbasemetadata.c +++ /dev/null @@ -1,2010 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION: gstbasemetadata - * @short_description: Base class for metadata handling elements - * - * This is a generice base class for metadata handling elements. The following - * types of elements are supported: - * <itemizedlist> - * <listitem><para>parsers (only parse data)</para></listitem> - * <listitem><para>demuxers (parse data and remove metadata chunks)</para> - * </listitem> - * <listitem><para>muxers</para></listitem> - * <listitem><para>any other kind of element that wants to handle chunks in - * file formats based on chunks</para></listitem> - * </itemizedlist> - * - * <refsect2> - * <para> - * This a abstract element that parses a stream and find chunks and offset - * where new chunks could be injected into it. - * Basically, the only thing need by implementors (parsers, (de)muxers) is to - * set virtual methods that will be used to setup the caps and do some - * 'processing', which is called after the stream is completely parsed and - * before the first buffer is sent to the next element. Usualy the 'processing' - * function will send tags messages and event in case of parsers and demuxers, - * and add chunks to be injected (using the helper function - * #gst_base_metadata_update_inject_segment_with_new_data in case of muxers. - * </para> - * <para> - * This can work in 'pull' and 'push' scheduling modes. In case of push mode, - * the stream will be parsed during sink activation if #gst_pad_get_range is - * available on upstream element. If get_range function is not available - * upstream, then the data will be hold until the stream is completly parsed, - * and then after that the fisrt buffer will be pushed downstream. The same - * happens with pull mode, if the downstream element calls gst_pad_get_range - * it will only gets data after the stream has been completely parsed. - * </para> - * <para> - * Seek, and query duration will only be available after the stream has been - * parsed. Query position will always be 0 (zero) before the stream is - * completely parsed. - * </para> - * <para> - * Currently there is implementation for JPEG and PNG (demux mode only) - * stream types and EXIF, IPTC and XMP metadatas. - * </para> - * </refsect2> - * - * Last reviewed on 2008-01-21 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <gst/gst.h> - -#include "gstbasemetadata.h" - -#include "metadataxmp.h" - -#include <string.h> - -/* - * enum and types - */ - -enum -{ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_EXIF, - ARG_IPTC, - ARG_XMP -}; - -/* - * defines and static global vars - */ - -GST_DEBUG_CATEGORY_STATIC (gst_base_metadata_debug); -#define GST_CAT_DEFAULT gst_base_metadata_debug - -static GstBaseMetadataClass *parent_class = NULL; - -/* - * static helper functions declaration - */ - -static void gst_base_metadata_init_members (GstBaseMetadata * filter); - -static void gst_base_metadata_dispose_members (GstBaseMetadata * filter); - -const gchar *gst_base_metadata_get_type_name (int img_type); - -static gboolean gst_base_metadata_pull_range_parse (GstBaseMetadata * filter); - -static gboolean gst_base_metadata_configure_caps (GstBaseMetadata * filter); - -static gboolean gst_base_metadata_processing (GstBaseMetadata * filter); - -static void gst_base_metadata_reset_streaming (GstBaseMetadata * filter); - -static void gst_base_metadata_reset_parsing (GstBaseMetadata * filter); - -static int -gst_base_metadata_parse (GstBaseMetadata * filter, const guint8 * buf, - guint32 size); - -static gboolean -gst_base_metadata_strip_push_buffer (GstBaseMetadata * base, - const gint64 offset_orig, GstBuffer ** prepend, GstBuffer ** buf, - gboolean inject_begin); - -static int -gst_base_metadata_buf_get_intersection_seg (const gint64 offset, guint32 size, - const gint64 seg_offset, const guint32 seg_size, - gint64 * boffset, guint32 * bsize); - -static gboolean -gst_base_metadata_translate_pos_to_orig (GstBaseMetadata * base, - gint64 pos, gint64 * orig_pos, GstBuffer ** buf, guint32 max_size); - -static gboolean gst_base_metadata_calculate_offsets (GstBaseMetadata * base); - - -/* - * GObject callback functions declaration - */ - -static void gst_base_metadata_base_init (gpointer gclass); - -static void gst_base_metadata_class_init (GstBaseMetadataClass * klass); - -static void -gst_base_metadata_init (GstBaseMetadata * filter, - GstBaseMetadataClass * gclass); - -static void gst_base_metadata_dispose (GObject * object); - -static void gst_base_metadata_finalize (GObject * object); - -static void gst_base_metadata_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - -static void gst_base_metadata_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -/* - * GStreamer callback functions declaration - */ - -static GstStateChangeReturn -gst_base_metadata_change_state (GstElement * element, - GstStateChange transition); - -static gboolean gst_base_metadata_src_event (GstPad * pad, GstEvent * event); - -static gboolean gst_base_metadata_sink_event (GstPad * pad, GstEvent * event); - -static gboolean gst_base_metadata_checkgetrange (GstPad * srcpad); - -static GstFlowReturn -gst_base_metadata_get_range (GstPad * pad, guint64 offset_orig, guint size, - GstBuffer ** buf); - -static GstFlowReturn gst_base_metadata_chain (GstPad * pad, GstBuffer * buf); - -static gboolean gst_base_metadata_sink_activate (GstPad * pad); - -static gboolean -gst_base_metadata_src_activate_pull (GstPad * pad, gboolean active); - -static const GstQueryType *gst_base_metadata_get_query_types (GstPad * pad); - -static gboolean gst_base_metadata_src_query (GstPad * pad, GstQuery * query); - -/* - * GST BOILERPLATE - */ - -GType -gst_base_metadata_get_type (void) -{ - static GType base_metadata_type = 0; - - if (G_UNLIKELY (base_metadata_type == 0)) { - static const GTypeInfo base_metadata_info = { - sizeof (GstBaseMetadataClass), - (GBaseInitFunc) gst_base_metadata_base_init, - NULL, - (GClassInitFunc) gst_base_metadata_class_init, - NULL, - NULL, - sizeof (GstBaseMetadata), - 0, - (GInstanceInitFunc) gst_base_metadata_init, - }; - - base_metadata_type = g_type_register_static (GST_TYPE_ELEMENT, - "GstBaseMetadata", &base_metadata_info, G_TYPE_FLAG_ABSTRACT); - } - return base_metadata_type; -} - -/* - *static helper functions implementation - */ - -static void -gst_base_metadata_init_members (GstBaseMetadata * filter) -{ - - filter->metadata = NULL; - - filter->img_type = IMG_NONE; - - filter->duration_orig = 0; - filter->duration = 0; - - filter->state = MT_STATE_NULL; - - filter->options = META_OPT_EXIF | META_OPT_IPTC | META_OPT_XMP; - - filter->need_processing = FALSE; - - filter->adapter_parsing = NULL; - filter->adapter_holding = NULL; - filter->next_offset = 0; - filter->next_size = 0; - filter->need_more_data = FALSE; - filter->offset_orig = 0; - filter->offset = 0; - - filter->append_buffer = NULL; - filter->prepend_buffer = NULL; - -} - -static void -gst_base_metadata_dispose_members (GstBaseMetadata * filter) -{ - - /* buffers used to build output buffer */ - - if (filter->prepend_buffer) { - gst_buffer_unref (filter->prepend_buffer); - filter->prepend_buffer = NULL; - } - - if (filter->append_buffer) { - gst_buffer_unref (filter->append_buffer); - filter->append_buffer = NULL; - } - - /* adapter used during parsing process */ - - if (filter->adapter_parsing) { - g_object_unref (filter->adapter_parsing); - filter->adapter_parsing = NULL; - } - - if (filter->adapter_holding) { - g_object_unref (filter->adapter_holding); - filter->adapter_holding = NULL; - } - - metadata_dispose (&filter->metadata); - -} - -const gchar * -gst_base_metadata_get_type_name (int img_type) -{ - const gchar *type_name = NULL; - - switch (img_type) { - case IMG_JPEG: - type_name = "jpeg"; - break; - case IMG_PNG: - type_name = "png"; - break; - default: - type_name = "invalid type"; - break; - } - return type_name; -} - -static gboolean -gst_base_metadata_pull_range_parse (GstBaseMetadata * filter) -{ - - int res; - gboolean ret = TRUE; - guint32 offset = 0; - gint64 duration = 0; - GstFormat format = GST_FORMAT_BYTES; - - if (!(ret = - gst_pad_query_peer_duration (filter->sinkpad, &format, &duration))) { - /* this should never happen, but try chain anyway */ - ret = TRUE; - goto done; - } - filter->duration_orig = duration; - - if (format != GST_FORMAT_BYTES) { - /* this should never happen, but try chain anyway */ - ret = TRUE; - goto done; - } - - do { - GstFlowReturn flow; - GstBuffer *buf = NULL; - - offset += filter->next_offset; - - /* 'filter->next_size' only says the minimum required number of bytes. - We try provided more bytes (4096) just to avoid a lot of calls to - 'metadata_parse' - returning META_PARSING_NEED_MORE_DATA */ - if (filter->next_size < 4096) { - if (duration - offset < 4096) { - /* In case there is no 4096 bytes available upstream. - It should be done upstream but we do here for safety */ - filter->next_size = duration - offset; - } else { - filter->next_size = 4096; - } - } - - flow = - gst_pad_pull_range (filter->sinkpad, offset, filter->next_size, &buf); - if (GST_FLOW_OK != flow) { - ret = FALSE; - goto done; - } - - res = - gst_base_metadata_parse (filter, GST_BUFFER_DATA (buf), - GST_BUFFER_SIZE (buf)); - if (res == META_PARSING_ERROR) { - ret = FALSE; - goto done; - } - - gst_buffer_unref (buf); - - } while (res == META_PARSING_NEED_MORE_DATA); - -done: - - return ret; - -} - -static gboolean -gst_base_metadata_configure_caps (GstBaseMetadata * filter) -{ - GstCaps *caps = NULL; - gboolean ret = FALSE; - const gchar *mime = NULL; - GstPad *peer = NULL; - - peer = gst_pad_get_peer (filter->sinkpad); - - switch (filter->img_type) { - case IMG_JPEG: - mime = "image/jpeg"; - break; - case IMG_PNG: - mime = "image/png"; - break; - default: - goto done; - break; - } - - caps = gst_caps_new_simple (mime, NULL); - - if (!gst_pad_set_caps (peer, caps)) { - goto done; - } - - ret = gst_pad_set_caps (filter->sinkpad, caps); - -done: - - if (caps) { - gst_caps_unref (caps); - caps = NULL; - } - - if (peer) { - gst_object_unref (peer); - peer = NULL; - } - - return ret; - -} - -/* - * gst_base_metadata_processing: - * @filter: the base metadata instance - * - * Do some external 'process', if not done yet, just after parse the stream - * and before give the fisrt buffer downstream. - * Typically here the tag message and events will be sent, in case of demuxer - * and new chunks will be added in case of muxers. - * @see_also: #gst_base_metadata_calculate_offsets - * - * Returns: - * <itemizedlist> - * <listitem><para>%TRUE no need futher processing, or the processing has - * been done</para></listitem> - * <listitem><para>%FALSE, if error. It is, need futher processing but - * #gst_base_metadata_calculate_offsets fails</para></listitem> - * </itemizedlist> - * - */ - -static gboolean -gst_base_metadata_processing (GstBaseMetadata * filter) -{ - gboolean ret = TRUE; - GstBaseMetadataClass *bclass = GST_BASE_METADATA_GET_CLASS (filter); - - if (filter->need_processing) { - bclass->processing (filter); - if (gst_base_metadata_calculate_offsets (filter)) { - filter->need_processing = FALSE; - } else { - ret = FALSE; - } - } - - return ret; - -} - -/* - * gst_base_metadata_reset_streaming: - * @filter: the base metadata instance - * - * Clean the streaming process. The parser status is not changed. - * @see_also: #gst_base_metadata_reset_parsing - * - * Returns: nothing - * - */ - -static void -gst_base_metadata_reset_streaming (GstBaseMetadata * filter) -{ - filter->offset_orig = 0; - filter->offset = 0; - if (filter->adapter_holding) - gst_adapter_clear (filter->adapter_holding); -} - -/* - * gst_base_metadata_reset_parsing: - * @filter: the base metadata instance - * - * Reset the parsing process to start from the beginning again. - * @see_also: #gst_base_metadata_reset_streaming - * - * Returns: nothing - * - */ - -static void -gst_base_metadata_reset_parsing (GstBaseMetadata * filter) -{ - if (filter->prepend_buffer) { - gst_buffer_unref (filter->prepend_buffer); - filter->prepend_buffer = NULL; - } - - if (filter->append_buffer) { - gst_buffer_unref (filter->append_buffer); - filter->append_buffer = NULL; - } - - if (filter->adapter_parsing) - gst_adapter_clear (filter->adapter_parsing); - - if (filter->adapter_holding) - gst_adapter_clear (filter->adapter_holding); - - filter->img_type = IMG_NONE; - filter->duration_orig = 0; - filter->duration = 0; - filter->state = MT_STATE_NULL; - filter->need_processing = FALSE; - filter->next_offset = 0; - filter->next_size = 0; - filter->need_more_data = FALSE; - filter->offset_orig = 0; - filter->offset = 0; - - metadata_dispose (&filter->metadata); - -} - -/* - * gst_base_metadata_parse - * @filter: the base metadata instance - * @buf: buffer to be parsed - * @size: size of the buffer in bytes - * - * Parse the current buffer. - * This buffer must be provided by another function wich keeps track of the - * correct offset in the input stream.* - * If this function returns META_PARSING_NEED_MORE_DATA, the calling function - * must look at @filter->next_offset and @filter->next_size to jump (forward) - * in input stream to provide the correct data in @buf for the next call. - * @see_also: #gst_base_metadata_pull_range_parse #gst_base_metadata_chain - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR if there was an error</para></listitem> - * <listitem><para>%META_PARSING_DONE if the parse has completly finished - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if need another buffer</para> - * </listitem> - * </itemizedlist> - */ - -static int -gst_base_metadata_parse (GstBaseMetadata * filter, const guint8 * buf, - guint32 size) -{ - - int ret = META_PARSING_ERROR; - - filter->next_offset = 0; - filter->next_size = 0; - - ret = metadata_parse (filter->metadata, buf, size, - &filter->next_offset, &filter->next_size); - - if (ret == META_PARSING_ERROR) { - if (META_DATA_IMG_TYPE (filter->metadata) == IMG_NONE) { - /* image type not recognized */ - GST_ELEMENT_ERROR (filter, STREAM, TYPE_NOT_FOUND, (NULL), - ("Only jpeg and png are supported")); - goto done; - } else { - GST_ELEMENT_ERROR (filter, STREAM, FAILED, (NULL), - ("Failed to parse stream.")); - goto done; - } - } else if (ret == META_PARSING_NEED_MORE_DATA) { - filter->need_more_data = TRUE; - } else { - filter->state = MT_STATE_PARSED; - filter->need_more_data = FALSE; - filter->need_processing = TRUE; - } - - /* reconfigure caps if it is different from type detected by 'base_metadata' - function */ - if (filter->img_type != META_DATA_IMG_TYPE (filter->metadata)) { - filter->img_type = META_DATA_IMG_TYPE (filter->metadata); - if (!gst_base_metadata_configure_caps (filter)) { - GST_ELEMENT_ERROR (filter, STREAM, FORMAT, (NULL), - ("Couldn't reconfigure caps for %s", - gst_base_metadata_get_type_name (filter->img_type))); - ret = META_PARSING_ERROR; - goto done; - } - } - -done: - - return ret; - -} - - -/* - * gst_base_metadata_strip_push_buffer: - * @base: the base metadata instance - * @offset_orig: the offset in original input stream of the buffer that will - * have data striped or injected - * @prepend: a buffer (can be NULL) that will be completely injected in the - * beginning og @buf - * @buf: a pointer to a buffer that will be modified (data striped/injected or - * prepended) - * @inject_begin: is TRUE can inject a chunk start exactly in @offset_orig - * - * Strip bytes from @buf that are part of some chunk that will be striped. Add - * a whole injected chunk if some inject chunk starts into the buffer. Prepend - * additonal data if @prepend is not NULL. After using the @prepend buffer it - * will be release and set to NULL. - * @see_also: #gst_base_metadata_get_range #gst_base_metadata_chain - * #gst_base_metadata_buf_get_intersection_seg - * - * Returns: - * <itemizedlist> - * <listitem><para>%TRUE if the buffer has been striped or injected (@prepend - * doesn't change the return value).</para></listitem> - * <listitem><para>%FALSE if it hasn't changed.</para></listitem> - * </itemizedlist> - * - */ - -static gboolean -gst_base_metadata_strip_push_buffer (GstBaseMetadata * base, - const gint64 offset_orig, GstBuffer ** prepend, GstBuffer ** buf, - gboolean inject_begin) -{ - MetadataChunk *strip = META_DATA_STRIP_CHUNKS (base->metadata).chunk; - MetadataChunk *inject = META_DATA_INJECT_CHUNKS (base->metadata).chunk; - const gsize strip_len = META_DATA_STRIP_CHUNKS (base->metadata).len; - const gsize inject_len = META_DATA_INJECT_CHUNKS (base->metadata).len; - - gboolean buffer_is_ok_to_change = FALSE; - - guint32 size_buf_in = GST_BUFFER_SIZE (*buf); - - gint64 *boffset_strip = NULL; - guint32 *bsize_strip = NULL; - - int i, j; - gboolean need_free_strip = FALSE; - - guint32 striped_bytes = 0; - guint32 injected_bytes = 0; - - guint32 prepend_size = prepend && *prepend ? GST_BUFFER_SIZE (*prepend) : 0; - - /* - * check all the 'inject chunks' having the 'original offset' starting into - * the buffer - * and calculates how many bytes will be injectd - */ - - if (inject_len) { - - for (i = 0; i < inject_len; ++i) { - if (inject[i].offset_orig >= offset_orig) { - if (G_LIKELY (inject_begin || inject[i].offset_orig > offset_orig)) { - if (inject[i].offset_orig < offset_orig + size_buf_in) { - injected_bytes += inject[i].size; - } else { - /* segment is after size (segments are sorted) */ - break; - } - } - } - } - - } - - /* - * strip step - */ - - if (strip_len == 0) - goto inject; - - /* just try to do fast allocation on stack */ - if (G_UNLIKELY (strip_len > 16)) { - boffset_strip = g_new (gint64, strip_len); - bsize_strip = g_new (guint32, strip_len); - need_free_strip = TRUE; - } else { - boffset_strip = g_alloca (sizeof (boffset_strip[0]) * strip_len); - bsize_strip = g_alloca (sizeof (bsize_strip[0]) * strip_len); - } - - memset (bsize_strip, 0x00, sizeof (bsize_strip[0]) * strip_len); - - /* - * calculate the number of bytes from the buffer bytes that intersect some - * 'strip chunk'. - * also get the position and size of segments into current buffer - * (boffset_strip[i] and bsize_strip[i]) - * that will be striped - */ - - for (i = 0; i < strip_len; ++i) { - int res; - - res = gst_base_metadata_buf_get_intersection_seg (offset_orig, size_buf_in, - strip[i].offset_orig, strip[i].size, - &boffset_strip[i], &bsize_strip[i]); - - /* segment is after size (segments are sorted) */ - striped_bytes += bsize_strip[i]; - if (res > 0) { - break; - } - - } - - if (striped_bytes) { - - guint8 *data; - - if (!buffer_is_ok_to_change) { - /* create a new buffer if there is no space on currect buffer or if is - read-only */ - buffer_is_ok_to_change = TRUE; - if (injected_bytes + prepend_size > striped_bytes) { - GstBuffer *new_buf = - gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + injected_bytes + - prepend_size - striped_bytes); - - memcpy (GST_BUFFER_DATA (new_buf), GST_BUFFER_DATA (*buf), - GST_BUFFER_SIZE (*buf)); - - gst_buffer_unref (*buf); - *buf = new_buf; - - } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY)) { - GstBuffer *new_buf = gst_buffer_copy (*buf); - - gst_buffer_unref (*buf); - *buf = new_buf; - GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY); - GST_BUFFER_SIZE (*buf) += injected_bytes + prepend_size - striped_bytes; - } - } - - data = GST_BUFFER_DATA (*buf); - - /* strip out the bytes from buffer */ - striped_bytes = 0; - for (i = 0; i < strip_len; ++i) { - /* intersect */ - if (bsize_strip[i]) { - memmove (data + boffset_strip[i] - striped_bytes, - data + boffset_strip[i] + bsize_strip[i] - striped_bytes, - size_buf_in - boffset_strip[i] - bsize_strip[i]); - striped_bytes += bsize_strip[i]; - } - } - size_buf_in -= striped_bytes; - - } - -inject: - - /* - * inject segments - */ - - if (inject_len) { - - guint8 *data; - guint32 striped_so_far; - - if (!buffer_is_ok_to_change) { - /* create a new buffer fs there is no space on currect buffer or if is - read-only */ - buffer_is_ok_to_change = TRUE; - if (injected_bytes + prepend_size > striped_bytes) { - GstBuffer *new_buf = - gst_buffer_new_and_alloc (GST_BUFFER_SIZE (*buf) + injected_bytes + - prepend_size - striped_bytes); - - memcpy (GST_BUFFER_DATA (new_buf), GST_BUFFER_DATA (*buf), - GST_BUFFER_SIZE (*buf)); - - gst_buffer_unref (*buf); - *buf = new_buf; - - } else if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY)) { - GstBuffer *new_buf = gst_buffer_copy (*buf); - - gst_buffer_unref (*buf); - *buf = new_buf; - GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY); - GST_BUFFER_SIZE (*buf) += injected_bytes + prepend_size - striped_bytes; - } - } - - data = GST_BUFFER_DATA (*buf); - - injected_bytes = 0; - striped_so_far = 0; - j = 0; - for (i = 0; i < inject_len; ++i) { - while (j < strip_len) { - if (strip[j].offset_orig < inject[i].offset_orig) - striped_so_far += bsize_strip[j++]; - else - break; - } - - /* inject the whole inject chunk if the 'original offset' is inside the - original buffer */ - - if (inject[i].offset_orig >= offset_orig) { - if (G_LIKELY (inject_begin || inject[i].offset_orig > offset_orig)) { - if (inject[i].offset_orig < - offset_orig + size_buf_in + striped_bytes - injected_bytes) { - /* insert */ - guint32 buf_off = - inject[i].offset_orig - offset_orig - striped_so_far + - injected_bytes; - memmove (data + buf_off + inject[i].size, data + buf_off, - size_buf_in - buf_off); - memcpy (data + buf_off, inject[i].data, inject[i].size); - injected_bytes += inject[i].size; - size_buf_in += inject[i].size; - } else { - /* segment is after size (segments are sorted) */ - break; - } - } - } - } - - } - - if (prepend_size) { - if (injected_bytes == 0 && striped_bytes == 0) { - GstBuffer *new_buf = - gst_buffer_new_and_alloc (size_buf_in + prepend_size); - - memcpy (GST_BUFFER_DATA (new_buf) + prepend_size, GST_BUFFER_DATA (*buf), - size_buf_in); - - gst_buffer_unref (*buf); - *buf = new_buf; - } else { - memmove (GST_BUFFER_DATA (*buf) + prepend_size, GST_BUFFER_DATA (*buf), - size_buf_in); - } - memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (*prepend), prepend_size); - gst_buffer_unref (*prepend); - *prepend = NULL; - } - - GST_BUFFER_SIZE (*buf) = size_buf_in + prepend_size; - - if (need_free_strip) { - g_free (boffset_strip); - g_free (bsize_strip); - } - - return injected_bytes || striped_bytes; - -} - -/* - * gst_base_metadata_buf_get_intersection_seg: - * @offset: offset of buffer in original stream - * @size: size of buffer - * @seg_offset: offset of segment in original stream - * @seg_size: size of segment - * @boffset: offset inside buffer where segment starts (-1 for no intersection) - * @bsize:size of intersection - * - * Calculate which bytes into the buffer given by @offset and @size intersetcs - * the segment given by @seg_offset and @seg_size - * @see_also: #gst_base_metadata_strip_push_buffer - * - * Returns: - * <itemizedlist> - * <listitem><para>%-1 if the segment is completly before the buffer</para> - * </listitem> - * <listitem><para>%0 if the segment intersects</para></listitem> - * <listitem><para>%1 if the segment is after the buffer</para></listitem> - * </itemizedlist> - */ - -static int -gst_base_metadata_buf_get_intersection_seg (const gint64 offset, guint32 size, - const gint64 seg_offset, const guint32 seg_size, - gint64 * boffset, guint32 * bsize) -{ - int ret = -1; - - *boffset = -1; - *bsize = 0; - - /* all segment after buffer */ - if (seg_offset >= offset + size) { - ret = 1; - goto done; - } - - if (seg_offset < offset) { - /* segment start somewhere before buffer */ - - /* all segment before buffer */ - if (seg_offset + seg_size <= offset) { - ret = -1; - goto done; - } - - *boffset = 0; - - if (seg_offset + seg_size >= offset + size) { - /* segment cover all buffer */ - *bsize = size; - } else { - /* segment goes from start of buffer to somewhere before end */ - *bsize = seg_size - (offset - seg_offset); - } - - ret = 0; - - } else { - /* segment start somewhere into buffer */ - - *boffset = seg_offset - offset; - - if (seg_offset + seg_size <= offset + size) { - /* all segment into buffer */ - *bsize = seg_size; - } else { - *bsize = size - *boffset; - } - - ret = 0; - - } - -done: - - return ret; - -} - -/* - * gst_base_metadata_translate_pos_to_orig: - * @base: the base metadata instance - * @pos: position in output stream - * @orig_pos: position in original stream - * @buf: if not NULL, will have data that starts at some point into a injected - * chunk - * @max_size: the maximum size to allocate to @buf. pass 0 if don't care - * - * Given a position in output stream (@pos), returns the position in original - * stream (@orig_pos) that contains the same data. If @pos is into a injected - * chunk, @orig_pos will contains the position just after the position in which - * the chunk has been insert and @buf (if non null) will be filled with - * injected bytes starting in @pos until the and of injected chunk. - * @see_also: #gst_base_metadata_src_event #gst_base_metadata_get_range - * - * Returns: - * <itemizedlist> - * <listitem><para>%TRUE if @pos is in original buffer</para></listitem> - * <listitem><para>%FALSE if @pos is into a injected chunk</para></listitem> - * </itemizedlist> - * - */ - -static gboolean -gst_base_metadata_translate_pos_to_orig (GstBaseMetadata * base, - gint64 pos, gint64 * orig_pos, GstBuffer ** buf, guint32 max_size) -{ - MetadataChunk *strip = META_DATA_STRIP_CHUNKS (base->metadata).chunk; - MetadataChunk *inject = META_DATA_INJECT_CHUNKS (base->metadata).chunk; - const gsize strip_len = META_DATA_STRIP_CHUNKS (base->metadata).len; - const gsize inject_len = META_DATA_INJECT_CHUNKS (base->metadata).len; - const gint64 duration_orig = base->duration_orig; - const gint64 duration = base->duration; - gboolean ret = TRUE; - const gint64 saved_pos = pos; - - int i; - - guint64 new_buf_size = 0; - guint64 injected_before = 0; - - if (G_UNLIKELY (pos == -1)) { - *orig_pos = -1; - return TRUE; - } else if (G_UNLIKELY (pos >= duration)) { - /* this should never happen */ - *orig_pos = duration_orig; - return TRUE; - } - - /* calculate for injected */ - - /* just calculate size */ - for (i = 0; i < inject_len; ++i) { - if (pos >= inject[i].offset) { - if (pos < inject[i].offset + inject[i].size) { - /* pos is inside the chunk */ - const guint32 offset_in_chunk = pos - inject[i].offset; - - ret = FALSE; - pos = inject[i].offset + inject[i].size; /* put pos just after chunk */ - new_buf_size += inject[i].size - offset_in_chunk; - /* we still continue, 'cause the next chunk could be just after this */ - } else { - /* in case pos is not inside a injected chunk */ - injected_before += inject[i].size; - } - } else { - /* pos is before the chunk */ - break; - } - } - - /* alloc buffer and calcute original pos */ - if (ret == FALSE) { - - *orig_pos = pos; - - if (buf) { - guint8 *data; - - if (max_size > 0) - if (new_buf_size > max_size) - new_buf_size = max_size; - - if (*buf) - gst_buffer_unref (*buf); - *buf = gst_buffer_new_and_alloc (new_buf_size); - data = GST_BUFFER_DATA (*buf); - pos = saved_pos; - for (i = 0; i < inject_len && new_buf_size > 0; ++i) { - if (inject[i].offset > pos) { - break; - } - if (pos < inject[i].offset + inject[i].size) { - const guint32 offset = pos - inject[i].offset; - guint32 size = inject[i].size - offset; - - if (size > new_buf_size) - size = new_buf_size; - memcpy (data, inject[i].data + offset, size); - data += size; - pos = inject[i].offset + inject[i].size; - new_buf_size -= size; - } - } - } - - goto done; - } - - /* calculate for striped */ - - *orig_pos = saved_pos - injected_before; - for (i = 0; i < strip_len; ++i) { - if (strip[i].offset_orig > pos) { - break; - } - *orig_pos += strip[i].size; - } - -done: - - if (G_UNLIKELY (*orig_pos >= duration_orig)) { - *orig_pos = duration_orig - 1; - } - - return ret; - -} - -/* - * gst_base_metadata_calculate_offsets: - * @base: the base metadata instance - * - * Recalculates the offset of injected chunks after take in account new sizes - * written by the 'muxers elements' and wrapped with bytes by the correct - * file type handler. - * @see_also: #gst_base_metadata_processing #metadata_lazy_update - * #gst_base_metadata_update_inject_segment_with_new_data - * - * Returns: - * <itemizedlist> - * <listitem><para>%TRUE if succeded</para></listitem> - * <listitem><para>%FALSE if fails. Which happens if the stream hasn't been - * completely parsed yet</para></listitem> - * </itemizedlist> - */ - -static gboolean -gst_base_metadata_calculate_offsets (GstBaseMetadata * base) -{ - int i, j; - guint32 bytes_striped, bytes_inject; - MetadataChunk *strip = META_DATA_STRIP_CHUNKS (base->metadata).chunk; - MetadataChunk *inject = META_DATA_INJECT_CHUNKS (base->metadata).chunk; - gsize strip_len; - gsize inject_len; - gboolean ret = TRUE; - - if (base->state != MT_STATE_PARSED) { - ret = FALSE; - GST_ELEMENT_ERROR (base, STREAM, FAILED, (NULL), ("Invalid state.")); - goto done; - } - - metadata_chunk_array_remove_zero_size (&META_DATA_INJECT_CHUNKS - (base->metadata)); - - metadata_lazy_update (base->metadata); - - strip_len = META_DATA_STRIP_CHUNKS (base->metadata).len; - inject_len = META_DATA_INJECT_CHUNKS (base->metadata).len; - - bytes_striped = 0; - bytes_inject = 0; - - /* calculate the new position off injected chunks */ - j = 0; - for (i = 0; i < inject_len; ++i) { - for (; j < strip_len; ++j) { - if (strip[j].offset_orig >= inject[i].offset_orig) { - break; - } - bytes_striped += strip[j].size; - } - inject[i].offset = inject[i].offset_orig - bytes_striped + bytes_inject; - bytes_inject += inject[i].size; - } - - /* FIXME (append): For the time being we don't have append buffers 'cause - in the case of files we are handling it is not possible to append after - the last byte on original stream (which is part of a kind of end-of-file - chunk) */ -#if 0 - /* calculate append buffer */ - append_size = 0; - for (i = inject_len - 1; i >= 0; --i) { - if (inject[i].offset_orig == base->duration_orig) - append_size += inject[i].size; - else - break; - } - if (append_size) { - guint8 *data; - - base->append_buffer = gst_buffer_new_and_alloc (append_size); - GST_BUFFER_FLAG_SET (base->append_buffer, GST_BUFFER_FLAG_READONLY); - data = GST_BUFFER_DATA (base->append_buffer); - for (i = inject_len - 1; i >= 0; --i) { - if (inject[i].offset_orig == base->duration_orig) { - memcpy (data, inject[i].data, inject[i].size); - data += inject[i].size; - } else { - break; - } - } - } -#endif - - if (base->duration_orig) { - base->duration = base->duration_orig; - for (i = 0; i < inject_len; ++i) { - base->duration += inject[i].size; - } - for (i = 0; i < strip_len; ++i) { - base->duration -= strip[i].size; - } - } - -done: - - return ret; - -} - - -/* - * GObject callback functions implementation - */ - -static void -gst_base_metadata_base_init (gpointer gclass) -{ - GST_DEBUG_CATEGORY_INIT (gst_base_metadata_debug, "basemetadata", 0, - "basemetadata element"); -} - -static void -gst_base_metadata_class_init (GstBaseMetadataClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_peek_parent (klass); - - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_base_metadata_dispose); - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_base_metadata_finalize); - - gobject_class->set_property = gst_base_metadata_set_property; - gobject_class->get_property = gst_base_metadata_get_property; - - g_object_class_install_property (gobject_class, ARG_EXIF, - g_param_spec_boolean ("exif", "EXIF", "Send EXIF metadata ?", - TRUE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, ARG_IPTC, - g_param_spec_boolean ("iptc", "IPTC", "Send IPTC metadata ?", - TRUE, G_PARAM_READWRITE)); - - g_object_class_install_property (gobject_class, ARG_XMP, - g_param_spec_boolean ("xmp", "XMP", "Send XMP metadata ?", - TRUE, G_PARAM_READWRITE)); - - gstelement_class->change_state = gst_base_metadata_change_state; - -} - -static void -gst_base_metadata_init (GstBaseMetadata * filter, GstBaseMetadataClass * gclass) -{ - /* sink pad */ - - filter->sinkpad = - gst_pad_new_from_template (gst_element_class_get_pad_template - (GST_ELEMENT_CLASS (gclass), "sink"), "sink"); - gst_pad_set_setcaps_function (filter->sinkpad, - GST_DEBUG_FUNCPTR (gclass->set_caps)); - gst_pad_set_getcaps_function (filter->sinkpad, - GST_DEBUG_FUNCPTR (gclass->get_sink_caps)); - gst_pad_set_event_function (filter->sinkpad, gst_base_metadata_sink_event); - gst_pad_set_chain_function (filter->sinkpad, - GST_DEBUG_FUNCPTR (gst_base_metadata_chain)); - gst_pad_set_activate_function (filter->sinkpad, - gst_base_metadata_sink_activate); - - /* source pad */ - - filter->srcpad = - gst_pad_new_from_template (gst_element_class_get_pad_template - (GST_ELEMENT_CLASS (gclass), "src"), "src"); - gst_pad_set_getcaps_function (filter->srcpad, - GST_DEBUG_FUNCPTR (gclass->get_src_caps)); - gst_pad_set_event_function (filter->srcpad, gst_base_metadata_src_event); - gst_pad_set_query_function (filter->srcpad, - GST_DEBUG_FUNCPTR (gst_base_metadata_src_query)); - gst_pad_set_query_type_function (filter->srcpad, - GST_DEBUG_FUNCPTR (gst_base_metadata_get_query_types)); - gst_pad_use_fixed_caps (filter->srcpad); - - gst_pad_set_checkgetrange_function (filter->srcpad, - GST_DEBUG_FUNCPTR (gst_base_metadata_checkgetrange)); - gst_pad_set_getrange_function (filter->srcpad, gst_base_metadata_get_range); - - gst_pad_set_activatepull_function (filter->srcpad, - GST_DEBUG_FUNCPTR (gst_base_metadata_src_activate_pull)); - /* addind pads */ - - gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); - gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); - - metadata_xmp_init (); - /* init members */ - - gst_base_metadata_init_members (filter); - -} - -static void -gst_base_metadata_dispose (GObject * object) -{ - GstBaseMetadata *filter = NULL; - - filter = GST_BASE_METADATA (object); - - gst_base_metadata_dispose_members (filter); - - metadata_xmp_dispose (); - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -gst_base_metadata_finalize (GObject * object) -{ - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static void -gst_base_metadata_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstBaseMetadata *filter = GST_BASE_METADATA (object); - - switch (prop_id) { - case ARG_EXIF: - if (g_value_get_boolean (value)) - filter->options |= META_OPT_EXIF; - else - filter->options &= ~META_OPT_EXIF; - break; - case ARG_IPTC: - if (g_value_get_boolean (value)) - filter->options |= META_OPT_IPTC; - else - filter->options &= ~META_OPT_IPTC; - break; - case ARG_XMP: - if (g_value_get_boolean (value)) - filter->options |= META_OPT_XMP; - else - filter->options &= ~META_OPT_XMP; - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_base_metadata_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstBaseMetadata *filter = GST_BASE_METADATA (object); - - switch (prop_id) { - case ARG_EXIF: - g_value_set_boolean (value, filter->options & META_OPT_EXIF); - break; - case ARG_IPTC: - g_value_set_boolean (value, filter->options & META_OPT_IPTC); - break; - case ARG_XMP: - g_value_set_boolean (value, filter->options & META_OPT_XMP); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -/* - * GStreamer callback functions declaration - */ - -static GstStateChangeReturn -gst_base_metadata_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; - GstBaseMetadata *filter = GST_BASE_METADATA (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - gst_base_metadata_reset_parsing (filter); - metadata_init (&filter->metadata, filter->options); - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - if (filter->metadata == NULL) - metadata_init (&filter->metadata, filter->options); - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) - goto done; - - switch (transition) { - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_base_metadata_reset_streaming (filter); - if (filter->state == MT_STATE_PARSED) - gst_base_metadata_reset_parsing (filter); - break; - default: - break; - } - -done: - - return ret; -} - -static gboolean -gst_base_metadata_src_event (GstPad * pad, GstEvent * event) -{ - GstBaseMetadata *filter = NULL; - gboolean ret = FALSE; - - filter = GST_BASE_METADATA (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_SEEK: - { - gdouble rate; - GstFormat format; - GstSeekFlags flags; - GstSeekType start_type; - gint64 start; - GstSeekType stop_type; - gint64 stop; - - /* we don't know where are the chunks to be stripped before base */ - if (!gst_base_metadata_processing (filter)) { - ret = FALSE; - goto done; - } - - gst_event_parse_seek (event, &rate, &format, &flags, - &start_type, &start, &stop_type, &stop); - - switch (format) { - case GST_FORMAT_BYTES: - break; - case GST_FORMAT_PERCENT: - if (filter->duration < 0) - goto done; - start = start * filter->duration / 100; - stop = stop * filter->duration / 100; - break; - default: - goto done; - } - format = GST_FORMAT_BYTES; - - if (start_type == GST_SEEK_TYPE_CUR) - start = filter->offset + start; - else if (start_type == GST_SEEK_TYPE_END) { - if (filter->duration < 0) - goto done; - start = filter->duration + start; - } - start_type = GST_SEEK_TYPE_SET; - - if (filter->prepend_buffer) { - gst_buffer_unref (filter->prepend_buffer); - filter->prepend_buffer = NULL; - } - - /* FIXME (append): if some chunk is injected after the end of original - file (which is not the case for any file type currently handled), - appending a buffer should be taken in account */ - - /* translate position and setup filter-prepend to be prepend to the - striped/injected buffer in next 'chain' calling */ - filter->offset = start; - gst_base_metadata_translate_pos_to_orig (filter, start, &start, - &filter->prepend_buffer, 0); - filter->offset_orig = start; - - if (stop_type == GST_SEEK_TYPE_CUR) - stop = filter->offset + stop; - else if (stop_type == GST_SEEK_TYPE_END) { - if (filter->duration < 0) - goto done; - stop = filter->duration + stop; - } - stop_type = GST_SEEK_TYPE_SET; - - gst_base_metadata_translate_pos_to_orig (filter, stop, &stop, NULL, 0); - - gst_event_unref (event); - event = gst_event_new_seek (rate, format, flags, - start_type, start, stop_type, stop); - - } - break; - default: - break; - } - - ret = gst_pad_event_default (pad, event); - event = NULL; - -done: - - if (event) { - gst_event_unref (event); - } - - gst_object_unref (filter); - - return ret; - -} - -static gboolean -gst_base_metadata_sink_event (GstPad * pad, GstEvent * event) -{ - GstBaseMetadata *filter = NULL; - gboolean ret = FALSE; - GstBaseMetadataClass *bclass; - - filter = GST_BASE_METADATA (gst_pad_get_parent (pad)); - bclass = GST_BASE_METADATA_GET_CLASS (filter); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - if (filter->need_more_data) { - GST_ELEMENT_WARNING (filter, STREAM, DECODE, (NULL), - ("Need more data. Unexpected EOS")); - } - break; - case GST_EVENT_TAG: - break; - default: - break; - } - - ret = bclass->sink_event (pad, event); - - gst_object_unref (filter); - - return ret; - -} - -static gboolean -gst_base_metadata_checkgetrange (GstPad * srcpad) -{ - GstBaseMetadata *filter = NULL; - - filter = GST_BASE_METADATA (GST_PAD_PARENT (srcpad)); - - return gst_pad_check_pull_range (filter->sinkpad); -} - -static GstFlowReturn -gst_base_metadata_get_range (GstPad * pad, - guint64 offset, guint size, GstBuffer ** buf) -{ - GstBaseMetadata *filter = NULL; - GstFlowReturn ret = GST_FLOW_OK; - gint64 offset_orig = 0; - guint size_orig; - GstBuffer *prepend = NULL; - gboolean need_append = FALSE; - gboolean into_inject; - - filter = GST_BASE_METADATA (GST_PAD_PARENT (pad)); - - if (!gst_base_metadata_processing (filter)) { - ret = GST_FLOW_ERROR; - goto done; - } - - if (offset + size > filter->duration) { - size = filter->duration - offset; - } - - size_orig = size; - - into_inject = !gst_base_metadata_translate_pos_to_orig (filter, offset, - &offset_orig, &prepend, size); - - if (into_inject) { - size_orig = GST_BUFFER_SIZE (prepend) < size_orig ? - size_orig - GST_BUFFER_SIZE (prepend) : 0; - } - - if (size_orig == 0) { - /* enough data in prepend */ - *buf = prepend; - goto done; - } - - if (size_orig > 1) { - gint64 pos; - - pos = offset + size - 1; - into_inject = gst_base_metadata_translate_pos_to_orig (filter, pos, &pos, - NULL, 0); - size_orig = pos + 1 - offset_orig; - } - - ret = gst_pad_pull_range (filter->sinkpad, offset_orig, size_orig, buf); - - if (ret == GST_FLOW_OK && *buf) { - gst_base_metadata_strip_push_buffer (filter, offset_orig, &prepend, buf, - FALSE); - - if (GST_BUFFER_SIZE (*buf) < size) { - /* need append */ - need_append = TRUE; - } else { - /* hide extra bytes */ - GST_BUFFER_SIZE (*buf) = size; - } - } - - -done: - - if (need_append) { - /* FIXME (append): together with SEEK and - gst_base_metadata_translate_pos_to_orig this way if chunk is added in - the end we are in trouble ...still not implemented 'cause it will not be - the case for the time being (All the file types handled have a kind of - end-of-file chunk (or mark, so nothing will be injected after it) */ - } - - return ret; - -} - - -static GstFlowReturn -gst_base_metadata_chain (GstPad * pad, GstBuffer * buf) -{ - GstBaseMetadata *filter = NULL; - GstFlowReturn ret = GST_FLOW_ERROR; - guint32 buf_size = 0; - guint32 new_buf_size = 0; - gboolean append = FALSE; - - filter = GST_BASE_METADATA (gst_pad_get_parent (pad)); - - if (filter->state != MT_STATE_PARSED) { - guint32 adpt_size; - - if (G_UNLIKELY (filter->adapter_parsing == NULL)) - filter->adapter_parsing = gst_adapter_new (); - - adpt_size = gst_adapter_available (filter->adapter_parsing); - - if (filter->next_offset) { - if (filter->next_offset >= adpt_size) { - /* clean adapter */ - gst_adapter_clear (filter->adapter_parsing); - filter->next_offset -= adpt_size; - if (filter->next_offset >= GST_BUFFER_SIZE (buf)) { - /* we don't need data in this buffer */ - filter->next_offset -= GST_BUFFER_SIZE (buf); - } else { - GstBuffer *new_buf; - - /* add to adapter just need part from buf */ - new_buf = - gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buf) - - filter->next_offset); - memcpy (GST_BUFFER_DATA (new_buf), - GST_BUFFER_DATA (buf) + filter->next_offset, - GST_BUFFER_SIZE (buf) - filter->next_offset); - filter->next_offset = 0; - gst_adapter_push (filter->adapter_parsing, new_buf); - } - } else { - /* remove first bytes and add buffer */ - gst_adapter_flush (filter->adapter_parsing, filter->next_offset); - filter->next_offset = 0; - gst_adapter_push (filter->adapter_parsing, gst_buffer_copy (buf)); - } - } else { - /* just push buffer */ - gst_adapter_push (filter->adapter_parsing, gst_buffer_copy (buf)); - } - - adpt_size = gst_adapter_available (filter->adapter_parsing); - - if (adpt_size && filter->next_size <= adpt_size) { - const guint8 *new_buf = - gst_adapter_peek (filter->adapter_parsing, adpt_size); - - if (gst_base_metadata_parse (filter, new_buf, - adpt_size) == META_PARSING_ERROR) { - ret = GST_FLOW_ERROR; - goto done; - } - } - } - - if (filter->state == MT_STATE_PARSED) { - - if (!gst_base_metadata_processing (filter)) { - ret = GST_FLOW_ERROR; - goto done; - } - - if (filter->adapter_holding) { - gst_adapter_push (filter->adapter_holding, buf); - buf = gst_adapter_take_buffer (filter->adapter_holding, - gst_adapter_available (filter->adapter_holding)); - g_object_unref (filter->adapter_holding); - filter->adapter_holding = NULL; - } - - if (filter->offset_orig + GST_BUFFER_SIZE (buf) == filter->duration_orig) - append = TRUE; - - buf_size = GST_BUFFER_SIZE (buf); - - gst_base_metadata_strip_push_buffer (filter, filter->offset_orig, - &filter->prepend_buffer, &buf, TRUE); - - if (buf) { /* may be all buffer has been striped */ - gst_buffer_set_caps (buf, GST_PAD_CAPS (filter->srcpad)); - new_buf_size = GST_BUFFER_SIZE (buf); - - ret = gst_pad_push (filter->srcpad, buf); - buf = NULL; /* this function don't owner it anymore */ - if (ret != GST_FLOW_OK) - goto done; - } else { - ret = GST_FLOW_OK; - } - - if (append && filter->append_buffer) { - gst_buffer_set_caps (filter->append_buffer, - GST_PAD_CAPS (filter->srcpad)); - gst_buffer_ref (filter->append_buffer); - ret = gst_pad_push (filter->srcpad, filter->append_buffer); - if (ret != GST_FLOW_OK) - goto done; - } - - filter->offset_orig += buf_size; - filter->offset += new_buf_size; - - } else { - /* just store while still not parsed */ - if (!filter->adapter_holding) - filter->adapter_holding = gst_adapter_new (); - gst_adapter_push (filter->adapter_holding, buf); - buf = NULL; - ret = GST_FLOW_OK; - } - -done: - - - if (buf) { - /* there was an error and buffer wasn't pushed */ - gst_buffer_unref (buf); - buf = NULL; - } - - gst_object_unref (filter); - - return ret; - -} - -static gboolean -gst_base_metadata_sink_activate (GstPad * pad) -{ - GstBaseMetadata *filter = NULL; - gboolean ret = TRUE; - - - filter = GST_BASE_METADATA (GST_PAD_PARENT (pad)); - - if (!gst_pad_check_pull_range (pad) || - !gst_pad_activate_pull (filter->sinkpad, TRUE)) { - /* Fail here ? nothing to be done by now, activate push mode */ - return gst_pad_activate_push (pad, TRUE); - } - - /* try to base */ - if (filter->state == MT_STATE_NULL) { - ret = gst_base_metadata_pull_range_parse (filter); - } - - if (ret) { - GstActivateMode mode; - - /* in gst_base_metadata_pull_range_parse() we could have triggered - * negotiation and plugged new downstream elements. - * If GST_PAD_ACTIVATE_MODE (filter->srcpad) is GST_ACTIVATE_PULL it means - * that downstream is active in pull mode so we don't deactivate pull mode. - */ - GST_OBJECT_LOCK (filter->srcpad); - mode = GST_PAD_ACTIVATE_MODE (filter->srcpad); - GST_OBJECT_UNLOCK (filter->srcpad); - - if (mode != GST_ACTIVATE_PULL) { - /* change from PULL to PUSH */ - gst_pad_activate_push (pad, TRUE); - } - } - - return ret; -} - -static gboolean -gst_base_metadata_src_activate_pull (GstPad * pad, gboolean active) -{ - GstBaseMetadata *filter = NULL; - gboolean ret; - - filter = GST_BASE_METADATA (gst_pad_get_parent (pad)); - - ret = gst_pad_activate_pull (filter->sinkpad, active); - - if (ret && filter->state == MT_STATE_NULL) { - ret = gst_base_metadata_pull_range_parse (filter); - } - - gst_object_unref (filter); - - return ret; -} - -static const GstQueryType * -gst_base_metadata_get_query_types (GstPad * pad) -{ - static const GstQueryType gst_base_metadata_src_query_types[] = { - GST_QUERY_POSITION, - GST_QUERY_DURATION, - GST_QUERY_FORMATS, - 0 - }; - - return gst_base_metadata_src_query_types; -} - -static gboolean -gst_base_metadata_src_query (GstPad * pad, GstQuery * query) -{ - gboolean ret = FALSE; - GstFormat format; - GstBaseMetadata *filter = GST_BASE_METADATA (gst_pad_get_parent (pad)); - - switch (GST_QUERY_TYPE (query)) { - case GST_QUERY_POSITION: - gst_query_parse_position (query, &format, NULL); - - if (format == GST_FORMAT_BYTES) { - gst_query_set_position (query, GST_FORMAT_BYTES, filter->offset); - ret = TRUE; - } - - break; - case GST_QUERY_DURATION: - - if (!gst_base_metadata_processing (filter)) { - ret = FALSE; - goto done; - } - - gst_query_parse_duration (query, &format, NULL); - - if (format == GST_FORMAT_BYTES) { - if (filter->duration >= 0) { - gst_query_set_duration (query, GST_FORMAT_BYTES, filter->duration); - ret = TRUE; - } - } - - break; - case GST_QUERY_FORMATS: - gst_query_set_formats (query, 1, GST_FORMAT_BYTES); - ret = TRUE; - break; - default: - break; - } - -done: - - gst_object_unref (filter); - - return ret; - -} - -/* - * extern functions declaration - */ - -/** - * gst_base_metadata_set_option_flag: - * @base: the base metadata instance - * @options: mode of operation - * - * Set how the this base class will behaviour. As a demuxer or muxer. Hanlding - * EXIF, IPTC, XMP or not. - * @see_also: #gst_base_metadata_unset_option_flag - * #gst_base_metadata_get_option_flag - */ -void -gst_base_metadata_set_option_flag (GstBaseMetadata * base, MetaOptions options) -{ - base->options |= options; -} - -/** - * gst_base_metadata_unset_option_flag: - * @base: the base metadata instance - * @options: mode of operation - * - * Set how the this base class will behaviour. As a demuxer or muxer. Hanlding - * EXIF, IPTC, XMP or not. - * @see_also: #gst_base_metadata_set_option_flag - * #gst_base_metadata_get_option_flag - */ -void -gst_base_metadata_unset_option_flag (GstBaseMetadata * base, - MetaOptions options) -{ - base->options &= ~options; -} - -/** - * gst_base_metadata_get_option_flag: - * @base: the base metadata instance - * - * Check how the this base class will behaviour. As a demuxer or muxer. - * Hanlding EXIF, IPTC, XMP or not. - * @see_also: #gst_base_metadata_set_option_flag - * #gst_base_metadata_unset_option_flag - * - * Returns: The current mode of operation - */ -MetaOptions -gst_base_metadata_get_option_flag (const GstBaseMetadata * base) -{ - return base->options; -} - - -/** - * gst_base_metadata_update_inject_segment_with_new_data: - * @base: the base metadata instance - * @data: new data to be injected - * @size: the size in bytes of @data - * @type: kind of metadata chunk it is (currently EXIF, IPTC or XMP) - * - * If the file type specification of the parsed stream allows a chunk of @type, - * set the @data and @size of the segment to be injected. This the @data has - * been injected (metadata type supported by the stream @type) then, the - * the @data ownership will be taken and @data and @size willl be set to 0; - * Hanlding EXIF, IPTC, XMP or not. - * @see_also: #gst_base_metadata_calculate_offsets - */ -void gst_base_metadata_update_inject_segment_with_new_data - (GstBaseMetadata * base, - guint8 ** data, guint32 * size, MetadataChunkType type) -{ - int i; - MetadataChunk *inject = META_DATA_INJECT_CHUNKS (base->metadata).chunk; - const gsize inject_len = META_DATA_INJECT_CHUNKS (base->metadata).len; - - if (!(data && size && *data && *size)) - goto done; - - for (i = 0; i < inject_len; ++i) { - if (inject[i].type == type) { - inject[i].size = *size; - g_free (inject[i].data); - inject[i].data = *data; - *size = 0; - *data = 0; - break; - } - } - -done: - - return; - -} diff --git a/ext/metadata/gstbasemetadata.h b/ext/metadata/gstbasemetadata.h deleted file mode 100644 index 946ac1a4a..000000000 --- a/ext/metadata/gstbasemetadata.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_BASE_METADATA_H__ -#define __GST_BASE_METADATA_H__ - -#include <gst/gst.h> -#include "metadata.h" - -G_BEGIN_DECLS - -/* *INDENT-OFF* */ -#define GST_TYPE_BASE_METADATA (gst_base_metadata_get_type()) -#define GST_BASE_METADATA(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\ - GST_TYPE_BASE_METADATA,GstBaseMetadata)) -#define GST_BASE_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),\ - GST_TYPE_BASE_METADATA,GstBaseMetadataClass)) -#define GST_BASE_METADATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\ - GST_TYPE_BASE_METADATA, GstBaseMetadataClass)) -#define GST_IS_BASE_METADATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),\ - GST_TYPE_BASE_METADATA)) -#define GST_IS_BASE_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),\ - GST_TYPE_BASE_METADATA)) -#define GST_BASE_METADATA_CAST(obj) ((GstBaseMetadata *)(obj)) -/* *INDENT-ON* */ - -typedef struct _GstBaseMetadata GstBaseMetadata; -typedef struct _GstBaseMetadataClass GstBaseMetadataClass; - -enum { - BASE_METADATA_DEMUXING, - BASE_METADATA_MUXING -}; - - -/* - * GST_BASE_METADATA_SRC_PAD: - * @obj: base metadata instance - * - * Gives the pointer to the #GstPad object of the element. - */ -#define GST_BASE_METADATA_SRC_PAD(obj) (GST_BASE_METADATA_CAST (obj)->srcpad) - -/* - * GST_BASE_METADATA_SINK_PAD: - * @obj: base metadata instance - * - * Gives the pointer to the #GstPad object of the element. - */ -#define GST_BASE_METADATA_SINK_PAD(obj) (GST_BASE_METADATA_CAST (obj)->sinkpad) - -/* - * GST_BASE_METADATA_EXIF_ADAPTER - * @obj: base metadata instance - * - * Gives the pointer to the EXIF #GstAdapter of the element. - */ -#define GST_BASE_METADATA_EXIF_ADAPTER(obj) \ - (GST_BASE_METADATA_CAST (obj)->metadata->exif_adapter) - -/* - * GST_BASE_METADATA_IPTC_ADAPTER - * @obj: base metadata instance - * - * Gives the pointer to the IPTC #GstAdapter of the element. - */ -#define GST_BASE_METADATA_IPTC_ADAPTER(obj) \ - (GST_BASE_METADATA_CAST (obj)->metadata->iptc_adapter) - -/* - * GST_BASE_METADATA_XMP_ADAPTER - * @obj: base metadata instance - * - * Gives the pointer to the XMP #GstAdapter of the element. - */ -#define GST_BASE_METADATA_XMP_ADAPTER(obj) \ - (GST_BASE_METADATA_CAST (obj)->metadata->xmp_adapter) - -/* - * GST_BASE_METADATA_IMG_TYPE - * @obj: base metadata instance - * - * Gives the type indentified by the parser of the element. - */ -#define GST_BASE_METADATA_IMG_TYPE(obj) \ - (GST_BASE_METADATA_CAST (obj)->img_type) - - -typedef enum _MetadataState -{ - MT_STATE_NULL, /* still need to check media type */ - MT_STATE_PARSED -} MetadataState; - -/** - * GstBaseMetadata: - * - * The opaque #GstBaseMetadata data structure. - */ -struct _GstBaseMetadata -{ - GstElement element; - - /*< protected >*/ - GstPad *sinkpad, *srcpad; - - MetaData *metadata; /* handle for parsing module */ - - ImageType img_type; - - /*< private >*/ - - gint64 duration_orig; /* durarion of stream */ - gint64 duration; /* durarion of modified stream */ - - MetadataState state; - - MetaOptions options; - - gboolean need_processing; /* still need a action before send first buffer */ - - GstAdapter *adapter_parsing; - GstAdapter *adapter_holding; - guint32 next_offset; - guint32 next_size; - gboolean need_more_data; - gint64 offset_orig; /* offset in original stream */ - gint64 offset; /* offset in current stream */ - - GstBuffer * append_buffer; - GstBuffer * prepend_buffer; - -}; - -struct _GstBaseMetadataClass -{ - GstElementClass parent_class; - - void (*processing) (GstBaseMetadata *basemetadata); - - gboolean (*set_caps) (GstPad * pad, GstCaps * caps); - - GstCaps* (*get_src_caps) (GstPad * pad); - GstCaps* (*get_sink_caps) (GstPad * pad); - - gboolean (*sink_event) (GstPad * pad, GstEvent * event); - -}; - -extern GType -gst_base_metadata_get_type (void); - -extern void -gst_base_metadata_set_option_flag(GstBaseMetadata *base, - const MetaOptions options); - -extern void -gst_base_metadata_unset_option_flag(GstBaseMetadata *base, - const MetaOptions options); - -extern MetaOptions -gst_base_metadata_get_option_flag(const GstBaseMetadata *base); - -extern void -gst_base_metadata_update_inject_segment_with_new_data (GstBaseMetadata *base, - guint8 ** data, guint32 * size, MetadataChunkType type); - -G_END_DECLS -#endif /* __GST_BASE_METADATA_H__ */ diff --git a/ext/metadata/gstmetadata.c b/ext/metadata/gstmetadata.c deleted file mode 100644 index 7ab2bbfb1..000000000 --- a/ext/metadata/gstmetadata.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gst/gst.h> - -#include "gstmetadatademux.h" -#include "gstmetadatamux.h" -#include "metadatatags.h" - -GST_DEBUG_CATEGORY_EXTERN (gst_metadata_exif_debug); -GST_DEBUG_CATEGORY_EXTERN (gst_metadata_iptc_debug); -GST_DEBUG_CATEGORY_EXTERN (gst_metadata_xmp_debug); - -static gboolean -plugin_init (GstPlugin * plugin) -{ - - gboolean ret = TRUE; - - GST_DEBUG_CATEGORY_INIT (gst_metadata_exif_debug, "metadata_exif", - 0, "Metadata exif"); - GST_DEBUG_CATEGORY_INIT (gst_metadata_iptc_debug, "metadata_iptc", - 0, "Metadata iptc"); - GST_DEBUG_CATEGORY_INIT (gst_metadata_xmp_debug, "metadata_xmp", 0, - "Metadata xmp"); - - metadata_tags_register (); - - ret = gst_metadata_demux_plugin_init (plugin); - - ret = ret && gst_metadata_mux_plugin_init (plugin); - - return ret; - -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "metadata", - "Metadata (EXIF, IPTC and XMP) image (JPEG, TIFF) demuxer and muxer", - plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN) diff --git a/ext/metadata/gstmetadatademux.c b/ext/metadata/gstmetadatademux.c deleted file mode 100644 index bb1080f0d..000000000 --- a/ext/metadata/gstmetadatademux.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION: element-metadatademux - * @see_also: #metadatamux - * - * <refsect2> - * <para> - * This element parses image files JPEG and PNG, to find metadata chunks (EXIF, - * IPTC, XMP) in it, and then send individual tags as a 'tag message' do the - * application and as 'tag event' to the next element in pipeline. It also - * strips out the metadata chunks from original stream (unless the 'parse-only' - * property is set to 'true'). In addition the whole metadata chunk (striped - * or not) it also sent as a message to the application bus, so the application - * can have more controls about the metadata. - * </para> - * <title>Example launch line</title> - * <para> - * <programlisting> - * gst-launch -v -m filesrc location=./test.jpeg ! metadatademux ! fakesink - * silent=TRUE - * </programlisting> - * <programlisting> - * GST_DEBUG:*metadata:5 gst-launch filesrc location=./test.jpeg ! - * metadatademux ! fakesink - * </programlisting> - * </para> - * <title>Application sample code using 'libexif' to have more control</title> - * <para> - * <programlisting> - * val = gst_tag_list_get_value_index (taglist, GST_TAG_EXIF, 0); - * if (val) { - * exif_chunk = gst_value_get_buffer (val); - * if (exif_chunk) { - * ed = exif_data_new_from_data (GST_BUFFER_DATA (exif_chunk), - * GST_BUFFER_SIZE (exif_chunk)); - * } - * } - * </programlisting> - * This same idea can be used to handle IPTC and XMP directly by using - * libdata and exempi (or any other libraries). Notice: the whole metadata - * chunk sent as a message to the application contains only metadata data, i.e. - * the wrapper specific to the file format (JPEG, PNG, ...) is already - * striped out. - * </para> - * </refsect2> - */ - - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <gst/gst.h> - -#include "gstmetadatademux.h" - -#include "metadataexif.h" - -#include "metadataiptc.h" - -#include "metadataxmp.h" - -#include <string.h> - - -/* - * enum and types - */ - -enum -{ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_PARSE_ONLY -}; - -/* - * defines and static global vars - */ - - -GST_DEBUG_CATEGORY (gst_metadata_demux_debug); -#define GST_CAT_DEFAULT gst_metadata_demux_debug - -#define GOTO_DONE_IF_NULL(ptr) \ - do { if ( NULL == (ptr) ) goto done; } while(FALSE) -#define GOTO_DONE_IF_NULL_AND_FAIL(ptr, ret) \ - do { if ( NULL == (ptr) ) { (ret) = FALSE; goto done; } } while(FALSE) - -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("image/jpeg, " - "tags-extracted = (bool) false;" - "image/png, " "tags-extracted = (bool) false") - ); - -static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("image/jpeg, " - "tags-extracted = (bool) true;" - "image/png, " "tags-extracted = (bool) true") - ); - -static GstMetadataDemuxClass *metadata_parent_class = NULL; - -/* - * static helper functions declaration - */ - -static gboolean -gst_metadata_demux_configure_srccaps (GstMetadataDemux * filter); - -/* - * GObject callback functions declaration - */ - -static void gst_metadata_demux_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - -static void gst_metadata_demux_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -/* - * GstBaseMetadata virtual functions declaration - */ - -static void gst_metadata_demux_send_tags (GstBaseMetadata * base); - -static gboolean gst_metadata_demux_set_caps (GstPad * pad, GstCaps * caps); - -static GstCaps *gst_metadata_demux_get_caps (GstPad * pad); - -static gboolean gst_metadata_demux_sink_event (GstPad * pad, GstEvent * event); - - -/* - * GST BOILERPLATE - */ - -GST_BOILERPLATE (GstMetadataDemux, gst_metadata_demux, GstBaseMetadata, - GST_TYPE_BASE_METADATA); - -/* - * static helper functions implementation - */ - -static gboolean -gst_metadata_demux_configure_srccaps (GstMetadataDemux * filter) -{ - GstCaps *caps = NULL; - gboolean ret = FALSE; - const gchar *mime = NULL; - - switch (GST_BASE_METADATA_IMG_TYPE (filter)) { - case IMG_JPEG: - mime = "image/jpeg"; - break; - case IMG_PNG: - mime = "image/png"; - break; - default: - ret = FALSE; - goto done; - break; - } - - caps = - gst_caps_new_simple (mime, "tags-extracted", G_TYPE_BOOLEAN, TRUE, NULL); - - ret = gst_pad_set_caps (GST_BASE_METADATA_SRC_PAD (filter), caps); - -done: - - if (caps) { - gst_caps_unref (caps); - caps = NULL; - } - - return ret; - -} - -/* - * GObject callback functions implementation - */ - -static void -gst_metadata_demux_base_init (gpointer gclass) -{ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details_simple (element_class, "Metadata demuxer", - "Demuxer/Extracter/Metadata", - "Send metadata tags (EXIF, IPTC and XMP) and " - "remove metadata chunks from stream", - "Edgard Lima <edgard.lima@indt.org.br>"); -} - -static void -gst_metadata_demux_class_init (GstMetadataDemuxClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseMetadataClass *gstbasemetadata_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasemetadata_class = (GstBaseMetadataClass *) klass; - - metadata_parent_class = g_type_class_peek_parent (klass); - - gobject_class->set_property = gst_metadata_demux_set_property; - gobject_class->get_property = gst_metadata_demux_get_property; - - g_object_class_install_property (gobject_class, ARG_PARSE_ONLY, - g_param_spec_boolean ("parse-only", "parse-only", - "If TRUE, don't strip out any chunk", FALSE, G_PARAM_READWRITE)); - - gstbasemetadata_class->processing = - GST_DEBUG_FUNCPTR (gst_metadata_demux_send_tags); - gstbasemetadata_class->set_caps = - GST_DEBUG_FUNCPTR (gst_metadata_demux_set_caps); - gstbasemetadata_class->get_sink_caps = - GST_DEBUG_FUNCPTR (gst_metadata_demux_get_caps); - gstbasemetadata_class->get_src_caps = - GST_DEBUG_FUNCPTR (gst_metadata_demux_get_caps); - gstbasemetadata_class->sink_event = - GST_DEBUG_FUNCPTR (gst_metadata_demux_sink_event); - -} - -static void -gst_metadata_demux_init (GstMetadataDemux * filter, - GstMetadataDemuxClass * gclass) -{ - gst_base_metadata_set_option_flag (GST_BASE_METADATA (filter), - META_OPT_EXIF | META_OPT_IPTC | META_OPT_XMP | META_OPT_DEMUX); -} - -static void -gst_metadata_demux_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - switch (prop_id) { - case ARG_PARSE_ONLY: - if (g_value_get_boolean (value)) - gst_base_metadata_set_option_flag (GST_BASE_METADATA (object), - META_OPT_PARSE_ONLY); - else - gst_base_metadata_unset_option_flag (GST_BASE_METADATA (object), - META_OPT_PARSE_ONLY); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_metadata_demux_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - guint8 option = - gst_base_metadata_get_option_flag (GST_BASE_METADATA (object)); - - switch (prop_id) { - case ARG_PARSE_ONLY: - g_value_set_boolean (value, option & META_OPT_PARSE_ONLY); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* - * GstBaseMetadata virtual functions implementation - */ - -/* - * gst_metadata_demux_send_tags: - * @base: the base metadata instance - * - * Send individual tags as message to the bus and as event to the next - * element, and send the whole metadata chunk (with file specific wrapper - * striped) to the next element as a event. - * - * Returns: nothing - * - */ - -static void -gst_metadata_demux_send_tags (GstBaseMetadata * base) -{ - - GstMetadataDemux *filter = GST_METADATA_DEMUX (base); - GstMessage *msg; - GstTagList *taglist = gst_tag_list_new (); - GstEvent *event; - GstPad *srcpad = GST_BASE_METADATA_SRC_PAD (filter); - - /* get whole chunk */ - - if (gst_base_metadata_get_option_flag (base) & META_OPT_EXIF) - metadataparse_exif_tag_list_add (taglist, GST_TAG_MERGE_KEEP, - GST_BASE_METADATA_EXIF_ADAPTER (base), METADATA_TAG_MAP_WHOLECHUNK); - if (gst_base_metadata_get_option_flag (base) & META_OPT_IPTC) - metadataparse_iptc_tag_list_add (taglist, GST_TAG_MERGE_KEEP, - GST_BASE_METADATA_IPTC_ADAPTER (base), METADATA_TAG_MAP_WHOLECHUNK); - if (gst_base_metadata_get_option_flag (base) & META_OPT_XMP) - metadataparse_xmp_tag_list_add (taglist, GST_TAG_MERGE_KEEP, - GST_BASE_METADATA_XMP_ADAPTER (base), METADATA_TAG_MAP_WHOLECHUNK); - - if (taglist && !gst_tag_list_is_empty (taglist)) { - - msg = - gst_message_new_tag (GST_OBJECT (filter), gst_tag_list_copy (taglist)); - gst_element_post_message (GST_ELEMENT (filter), msg); - - event = gst_event_new_tag (taglist); - gst_pad_push_event (srcpad, event); - taglist = NULL; - } - - if (!taglist) - taglist = gst_tag_list_new (); - - /*get individual tags */ - - if (gst_base_metadata_get_option_flag (base) & META_OPT_EXIF) - metadataparse_exif_tag_list_add (taglist, GST_TAG_MERGE_KEEP, - GST_BASE_METADATA_EXIF_ADAPTER (base), METADATA_TAG_MAP_INDIVIDUALS); - if (gst_base_metadata_get_option_flag (base) & META_OPT_IPTC) - metadataparse_iptc_tag_list_add (taglist, GST_TAG_MERGE_KEEP, - GST_BASE_METADATA_IPTC_ADAPTER (base), METADATA_TAG_MAP_INDIVIDUALS); - if (gst_base_metadata_get_option_flag (base) & META_OPT_XMP) - metadataparse_xmp_tag_list_add (taglist, GST_TAG_MERGE_KEEP, - GST_BASE_METADATA_XMP_ADAPTER (base), METADATA_TAG_MAP_INDIVIDUALS); - - if (taglist && !gst_tag_list_is_empty (taglist)) { - - msg = gst_message_new_tag (GST_OBJECT (filter), taglist); - gst_element_post_message (GST_ELEMENT (filter), msg); - taglist = NULL; - } - - if (taglist) - gst_tag_list_free (taglist); - -} - -static gboolean -gst_metadata_demux_set_caps (GstPad * pad, GstCaps * caps) -{ - GstMetadataDemux *filter = NULL; - GstStructure *structure = NULL; - const gchar *mime = NULL; - gboolean ret = FALSE; - gboolean based = TRUE; - - filter = GST_METADATA_DEMUX (gst_pad_get_parent (pad)); - - structure = gst_caps_get_structure (caps, 0); - - mime = gst_structure_get_name (structure); - - if (strcmp (mime, "image/jpeg") == 0) { - GST_BASE_METADATA_IMG_TYPE (filter) = IMG_JPEG; - } else if (strcmp (mime, "image/png") == 0) { - GST_BASE_METADATA_IMG_TYPE (filter) = IMG_PNG; - } else { - ret = FALSE; - goto done; - } - - if (gst_structure_get_boolean (structure, "tags-extracted", &based)) { - if (based == TRUE) { - ret = FALSE; - goto done; - } - } - - ret = gst_metadata_demux_configure_srccaps (filter); - -done: - - gst_object_unref (filter); - - return ret; -} - -static GstCaps * -gst_metadata_demux_get_caps (GstPad * pad) -{ - GstMetadataDemux *filter = NULL; - GstPad *otherpad; - GstCaps *caps_new = NULL; - GstCaps *caps_otherpad_peer = NULL; - - filter = GST_METADATA_DEMUX (gst_pad_get_parent (pad)); - - (GST_BASE_METADATA_SRC_PAD (filter) == pad) ? - (otherpad = GST_BASE_METADATA_SINK_PAD (filter)) : - (otherpad = GST_BASE_METADATA_SRC_PAD (filter)); - - caps_new = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); - - caps_otherpad_peer = gst_pad_get_allowed_caps (otherpad); - GOTO_DONE_IF_NULL (caps_otherpad_peer); - - if (gst_caps_is_empty (caps_otherpad_peer) - || gst_caps_is_any (caps_otherpad_peer)) { - goto done; - } else { - - guint i; - guint caps_size = 0; - - caps_size = gst_caps_get_size (caps_otherpad_peer); - - gst_caps_unref (caps_new); - - caps_new = gst_caps_new_empty (); - - for (i = 0; i < caps_size; ++i) { - GstStructure *structure = NULL; - GstStructure *structure_new = NULL; - const gchar *mime = NULL; - - structure = gst_caps_get_structure (caps_otherpad_peer, i); - - mime = gst_structure_get_name (structure); - - if (pad == GST_BASE_METADATA_SINK_PAD (filter)) { - structure_new = - gst_structure_new (mime, "tags-extracted", G_TYPE_BOOLEAN, FALSE, - NULL); - } else { - structure_new = - gst_structure_new (mime, "tags-extracted", G_TYPE_BOOLEAN, TRUE, - NULL); - } - - gst_caps_append_structure (caps_new, structure_new); - - } - - } - -done: - - if (caps_otherpad_peer) { - gst_caps_unref (caps_otherpad_peer); - caps_otherpad_peer = NULL; - } - - gst_object_unref (filter); - - return caps_new; - -} - -static gboolean -gst_metadata_demux_sink_event (GstPad * pad, GstEvent * event) -{ - return gst_pad_event_default (pad, event); -} - - -/* - * element plugin init function - */ - -gboolean -gst_metadata_demux_plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (gst_metadata_demux_debug, "metadatademux", 0, - "Metadata demuxer"); - - return gst_element_register (plugin, "metadatademux", - GST_RANK_NONE, GST_TYPE_METADATA_DEMUX); -} diff --git a/ext/metadata/gstmetadatademux.h b/ext/metadata/gstmetadatademux.h deleted file mode 100644 index eef59b8af..000000000 --- a/ext/metadata/gstmetadatademux.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_METADATA_DEMUX_H__ -#define __GST_METADATA_DEMUX_H__ - -#include <gst/gst.h> - -#include "gstbasemetadata.h" - -G_BEGIN_DECLS - -/* *INDENT-OFF* */ -#define GST_TYPE_METADATA_DEMUX \ - (gst_metadata_demux_get_type()) -#define GST_METADATA_DEMUX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_METADATA_DEMUX,GstMetadataDemux)) -#define GST_METADATA_DEMUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_METADATA_DEMUX,\ - GstMetadataDemuxClass)) -#define GST_IS_METADATA_DEMUX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_METADATA_DEMUX)) -#define GST_IS_METADATA_DEMUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_METADATA_DEMUX)) -/* *INDENT-ON* */ - -typedef struct _GstMetadataDemux GstMetadataDemux; -typedef struct _GstMetadataDemuxClass GstMetadataDemuxClass; - - -/** - * GstMetadataDemux: - * - * The opaque #GstMetadataDemux data structure. - */ - -struct _GstMetadataDemux -{ - GstBaseMetadata metadata; -}; - -struct _GstMetadataDemuxClass -{ - GstBaseMetadataClass parent_class; -}; - -GType gst_metadata_demux_get_type (void); - -gboolean gst_metadata_demux_plugin_init (GstPlugin * plugin); - -G_END_DECLS -#endif /* __GST_METADATA_DEMUX_H__ */ diff --git a/ext/metadata/gstmetadatamux.c b/ext/metadata/gstmetadatamux.c deleted file mode 100644 index df8ff1cc4..000000000 --- a/ext/metadata/gstmetadatamux.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION: element-metadatamux - * - * <refsect2> - * <para> - * This element writes tags into metadata (EXIF, IPTC and XMP) chunks, and - * writes the chunks into image files (JPEG, PNG). Tags the are received as - * GST_EVENT_TAG event or set by the application using #GstTagSetter interface. - * </para> - * <title>Example launch line</title> - * <para> - * <programlisting> - * gst-launch -v -m filesrc location=orig.jpeg ! metadatamux ! filesink - * location=dest.jpeg - * </programlisting> - * <programlisting> - * gst-launch -v -m filesrc location=orig.png ! metadatademux ! pngdec ! - * ffmpegcolorspace ! jpegenc ! metadatamux ! filesink location=dest.jpeg - * </programlisting> - * </para> - * <title>How it works</title> - * <para> - * If this element receives a GST_TAG_EXIF, GST_TAG_IPTC or GST_TAG_XMP which - * are whole chunk metadata tags, then this whole chunk will be modified by - * individual tags received and written to the file. Otherwise, a new chunk - * will be created from the scratch and then modified in same way. - * </para> - * </refsect2> - */ - - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -#include <gst/gst.h> - -#include "gstmetadatamux.h" - -#include "metadataiptc.h" - -#include "metadataxmp.h" - -#include <string.h> - -/* - * enum and types - */ - -enum -{ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_EXIF_BYTE_ORDER, -}; - - -/* - * defines and static global vars - */ - - -GST_DEBUG_CATEGORY (gst_metadata_mux_debug); -#define GST_CAT_DEFAULT gst_metadata_mux_debug - -#define GOTO_DONE_IF_NULL(ptr) \ - do { if ( NULL == (ptr) ) goto done; } while(FALSE) - -#define GOTO_DONE_IF_NULL_AND_FAIL(ptr, ret) \ - do { if ( NULL == (ptr) ) { (ret) = FALSE; goto done; } } while(FALSE) - -#define DEFAULT_EXIF_BYTE_ORDER GST_META_EXIF_BYTE_ORDER_MOTOROLA - -static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("image/jpeg, tags-extracted = (bool) true;" - "image/png, tags-extracted = (bool) true") - ); - -static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS ("image/jpeg; " "image/png") - ); - -static GstMetadataMuxClass *metadata_parent_class = NULL; - -/* - * static helper functions declaration - */ - -static gboolean gst_metadata_mux_configure_srccaps (GstMetadataMux * filter); - -/* - * GObject callback functions declaration - */ - -static void gst_metadata_mux_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - -static void gst_metadata_mux_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static GstStateChangeReturn gst_metadata_mux_change_state (GstElement * element, - GstStateChange transition); - - -/* - * GstBaseMetadata virtual functions declaration - */ - -static void gst_metadata_mux_create_chunks_from_tags (GstBaseMetadata * base); - -static gboolean gst_metadata_mux_set_caps (GstPad * pad, GstCaps * caps); - -static GstCaps *gst_metadata_mux_get_caps (GstPad * pad); - -static gboolean gst_metadata_mux_sink_event (GstPad * pad, GstEvent * event); - -/* - * GST BOILERPLATE - */ - -static void -gst_metadata_mux_add_interfaces (GType type) -{ - static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL }; - - g_type_add_interface_static (type, GST_TYPE_TAG_SETTER, &tag_setter_info); -} - - -GST_BOILERPLATE_FULL (GstMetadataMux, gst_metadata_mux, GstBaseMetadata, - GST_TYPE_BASE_METADATA, gst_metadata_mux_add_interfaces); - - -/* - * static helper functions implementation - */ - -static gboolean -gst_metadata_mux_configure_srccaps (GstMetadataMux * filter) -{ - GstCaps *caps = NULL; - gboolean ret = FALSE; - const gchar *mime = NULL; - - switch (GST_BASE_METADATA_IMG_TYPE (filter)) { - case IMG_JPEG: - mime = "image/jpeg"; - break; - case IMG_PNG: - mime = "image/png"; - break; - default: - ret = FALSE; - goto done; - break; - } - - caps = gst_caps_new_simple (mime, NULL); - - ret = gst_pad_set_caps (GST_BASE_METADATA_SRC_PAD (filter), caps); - -done: - - if (caps) { - gst_caps_unref (caps); - caps = NULL; - } - - return ret; - -} - -/* - * GObject callback functions declaration - */ - -static void -gst_metadata_mux_base_init (gpointer gclass) -{ - -/* *INDENT-ON* */ - GstElementClass *element_class = GST_ELEMENT_CLASS (gclass); - - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&src_factory)); - gst_element_class_add_pad_template (element_class, - gst_static_pad_template_get (&sink_factory)); - gst_element_class_set_details_simple (element_class, "Metadata muxer", - "Muxer/Formatter/Metadata", - "Write metadata (EXIF, IPTC and XMP) into a image stream", - "Edgard Lima <edgard.lima@indt.org.br>"); -} - -static void -gst_metadata_mux_class_init (GstMetadataMuxClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - GstBaseMetadataClass *gstbasemetadata_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - gstbasemetadata_class = (GstBaseMetadataClass *) klass; - - metadata_parent_class = g_type_class_peek_parent (klass); - - gobject_class->set_property = gst_metadata_mux_set_property; - gobject_class->get_property = gst_metadata_mux_get_property; - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_metadata_mux_change_state); - - gstbasemetadata_class->processing = - GST_DEBUG_FUNCPTR (gst_metadata_mux_create_chunks_from_tags); - gstbasemetadata_class->set_caps = - GST_DEBUG_FUNCPTR (gst_metadata_mux_set_caps); - gstbasemetadata_class->get_sink_caps = - GST_DEBUG_FUNCPTR (gst_metadata_mux_get_caps); - gstbasemetadata_class->get_src_caps = - GST_DEBUG_FUNCPTR (gst_metadata_mux_get_caps); - gstbasemetadata_class->sink_event = - GST_DEBUG_FUNCPTR (gst_metadata_mux_sink_event); - - /** - * GstMetadataMux:exif-byte-order: - * - * Set byte-order for exif metadata writing. - * - * Since: 0.10.11 - */ - g_object_class_install_property (gobject_class, ARG_EXIF_BYTE_ORDER, - g_param_spec_enum ("exif-byte-order", "Exif byte-order", - "Byte-order for exif metadata writing", GST_TYPE_META_EXIF_BYTE_ORDER, - DEFAULT_EXIF_BYTE_ORDER, G_PARAM_READWRITE)); - -} - -static void -gst_metadata_mux_init (GstMetadataMux * filter, GstMetadataMuxClass * gclass) -{ - gst_base_metadata_set_option_flag (GST_BASE_METADATA (filter), - META_OPT_EXIF | META_OPT_IPTC | META_OPT_XMP | META_OPT_MUX); - filter->exif_options.byteorder = DEFAULT_EXIF_BYTE_ORDER; -} - -static void -gst_metadata_mux_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstMetadataMux *filter = GST_METADATA_MUX (object); - switch (prop_id) { - case ARG_EXIF_BYTE_ORDER: - filter->exif_options.byteorder = g_value_get_enum (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_metadata_mux_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstMetadataMux *filter = GST_METADATA_MUX (object); - switch (prop_id) { - case ARG_EXIF_BYTE_ORDER: - g_value_set_enum (value, filter->exif_options.byteorder); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GstStateChangeReturn -gst_metadata_mux_change_state (GstElement * element, GstStateChange transition) -{ - GstStateChangeReturn ret; - GstMetadataMux *filter = GST_METADATA_MUX (element); - - switch (transition) { - case GST_STATE_CHANGE_NULL_TO_READY: - break; - case GST_STATE_CHANGE_READY_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_PLAYING: - break; - default: - break; - } - - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); - - switch (transition) { - case GST_STATE_CHANGE_PLAYING_TO_PAUSED: - break; - case GST_STATE_CHANGE_PAUSED_TO_READY: - gst_tag_setter_reset_tags (GST_TAG_SETTER (filter)); - break; - case GST_STATE_CHANGE_READY_TO_NULL: - break; - default: - break; - } - - return ret; -} - -/* - * GstBaseMetadata virtual functions implementation - */ - -/* - * gst_metadata_mux_create_chunks_from_tags: - * @base: the base metadata instance - * - * This function creates new metadata (EXIF, IPTC, XMP) chunks with the tags - * received and add it to the list of segments that will be injected to the - * resulting file by #GstBaseMetadata. - * - * Returns: nothing - * - */ - -static void -gst_metadata_mux_create_chunks_from_tags (GstBaseMetadata * base) -{ - GstMetadataMux *filter = GST_METADATA_MUX (base); - GstTagSetter *setter = GST_TAG_SETTER (filter); - const GstTagList *taglist = gst_tag_setter_get_tag_list (setter); - - GST_DEBUG_OBJECT (base, "Creating chunks from tags.."); - - if (taglist) { - guint8 *buf = NULL; - guint32 size = 0; - - if (gst_base_metadata_get_option_flag (base) & META_OPT_EXIF) { - GST_DEBUG_OBJECT (base, "Using EXIF"); - metadatamux_exif_create_chunk_from_tag_list (&buf, &size, taglist, - &filter->exif_options); - gst_base_metadata_update_inject_segment_with_new_data (base, &buf, &size, - MD_CHUNK_EXIF); - g_free (buf); - buf = NULL; - size = 0; - } - - if (gst_base_metadata_get_option_flag (base) & META_OPT_IPTC) { - GST_DEBUG_OBJECT (base, "Using IPTC"); - metadatamux_iptc_create_chunk_from_tag_list (&buf, &size, taglist); - gst_base_metadata_update_inject_segment_with_new_data (base, &buf, &size, - MD_CHUNK_IPTC); - g_free (buf); - buf = NULL; - size = 0; - } - - if (gst_base_metadata_get_option_flag (base) & META_OPT_XMP) { - GST_DEBUG_OBJECT (base, "Using XMP"); - metadatamux_xmp_create_chunk_from_tag_list (&buf, &size, taglist); - gst_base_metadata_update_inject_segment_with_new_data (base, &buf, &size, - MD_CHUNK_XMP); - g_free (buf); - } - - } else { - GST_DEBUG_OBJECT (base, "Empty taglist"); - } - -} - -static gboolean -gst_metadata_mux_set_caps (GstPad * pad, GstCaps * caps) -{ - GstMetadataMux *filter = NULL; - GstStructure *structure = NULL; - const gchar *mime = NULL; - gboolean ret = FALSE; - gboolean based = TRUE; - - filter = GST_METADATA_MUX (gst_pad_get_parent (pad)); - - structure = gst_caps_get_structure (caps, 0); - - mime = gst_structure_get_name (structure); - - if (strcmp (mime, "image/jpeg") == 0) { - GST_BASE_METADATA_IMG_TYPE (filter) = IMG_JPEG; - } else if (strcmp (mime, "image/png") == 0) { - GST_BASE_METADATA_IMG_TYPE (filter) = IMG_PNG; - } else { - ret = FALSE; - goto done; - } - - if (gst_structure_get_boolean (structure, "tags-extracted", &based)) { - if (based == FALSE) { - ret = FALSE; - goto done; - } - } - - ret = gst_metadata_mux_configure_srccaps (filter); - -done: - - gst_object_unref (filter); - - return ret; -} - -static GstCaps * -gst_metadata_mux_get_caps (GstPad * pad) -{ - GstMetadataMux *filter = NULL; - GstPad *otherpad; - GstCaps *caps_new = NULL; - GstCaps *caps_otherpad_peer = NULL; - - filter = GST_METADATA_MUX (gst_pad_get_parent (pad)); - - (GST_BASE_METADATA_SRC_PAD (filter) == pad) ? - (otherpad = GST_BASE_METADATA_SINK_PAD (filter)) : - (otherpad = GST_BASE_METADATA_SRC_PAD (filter)); - - caps_new = gst_caps_copy (gst_pad_get_pad_template_caps (pad)); - - caps_otherpad_peer = gst_pad_get_allowed_caps (otherpad); - GOTO_DONE_IF_NULL (caps_otherpad_peer); - - if (gst_caps_is_empty (caps_otherpad_peer) - || gst_caps_is_any (caps_otherpad_peer)) { - goto done; - } else { - - guint i; - guint caps_size = 0; - - caps_size = gst_caps_get_size (caps_otherpad_peer); - - gst_caps_unref (caps_new); - - caps_new = gst_caps_new_empty (); - - for (i = 0; i < caps_size; ++i) { - GstStructure *structure = NULL; - GstStructure *structure_new = NULL; - const gchar *mime = NULL; - - structure = gst_caps_get_structure (caps_otherpad_peer, i); - - mime = gst_structure_get_name (structure); - - if (pad == GST_BASE_METADATA_SINK_PAD (filter)) { - structure_new = - gst_structure_new (mime, "tags-extracted", G_TYPE_BOOLEAN, TRUE, - NULL); - } else { - structure_new = gst_structure_new (mime, NULL); - } - - gst_caps_append_structure (caps_new, structure_new); - - } - - } - -done: - - if (caps_otherpad_peer) { - gst_caps_unref (caps_otherpad_peer); - caps_otherpad_peer = NULL; - } - - gst_object_unref (filter); - - return caps_new; - -} - -static gboolean -gst_metadata_mux_sink_event (GstPad * pad, GstEvent * event) -{ - GstMetadataMux *filter = NULL; - gboolean ret = FALSE; - - filter = GST_METADATA_MUX (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_TAG: - { - GstTagList *taglist; - GstTagSetter *setter = GST_TAG_SETTER (filter); - const GstTagMergeMode mode = gst_tag_setter_get_tag_merge_mode (setter); - - gst_event_parse_tag (event, &taglist); - gst_tag_setter_merge_tags (setter, taglist, mode); - break; - } - default: - break; - } - - ret = gst_pad_event_default (pad, event); - - gst_object_unref (filter); - - return ret; - -} - -/* - * element plugin init function - */ - -gboolean -gst_metadata_mux_plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (gst_metadata_mux_debug, "metadatamux", 0, - "Metadata muxer"); - - return gst_element_register (plugin, "metadatamux", - GST_RANK_NONE, GST_TYPE_METADATA_MUX); -} diff --git a/ext/metadata/gstmetadatamux.h b/ext/metadata/gstmetadatamux.h deleted file mode 100644 index 0e811632a..000000000 --- a/ext/metadata/gstmetadatamux.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_METADATA_MUX_H__ -#define __GST_METADATA_MUX_H__ - -#include <gst/gst.h> - -#include "gstbasemetadata.h" - -#include "metadataexif.h" - -G_BEGIN_DECLS - -/* *INDENT-OFF* */ -#define GST_TYPE_METADATA_MUX \ - (gst_metadata_mux_get_type()) -#define GST_METADATA_MUX(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_METADATA_MUX,GstMetadataMux)) -#define GST_METADATA_MUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_METADATA_MUX,GstMetadataMuxClass)) -#define GST_IS_METADATA_MUX(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_METADATA_MUX)) -#define GST_IS_METADATA_MUX_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_METADATA_MUX)) -/* *INDENT-ON* */ - -typedef struct _GstMetadataMux GstMetadataMux; -typedef struct _GstMetadataMuxClass GstMetadataMuxClass; - -/** - * GstMetadataMux: - * - * The opaque #GstMetadataMux data structure. - */ - -struct _GstMetadataMux -{ - GstBaseMetadata metadata; - MetaExifWriteOptions exif_options; -}; - -struct _GstMetadataMuxClass -{ - GstBaseMetadataClass parent_class; -}; - -GType gst_metadata_mux_get_type (void); - -gboolean gst_metadata_mux_plugin_init (GstPlugin * plugin); - -G_END_DECLS -#endif /* __GST_METADATA_MUX_H__ */ diff --git a/ext/metadata/metadata.c b/ext/metadata/metadata.c deleted file mode 100644 index fd515303a..000000000 --- a/ext/metadata/metadata.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION: metadata - * @short_description: This module provides high-level functions to parse files - * - * This module find out the stream type (JPEG or PNG), and provide functions to - * the caller to know where are the metadata chunks and where should it be - * written, as well, it gives the caller the metedata chunk to be written and - * also gets a metadata chunk and wraps it according the strem type - * specification. - * - * <refsect2> - * <para> - * #metadata_init must be called before any other function in this module and - * must be paired with a call to #metadata_dispose. #metadata_parse is used to - * parse the stream (find the metadata chunks and the place it should be - * written to. And #metadata_lazy_update is used by muxers to wrap the metadata - * chunk according the stream type specification. Actually after indentify the - * stream type, the real jog of parsing is delivered to speciallized module. - * See, #metadata[mux/parse][jpeg/png].[c/h] files. - * </para> - * </refsect2> - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#include <string.h> - -#include "metadata.h" - -/* - * static helper functions declaration - */ - -static MetadataParsingReturn -metadata_parse_none (MetaData * meta_data, const guint8 * data, - guint32 * data_size, guint8 ** next_start, guint32 * next_size); - -/* - * extern functions implementations - */ - -/* - * metadata_init: - * @meta_data: [in] metadata handler to be inited - * @options: [in] which types of metadata will be processed (EXIF, IPTC and/or - * XMP) and how it will be handled (DEMUXING or MUXING). Look at #MetaOptions - * to see the available options. - * - * Init metadata handle. - * This function must be called before any other function from this module. - * This function must not be called twice without call to #metadata_dispose - * beteween them. - * @see_also: #metadata_dispose #metadata_parse - * - * Returns: nothing - */ - -void -metadata_init (MetaData ** meta_data, const MetaOptions options) -{ - - if (meta_data == NULL) - return; - if ((*meta_data)) - metadata_dispose (meta_data); - - (*meta_data) = g_new (MetaData, 1); - - (*meta_data)->state = STATE_NULL; - (*meta_data)->img_type = IMG_NONE; - (*meta_data)->options = options; - (*meta_data)->offset_orig = 0; - (*meta_data)->exif_adapter = NULL; - (*meta_data)->iptc_adapter = NULL; - (*meta_data)->xmp_adapter = NULL; - - if ((*meta_data)->options & META_OPT_DEMUX) { - /* 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 increases - dynamically */ - 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); - } - -} - -/* - * metadata_dispose: - * @meta_data: [in] metadata handler to be freed - * - * Call this function to free any resource allocated by #metadata_init - * @see_also: #metadata_init - * - * Returns: nothing - */ - -void -metadata_dispose (MetaData ** meta_data) -{ - - if (meta_data == NULL || (*meta_data) == NULL) - return; - - switch ((*meta_data)->img_type) { - case IMG_JPEG: - if (G_LIKELY ((*meta_data)->options & META_OPT_DEMUX)) - 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)->options & META_OPT_DEMUX)) - metadataparse_png_dispose (&(*meta_data)->format_data.png_parse); - else - metadatamux_png_dispose (&(*meta_data)->format_data.png_mux); - break; - case IMG_NONE: - default: - break; - } - - metadata_chunk_array_free (&(*meta_data)->strip_chunks); - metadata_chunk_array_free (&(*meta_data)->inject_chunks); - - if ((*meta_data)->xmp_adapter) { - g_object_unref ((*meta_data)->xmp_adapter); - (*meta_data)->xmp_adapter = NULL; - } - - if ((*meta_data)->iptc_adapter) { - g_object_unref ((*meta_data)->iptc_adapter); - (*meta_data)->iptc_adapter = NULL; - } - - if ((*meta_data)->exif_adapter) { - g_object_unref ((*meta_data)->exif_adapter); - (*meta_data)->exif_adapter = NULL; - } - - g_free (*meta_data); - *meta_data = NULL; - -} - - -/* - * metadata_parse: - * @meta_data: [in] metadata handle - * @buf: [in] data to be parsed - * @buf_size: [in] size of @buf 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 this function @buf - * must have the same data (probably resized, see @next_size) - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * This function is used to parse the stream step-by-step incrementaly, which - * means, discover the stream type and find the metadata chunks - * (#META_OPT_DEMUX), or point out where metadata chunks should be written - * (#META_OPT_MUX). It is important to notice that there could be both strip - * and inject chunks in both demuxing and muxing modes. - * @see_also: #metadata_init #META_DATA_STRIP_CHUNKS #META_DATA_INJECT_CHUNKS - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if parse has finished. Now strip and - * inject chunks has been found - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_offset and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -MetadataParsingReturn -metadata_parse (MetaData * meta_data, const guint8 * buf, - guint32 buf_size, guint32 * next_offset, guint32 * next_size) -{ - - int ret = META_PARSING_DONE; - - guint8 *next_start = (guint8 *) buf; - - if (meta_data->state == STATE_NULL) { - ret = - metadata_parse_none (meta_data, buf, &buf_size, &next_start, next_size); - if (ret == META_PARSING_DONE) - meta_data->state = STATE_READING; - else - goto done; - } - - switch (meta_data->img_type) { - case IMG_JPEG: - if (G_LIKELY (meta_data->options & META_OPT_DEMUX)) { - GST_DEBUG ("parsing jpeg"); - ret = - metadataparse_jpeg_parse (&meta_data->format_data.jpeg_parse, - (guint8 *) buf, &buf_size, meta_data->offset_orig, &next_start, - next_size); - } else { - GST_DEBUG ("formatting jpeg"); - ret = - metadatamux_jpeg_parse (&meta_data->format_data.jpeg_mux, - (guint8 *) buf, &buf_size, meta_data->offset_orig, &next_start, - next_size); - } - break; - case IMG_PNG: - if (G_LIKELY (meta_data->options & META_OPT_DEMUX)) { - GST_DEBUG ("parsing png"); - ret = - metadataparse_png_parse (&meta_data->format_data.png_parse, - (guint8 *) buf, &buf_size, meta_data->offset_orig, &next_start, - next_size); - } else { - GST_DEBUG ("formatting png"); - ret = - metadatamux_png_parse (&meta_data->format_data.png_mux, - (guint8 *) buf, &buf_size, meta_data->offset_orig, &next_start, - next_size); - } - break; - default: - /* unexpected */ - ret = META_PARSING_ERROR; - goto done; - break; - } - - *next_offset = next_start - buf; - meta_data->offset_orig += *next_offset; - -done: - - if (ret == META_PARSING_DONE) { - meta_data->state = STATE_DONE; - } - GST_DEBUG ("parsing/formatting done : %d", ret); - - return ret; -} - -/* - * metadata_lazy_update: - * @meta_data: [in] metata handle - * - * This function must be called after #metadata_parse and after the element - * has modified the segments (chunks) - * Data written to #META_DATA_INJECT_CHUNKS will be properly wrapped - * This function is really important in case of muxing because it gives the - * oportunity to muxers: - * 1: to frame new segments - * ex: in case of JPEG it can wrap the EXIF chunk (created using tags) with - * chunk id and chunk size - * 2: 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_also: #metadata_parse #META_DATA_INJECT_CHUNKS - * - * Returns: nothing - */ - -void -metadata_lazy_update (MetaData * meta_data) -{ - switch (meta_data->img_type) { - case IMG_JPEG: - if (G_LIKELY (meta_data->options & META_OPT_DEMUX)) - 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->options & META_OPT_DEMUX)) - 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; - } - -} - - -/* - * static helper functions implementation - */ - -/* - * metadata_parse_none: - * @meta_data: [in] metata handle - * @buf: [in] data to be parsed - * @buf_size: [in] size of @buf 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 this function @buf - * must have the same data (probably resized, see @next_size) - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * Parse the fisrt bytes of the stream to identify the stream type - * @see_also: metadata_parse - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR none of the alloed strem types (JPEG, - * PNG) has been identified - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if the stream type has been identified - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_offset and @next_size) - * </para></listitem> - * </itemizedlist> - */ -static MetadataParsingReturn -metadata_parse_none (MetaData * meta_data, const guint8 * buf, - guint32 * buf_size, guint8 ** next_start, guint32 * next_size) -{ - - int ret = META_PARSING_ERROR; - GstAdapter **exif = NULL; - GstAdapter **iptc = NULL; - GstAdapter **xmp = NULL; - - *next_start = (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 (*buf_size < 3) { - *next_size = 3; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - if (meta_data->options & META_OPT_EXIF) - exif = &meta_data->exif_adapter; - if (meta_data->options & META_OPT_IPTC) - iptc = &meta_data->iptc_adapter; - if (meta_data->options & META_OPT_XMP) - xmp = &meta_data->xmp_adapter; - - if (buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF) { - if (G_LIKELY (meta_data->options & META_OPT_DEMUX)) - metadataparse_jpeg_init (&meta_data->format_data.jpeg_parse, exif, iptc, - xmp, &meta_data->strip_chunks, &meta_data->inject_chunks, - meta_data->options & META_OPT_PARSE_ONLY); - else - metadatamux_jpeg_init (&meta_data->format_data.jpeg_mux, - &meta_data->strip_chunks, &meta_data->inject_chunks); - 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 (*buf_size < 8) { - *next_size = 8; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - if (buf[0] == 0x89 && buf[1] == 0x50 && buf[2] == 0x4E && buf[3] == 0x47 && - buf[4] == 0x0D && buf[5] == 0x0A && buf[6] == 0x1A && buf[7] == 0x0A) { - if (G_LIKELY (meta_data->options & META_OPT_DEMUX)) - metadataparse_png_init (&meta_data->format_data.png_parse, exif, iptc, - xmp, &meta_data->strip_chunks, &meta_data->inject_chunks, - meta_data->options & META_OPT_PARSE_ONLY); - else - metadatamux_png_init (&meta_data->format_data.png_mux, - &meta_data->strip_chunks, &meta_data->inject_chunks); - ret = META_PARSING_DONE; - meta_data->img_type = IMG_PNG; - goto done; - } - -done: - - return ret; -} diff --git a/ext/metadata/metadata.h b/ext/metadata/metadata.h deleted file mode 100644 index 6e08ae7f0..000000000 --- a/ext/metadata/metadata.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __METADATA_H__ -#define __METADATA_H__ - -/* - * includes - */ - -#include <gst/base/gstadapter.h> -#include "metadatatypes.h" - -#include "metadataparsejpeg.h" -#include "metadatamuxjpeg.h" -#include "metadataparsepng.h" -#include "metadatamuxpng.h" - -G_BEGIN_DECLS - -/* - * enum and types - */ - -/* *INDENT-OFF* */ -typedef enum _tag_MetaOptions -{ - META_OPT_EXIF = (1 << 0), - META_OPT_IPTC = (1 << 1), - META_OPT_XMP = (1 << 2), - META_OPT_PARSE_ONLY = (1 << 3), /* only makes sense with META_OPT_DEMUX */ - META_OPT_DEMUX = (1 << 4), /* to operates in demuxing mode */ - META_OPT_MUX = (1 << 5), /* to operates in muxing mode */ - META_OPT_ALL = (1 << 6) - 1 -} MetaOptions; -/* *INDENT-ON* */ - -typedef enum _tag_MetaState -{ - STATE_NULL, - STATE_READING, - STATE_DONE -} MetaState; - -typedef enum _tag_ImageType -{ - IMG_NONE, - IMG_JPEG, - IMG_PNG -} ImageType; - -typedef struct _tag_MetaData -{ - MetaState state; - ImageType img_type; - guint8 options; - guint32 offset_orig; /* offset since begining of stream */ - union - { - JpegParseData jpeg_parse; - JpegMuxData jpeg_mux; - PngParseData png_parse; - PngMuxData png_mux; - } format_data; - GstAdapter * exif_adapter; - GstAdapter * iptc_adapter; - GstAdapter * xmp_adapter; - - MetadataChunkArray strip_chunks; - MetadataChunkArray inject_chunks; - -} MetaData; - -/* - * defines and macros - */ - -#define META_DATA_IMG_TYPE(p) (p)->img_type - -#define META_DATA_STRIP_CHUNKS(p) (p)->strip_chunks -#define META_DATA_INJECT_CHUNKS(p) (p)->inject_chunks - -/* - * external function prototypes - */ - -extern void metadata_init (MetaData ** meta_data, const MetaOptions options); - -extern void metadata_dispose (MetaData ** meta_data); - -extern MetadataParsingReturn -metadata_parse (MetaData * meta_data, const guint8 * buf, - guint32 buf_size, guint32 * next_offset, guint32 * next_size); - - -extern void metadata_lazy_update (MetaData * meta_data); - -G_END_DECLS -#endif /* __METADATA_H__ */ diff --git a/ext/metadata/metadata_mapping.htm b/ext/metadata/metadata_mapping.htm deleted file mode 100644 index 6b226bcc8..000000000 --- a/ext/metadata/metadata_mapping.htm +++ /dev/null @@ -1,1317 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<HTML> -<HEAD> - <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8"> - <TITLE></TITLE> - <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.3 (Linux)"> - <META NAME="AUTHOR" CONTENT="Edgard Lima"> - <META NAME="CREATED" CONTENT="20080131;12581600"> - <META NAME="CHANGEDBY" CONTENT="Edgard Lima"> - <META NAME="CHANGED" CONTENT="20080210;6205000"> - <META NAME="CHANGEDBY" CONTENT="Edgard Lima"> - <META NAME="CHANGEDBY" CONTENT="Edgard Lima"> - <META NAME="CHANGEDBY" CONTENT="Edgard Lima"> - <META NAME="CHANGEDBY" CONTENT="Edgard Lima"> - <META NAME="CHANGEDBY" CONTENT="Edgard Lima"> - <!-- --> - <META NAME="CHANGEDBY" CONTENT="Edgard Lima"> - <STYLE TYPE="text/css"> - <!-- - @page { size: landscape; margin: 2cm } - P { margin-bottom: 0.21cm } - P.western { so-language: en-US } - TD P { margin-bottom: 0cm } - TD P.western { so-language: en-US } - --> - </STYLE> -</HEAD> -<BODY LANG="en-US" DIR="LTR"> -<P CLASS="western" STYLE="margin-bottom: 0cm"><BR> -</P> -<TABLE WIDTH=100% BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0> - <COL WIDTH=34*> - <COL WIDTH=37*> - <COL WIDTH=27*> - <COL WIDTH=27*> - <COL WIDTH=36*> - <COL WIDTH=36*> - <COL WIDTH=33*> - <COL WIDTH=26*> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#cccccc"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt"><B>gsttaglist.h</B></FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#cccccc"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt"><B>metadatatags.h</B></FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#cccccc"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt"><B>value</B></FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#cccccc"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt"><B>type</B></FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#cccccc"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt"><B>description</B></FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#cccccc"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt"><B>EXIF</B></FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#cccccc"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt"><B>IPTC</B></FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#cccccc"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt"><B>XMP</B></FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_EXIF</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT>“<FONT SIZE=1 STYLE="font-size: 8pt">exif”</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_BUFFER</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">exif - chunk that could be used directly by the application</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">exif_data_new_from_data()</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_IPTC</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT>“<FONT SIZE=1 STYLE="font-size: 8pt">iptc”</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_BUFFER</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">iptc - chunk that could be used directly by the application</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">iptc_data_new_from_data()</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_XMP</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT>“<FONT SIZE=1 STYLE="font-size: 8pt">xmp”</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_BUFFER</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">xmp - chunk that could be used directly by the application</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">xmp_new()</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_APERTURE</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-aperture"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">The - lens aperture. <BR>(APEX)</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_APERTURE_VALUE</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_BRIGHTNESS</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-brightness"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Brightness - (APEX from -99.99 to 99.99)</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_BRIGHTNESS_VALUE</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_COLOR_SPACE</FONT></FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">"capture-color-space"</FONT></FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">1- - sRGB;<BR>0xFFFF - Uncalibrated</FONT></FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT STYLE="margin-bottom: 0.5cm"><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_COLOR_SPACE</FONT></FONT></P> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">BUG - in libexif. Can't be created in a exif data created from the - scratch</FONT></FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_CONTRAST</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-contrast"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_INT</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">from - -100 to 100:<BR>[-100, -34] – soft ;<BR>[-33, 33] – normal - ;<BR>[34, 100] – hard </FONT> - </P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_CONTRAST<BR>0- - normal;<BR>1- soft;<BR>2- hard</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_CUSTOM_RENDERED</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-custom-rendered"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">0- - Normal process;<BR>1- Custom process</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_CUSTOM_RENDERED</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_DIGITAL_ZOOM</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-digital-zoom"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Digital - zoom ratio"<BR>(zero, means digital zoom not used)</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_DIGITAL_ZOOM_RATIO</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_EXPOSURE_MODE</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-exposure-mode"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">0- - Auto exposure;<BR>1- Manual exposure;<BR>2- Auto bracket (the - camera shoots a series of frames of the same scene at different - exposure settings)</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_EXPOSURE_MODE</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_EXPOSURE_PROGRAM</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-exposure-program"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT STYLE="margin-bottom: 0.5cm"><FONT SIZE=1 STYLE="font-size: 8pt">0- - not defined; 1-Manual; 2- Normal program ; 3- Aperture priority ; - 4- Shutter priority ; 5- Creative program (biased toward death of - field); 6- Action program (biased toward fast shutter speed); 7- - Portrait mode (for closeup photos with the background out of - focus) ; 8- Landscape mode (for landscape photos with the - background in focus) </FONT> - </P> - <P CLASS="western" ALIGN=LEFT STYLE="margin-bottom: 0.5cm"><FONT SIZE=1 STYLE="font-size: 8pt">*** - exif is until here *** </FONT> - </P> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">9- - Night ; 10- Back-light ; 11- Spotlight ; 12- Snow ; 13- Beach </FONT> - </P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT STYLE="margin-bottom: 0.5cm"><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_EXPOSURE_PROGRAM</FONT></P> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">(only - from 0 to 8)</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_EXPOSURE_TIME</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-exposure-time"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Exposure - time in seconds</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_EXPOSURE_TIME</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><BR> - </P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_FLASH</FONT></FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">"capture-flash"</FONT></FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">0000.H - = Flash did not fire; 0001.H = Flash fired; 0005.H = Strobe return - light not detected; 0007.H = Strobe return light detected; 0009.H - = Flash fired, compulsory flash mode; 000D.H = Flash fired, - compulsory flash mode, return light not detected; 000F.H = Flash - fired, compulsory flash mode, return light detected; 0010.H = - Flash did not fire, compulsory flash mode; 0018.H = Flash did not - fire, auto mode; 0019.H = Flash fired, auto mode; 001D.H = Flash - fired, auto mode, return light not detected; 001F.H = Flash fired, - auto mode, return light detected; 0020.H = No flash function; - 0041.H = Flash fired, red-eye reduction mode; 0045.H = Flash - fired, red-eye reduction mode, return light not detected; 0047.H = - Flash fired, red-eye reduction mode, return light detected; 0049.H - = Flash fired, compulsory flash mode, red-eye reduction mode; - 004D.H = Flash fired, compulsory flash mode, red-eye reduction - mode, return light not detected; 004F.H = Flash fired, compulsory - flash mode, red-eye reduction mode, return light detected; 0059.H - = Flash fired, auto mode, red-eye reduction mode; 005D.H = Flash - fired, auto mode, return light not detected, red-eye reduction - mode; 005F.H = Flash fired, auto mode, return light detected, - red-eye reduction mode; Other = reserved</FONT></FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT STYLE="margin-bottom: 0.5cm"><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_FLASH</FONT></FONT></P> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">BUG - in libexif. Can't be created in a exif data created from the - scratch (exif-tag.c – ExifTagTable missing ifd information for - Flash tag)</FONT></FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_FNUMBER</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-fnumber"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">F - number (focal ratio)</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_FNUMBER</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><BR> - </P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_FOCAL_LEN</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-focal-len"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Focal - length of lens used to take image. Unit is millimeter</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_FOCAL_LENGTH</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_GAIN</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-gain"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">0- - None ; 1- Low gain up ; 2- High gain up ; 3- Low gain down ; 4- - High gain down</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_GAIN_CONTROL</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_ISO_SPEED_RATINGS</FONT></FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">"capture-iso-speed-ratings"</FONT></FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_INT</FONT></FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">ISO - Speed and ISO Latitude as specified in ISO 12232</FONT></FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_ISO_SPEED_RATINGS<BR>BUG: - <A HREF="https://sourceforge.net/tracker/?func=detail&atid=112272&aid=1884609&group_id=12272">clique - here</A></FONT></FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT COLOR="#ff0000"><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_LIGHT_SOURCE</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-light-source"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">0- - unknown (default); 1- Daylight; 2- Fluorescent; 3- Tungsten - (incandescent light); 4- Flash; 9- Fine weather; 10- Cloudy - weather; 11- Shade; 12- Daylight fluorescent (D 5700 – 7100K); - 13- Day white fluorescent (N 4600 – 5400K); 14- Cool white - fluorescent (W 3900 – 4500K); 15- White fluorescent (WW 3200 – - 3700K) 17- Standard light A; 18-Standard light B; 19- Standard - light C; 20- D55; 21- D65; 22- D75; 23- D50; 24- ISO studio - tungsten; 255- other light source; Other = reserved</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_LIGHT_SOURCE</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER>-</P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_ORIENTATION</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-orientation"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">The - relation of the '0th row' and '0th column' to visual position:<BR>1- - top-left; 2- top-right; 3- bottom-right; 4- bottom-left; 5- - left-top; 6- right-top; 7- right-bottom; 8- left-bottom</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_ORIENTATION</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_SATURATION</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-saturation"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_INT</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">from - -100 to 100:<BR>[-100, -34] – low ;<BR>[-33, 33] – normal - ;<BR>[34, 100] - high</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_SATURATION<BR>0- - normal;<BR>1- low;<BR>2- high</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_SCENE_CAPTURE_TYPE</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-scene-capture-type"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">0- - Standard;<BR>1- Landscape;<BR>2- Portrait;<BR>3- Night scene</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_SCENE_CAPTURE_TYPE</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_SHUTTER_SPEED</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-shutter-speed"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Saturation<BR>(in - APEX units)</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_SHUTTER_SPEED_VALUE</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CAPTURE_WHITE_BALANCE</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"capture-white-balance"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT STYLE="margin-bottom: 0.5cm"><FONT SIZE=1 STYLE="font-size: 8pt">0- - Auto; 1- Off </FONT> - </P> - <P CLASS="western" ALIGN=LEFT STYLE="margin-bottom: 0.5cm"><FONT SIZE=1 STYLE="font-size: 8pt">*** - exif is until here *** </FONT> - </P> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">2- - Sunlight ; 3- Cloudy ; 4- Shade ; 5- Tungsten ; 6- Fluorescent ; - 7- Incandescent; 8- Flash ; 9- Horizon (sun on the horizon)</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT STYLE="margin-bottom: 0.5cm"><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_WHITE_BALANCE</FONT></P> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">(only - 0 and 1)</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CREATOR_TOOL</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"creator-tool"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">The - name of the first known tool used to create the resource. Or - firmware or driver version of device</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_SOFTWARE</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_DATE_TIME_DIGITIZED</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"date-time-digitized"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Date/Time - of image digitized<BR>formated as <A HREF="http://www.w3.org/TR/1998/NOTE-datetime-19980827">subset - of ISO RFC - 8601</A>:<BR>YYYY<BR>YYYY-MM<BR>YYYY-MM-DD<BR>YYYY-MM-DDThh:mmTZD<BR>YYYY-MM-DDThh:mm:ssTZD<BR>YYYY-MM-DDThh:mm:ss.sTZD<BR>where:<BR>YYYY - = four-digit year;<BR>MM = two-digit month (01=January);<BR>DD = - two-digit day of month (01 through 31);<BR>hh = two digits of hour - (00 through 23);<BR>mm = two digits of minute (00 through 59);<BR>ss - = two digits of second (00 through 59);<BR>s = one or more digits - representing a decimal fraction of a second;<BR>TZD = time zone - designator (Z or +hh:mm or -hh:mm)</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_DATE_TIME_DIGITIZED</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_DATE_TIME_MODIFIED</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"date-time-modified"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Date/Time - of image was last modified<BR>the same format as - GST_TAG_DATE_TIME_DIGITIZED</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_DATE_TIME</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_DATE_TIME_ORIGINAL</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"date-time-original"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Date/Time - of original image taken<BR>the same format as - GST_TAG_DATE_TIME_DIGITIZED</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_DATE_TIME_ORIGINAL</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_DEVICE_MAKE</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"device-make"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">The - manufacturer of the recording equipment</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_MAKE</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_DEVICE_MODEL</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"device-model"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">The - model name or model number of the equipment</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_MODEL</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_EXIF_MAKER_NOTE</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"exif-maker-note"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_BUFFER</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Camera - private data</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_MAKER_NOTE</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_GPS_ALTITUDE</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"gps-altitude"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Altitude - (positive means abive sea and negative bellow sea)</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_GPS_ALTITUDE</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_GPS_LATITUDE</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"gps-latitude"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Latitude - in the same format as specified in XMP:<BR>"DDD,MM,SSk" - or "DDD,MM.mmk"<BR>D- degrees<BR>M- minutes<BR>S- - seconds<BR>k- 'N', 'S', 'E', 'W' (North, South, East, West)</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_GPS_LATITUDE</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_GPS_LONGITUDE</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"gps-longitude"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Longitude. - The format is the sames as GST_TAG_GPS_LATITUDE</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_GPS_LONGITUDE</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_IMAGE_HEIGHT</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"image-height"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Image - height in pixels</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_PIXEL_Y_DIMENSION</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_IMAGE_WIDTH</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"image-width"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_UINT</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Image - width in pixels</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_PIXEL_X_DIMENSION</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_IMAGE_XRESOLUTION</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"image-xresolution"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Horizontal - resolution in pixels per inch.<BR>Here it is always in inches.<BR>In - EXIF it depends on EXIF_TAG_RESOLUTION_UNIT</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_X_RESOLUTION</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_IMAGE_YRESOLUTION</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"image-yresolution"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TYPE_FRACTION</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Vertical - resolution in pixels per inch.<BR>Here it is always in inches.<BR>In - EXIF it depends on EXIF_TAG_RESOLUTION_UNIT</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">EXIF_TAG_Y_RESOLUTION</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_COMPOSER</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"composer"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Name - of the creator of the object, e.g. writer, photographer or graphic - artist.</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">IPTC_TAG_BYLINE</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_COPYRIGHT</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"copyright"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Any - necessary copyright notice.</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">IPTC_TAG_COPYRIGHT_NOTICE</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=LEFT>“<FONT SIZE=1 STYLE="font-size: 8pt">dc:rights”</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_DESCRIPTION</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"description"</FONT></P> - </TD> - <TD WIDTH=11% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">A - textual description of the data</FONT></P> - </TD> - <TD WIDTH=14% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=13% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">IPTC_TAG_CAPTION</FONT></P> - </TD> - <TD WIDTH=10% BGCOLOR="#e6e6ff"> - <P CLASS="western" ALIGN=LEFT>“<FONT SIZE=1 STYLE="font-size: 8pt">dc:description”</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_TITLE</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"title"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">A - shorthand reference for the object.</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">IPTC_TAG_OBJECT_NAME</FONT></P> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=LEFT>“<FONT SIZE=1 STYLE="font-size: 8pt">dc:title”</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_CODEC</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"codec"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">A - textual definition of the object type.</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=13%> - <PRE STYLE="text-align: left"><FONT SIZE=1 STYLE="font-size: 8pt">IPTC_TAG_OBJECT_TYPE</FONT></PRE> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=LEFT>“<FONT SIZE=1 STYLE="font-size: 8pt">dc:type”</FONT></P> - </TD> - </TR> - <TR VALIGN=TOP> - <TD WIDTH=13%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">GST_TAG_VIDEO_CODEC</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">"video-codec"</FONT></P> - </TD> - <TD WIDTH=11%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">G_TYPE_STRING</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=LEFT><FONT SIZE=1 STYLE="font-size: 8pt">Image - format.</FONT></P> - </TD> - <TD WIDTH=14%> - <P CLASS="western" ALIGN=CENTER><FONT SIZE=1 STYLE="font-size: 8pt">-</FONT></P> - </TD> - <TD WIDTH=13%> - <PRE STYLE="text-align: left"><FONT SIZE=1 STYLE="font-size: 8pt">IPTC_TAG_IMAGE_TYPE</FONT></PRE> - </TD> - <TD WIDTH=10%> - <P CLASS="western" ALIGN=LEFT>“<FONT SIZE=1 STYLE="font-size: 8pt">dc:format”</FONT></P> - </TD> - </TR> -</TABLE> -<P CLASS="western" STYLE="margin-bottom: 0cm"><BR> -</P> -</BODY> -</HTML> diff --git a/ext/metadata/metadataexif.c b/ext/metadata/metadataexif.c deleted file mode 100644 index 32f575282..000000000 --- a/ext/metadata/metadataexif.c +++ /dev/null @@ -1,1368 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/** - * SECTION: metadataexif - * @short_description: This module provides functions to extract tags from - * EXIF metadata chunks and create EXIF chunks from metadata tags. - * @see_also: #metadatatags.[c/h] - * - * If libexif isn't available at compilation time, only the whole chunk - * (#METADATA_TAG_MAP_WHOLECHUNK) tags is created. It means that individual - * tags aren't mapped. - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "metadataexif.h" -#include "metadataparseutil.h" -#include "metadatatags.h" - -/* - * defines - */ - -GST_DEBUG_CATEGORY (gst_metadata_exif_debug); -#define GST_CAT_DEFAULT gst_metadata_exif_debug - -GType -gst_meta_exif_byte_order_get_type (void) -{ - static GType meta_exif_byte_order_type = 0; - static const GEnumValue meta_exif_byte_order[] = { - {GST_META_EXIF_BYTE_ORDER_MOTOROLA, "Motorola byte-order", "Motorola"}, - {GST_META_EXIF_BYTE_ORDER_INTEL, "Intel byte-order", "Intel"}, - {0, NULL, NULL}, - }; - - if (!meta_exif_byte_order_type) { - meta_exif_byte_order_type = - g_enum_register_static ("MetaExifByteOrder", meta_exif_byte_order); - } - return meta_exif_byte_order_type; -} - -/* - * Implementation when libexif isn't available at compilation time - */ - -#ifndef HAVE_EXIF - -/* - * extern functions implementations - */ - - -void -metadataparse_exif_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, - GstAdapter * adapter, MetadataTagMapping mapping) -{ - - if (mapping & METADATA_TAG_MAP_WHOLECHUNK) { - GST_LOG ("EXIF not defined, sending just one tag as whole chunk"); - metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_EXIF, - adapter); - } - -} - -void -metadatamux_exif_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, - const GstTagList * taglist, const MetaExifWriteOptions * opts) -{ - /* do nothing */ -} - -#else /* ifndef HAVE_EXIF */ - -/* - * Implementation when libexif is available at compilation time - */ - -/* - * includes - */ - -#include <libexif/exif-data.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> -#include <stdio.h> - -/* - * enum and types - */ - -typedef struct _tag_MEUserData -{ - GstTagList *taglist; - GstTagMergeMode mode; - ExifShort resolution_unit; /* 2- inches (default), 3- cm */ - int altitude_ref; /* -1- not specified, 0- above sea, 1- bellow sea */ - gchar latitude_ref; /* k- not specified, 'N'- north, 'S'- south */ - gchar longitude_ref; /* k- not specified, 'E'- north, 'W'- south */ -} MEUserData; - -typedef struct _tag_MapIntStr -{ - ExifTag exif; - ExifIfd ifd; - const gchar *str; -} MapIntStr; - -/* - * defines and static global vars - */ - -/* *INDENT-OFF* */ -/* When changing this table, update 'metadata_mapping.htm' file too. */ -static MapIntStr mappedTags[] = { - {EXIF_TAG_APERTURE_VALUE, /*RATIONAL,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_APERTURE /*GST_TYPE_FRACTION*/}, - - {EXIF_TAG_BRIGHTNESS_VALUE, /*SRATIONAL,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_BRIGHTNESS /*GST_TYPE_FRACTION*/}, - - {EXIF_TAG_COLOR_SPACE, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_COLOR_SPACE /*G_TYPE_UINT*/}, - - {EXIF_TAG_CONTRAST, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_CONTRAST /*G_TYPE_INT*/}, - - {EXIF_TAG_CUSTOM_RENDERED, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_CUSTOM_RENDERED /*G_TYPE_UINT*/}, - - {EXIF_TAG_DIGITAL_ZOOM_RATIO, /*RATIONAL,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_DIGITAL_ZOOM /*GST_TYPE_FRACTION*/}, - - {EXIF_TAG_EXPOSURE_PROGRAM, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_EXPOSURE_PROGRAM /*G_TYPE_UINT*/}, - - {EXIF_TAG_EXPOSURE_MODE, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_EXPOSURE_MODE /*G_TYPE_UINT*/}, - - {EXIF_TAG_EXPOSURE_TIME, /*RATIONAL,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_EXPOSURE_TIME /*GST_TYPE_FRACTION*/}, - - {EXIF_TAG_FLASH, /*SHORT*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_FLASH /*G_TYPE_UINT*/}, - - {EXIF_TAG_FNUMBER, /*RATIONAL,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_FNUMBER /*GST_TYPE_FRACTION*/}, - - {EXIF_TAG_FOCAL_LENGTH, /*SRATIONAL*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_FOCAL_LEN /*GST_TYPE_FRACTION*/}, - - {EXIF_TAG_GAIN_CONTROL, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_GAIN /*G_TYPE_UINT*/}, - - {EXIF_TAG_ISO_SPEED_RATINGS, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_ISO_SPEED_RATINGS /*G_TYPE_INT*/}, - - {EXIF_TAG_LIGHT_SOURCE, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_LIGHT_SOURCE /*G_TYPE_UINT*/}, - - {EXIF_TAG_ORIENTATION, /*SHORT,*/ EXIF_IFD_0, - GST_TAG_CAPTURE_ORIENTATION /*G_TYPE_UINT*/}, - - {EXIF_TAG_SATURATION, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_SATURATION /*G_TYPE_INT*/}, - - {EXIF_TAG_SCENE_CAPTURE_TYPE, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_SCENE_CAPTURE_TYPE /*G_TYPE_UINT*/}, - - {EXIF_TAG_SHUTTER_SPEED_VALUE, /*SRATIONAL,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_SHUTTER_SPEED /*GST_TYPE_FRACTION*/}, - - {EXIF_TAG_WHITE_BALANCE, /*SHORT,*/ EXIF_IFD_EXIF, - GST_TAG_CAPTURE_WHITE_BALANCE /*G_TYPE_UINT*/}, - - {EXIF_TAG_SOFTWARE, /*ASCII,*/ EXIF_IFD_0, - GST_TAG_CREATOR_TOOL /*G_TYPE_STRING*/}, - - {EXIF_TAG_DATE_TIME_DIGITIZED, /*ASCII,*/ EXIF_IFD_EXIF, - GST_TAG_DATE_TIME_DIGITIZED /*G_TYPE_STRING*/}, - - {EXIF_TAG_DATE_TIME, /*ASCII,*/ EXIF_IFD_0, - GST_TAG_DATE_TIME_MODIFIED /*G_TYPE_STRING*/}, - - {EXIF_TAG_DATE_TIME_ORIGINAL, /*ASCII,*/ EXIF_IFD_EXIF, - GST_TAG_DATE_TIME_ORIGINAL /*G_TYPE_STRING*/}, - - {EXIF_TAG_IMAGE_DESCRIPTION, /*ASCII,*/ EXIF_IFD_0, - GST_TAG_DESCRIPTION /*G_TYPE_STRING*/}, - - {EXIF_TAG_MAKE, /*ASCII,*/ EXIF_IFD_0, - GST_TAG_DEVICE_MAKE /*G_TYPE_STRING*/}, - - {EXIF_TAG_MODEL, /*ASCII,*/ EXIF_IFD_0, - GST_TAG_DEVICE_MODEL /*G_TYPE_STRING*/}, - - {EXIF_TAG_MAKER_NOTE, /*UNDEFINED(size any)*/ EXIF_IFD_EXIF, - GST_TAG_EXIF_MAKER_NOTE /*GST_TYPE_BUFFER*/}, - - {EXIF_TAG_PIXEL_Y_DIMENSION, /*LONG,*/ EXIF_IFD_EXIF, - GST_TAG_IMAGE_HEIGHT /*G_TYPE_INT*/}, - - {EXIF_TAG_PIXEL_X_DIMENSION, /*LONG,*/ EXIF_IFD_EXIF, - GST_TAG_IMAGE_WIDTH /*G_TYPE_INT*/}, - - {EXIF_TAG_X_RESOLUTION, /*RATIONAL,*/ EXIF_IFD_0, - GST_TAG_IMAGE_XRESOLUTION /*GST_TYPE_FRACTION*/}, /* inches */ - - {EXIF_TAG_Y_RESOLUTION, /*RATIONAL,*/ EXIF_IFD_0, - GST_TAG_IMAGE_YRESOLUTION /*GST_TYPE_FRACTION*/}, /* inches */ - - {EXIF_TAG_GPS_ALTITUDE, /*RATIONAL,*/ EXIF_IFD_GPS, - GST_TAG_GEO_LOCATION_ELEVATION /*G_TYPE_DOUBLE*/}, - - {EXIF_TAG_GPS_LATITUDE, /*RATIONAL(3),*/ EXIF_IFD_GPS, - GST_TAG_GEO_LOCATION_LATITUDE /*G_TYPE_DOUBLE*/}, - - {EXIF_TAG_GPS_LONGITUDE, /*RATIONAL(3),*/ EXIF_IFD_GPS, - GST_TAG_GEO_LOCATION_LONGITUDE /*G_TYPE_DOUBLE*/}, - - {0, EXIF_IFD_COUNT, NULL} -}; -/* *INDENT-ON* */ - -#define IS_NUMBER(n) ('0' <= (n) && (n) <= '9') -#define IS_FRACT_POSITIVE(n,d) \ - ( ! ( ((n) >> (sizeof(n)*8-1)) ^ ((d) >> (sizeof(d)*8-1)) ) ) -#define CHAR_TO_INT(c) ((c) - '0') - -/* - * static helper functions declaration - */ - -static const gchar *metadataparse_exif_get_tag_from_exif (ExifTag exif, - GType * type); - -static ExifTag -metadatamux_exif_get_exif_from_tag (const gchar * tag, GType * type, - ExifIfd * ifd); - -static void -metadataparse_exif_data_foreach_content_func (ExifContent * content, - void *callback_data); - -static void -metadataparse_exif_content_foreach_entry_func (ExifEntry * entry, - void *user_data); - -static gboolean -metadataparse_handle_unit_tags (ExifEntry * entry, MEUserData * meudata, - const ExifByteOrder byte_order); - -static void -metadatamux_exif_for_each_tag_in_list (const GstTagList * list, - const gchar * tag, gpointer user_data); - -static gboolean metadataparse_exif_convert_to_datetime (GString * dt); - -static gboolean metadatamux_exif_convert_from_datetime (GString * dt); - -/* - * extern functions implementations - */ - -/* - * metadataparse_exif_tag_list_add: - * @taglist: tag list in which extracted tags will be added - * @mode: tag list merge mode - * @adapter: contains the EXIF metadata chunk - * @mapping: if is to extract individual tags and/or the whole chunk. - * - * This function gets a EXIF chunk (@adapter) and extract tags from it - * and the add to @taglist. - * Note: The EXIF chunk (@adapetr) must NOT be wrapped by any bytes specific - * to any file format - * - * Returns: nothing - */ - -void -metadataparse_exif_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, - GstAdapter * adapter, MetadataTagMapping mapping) -{ - const guint8 *buf; - guint32 size; - ExifData *exif = NULL; - MEUserData user_data = { taglist, mode, 2, -1, 'k', 'k' }; - - if (adapter == NULL || (size = gst_adapter_available (adapter)) == 0) { - goto done; - } - - /* add chunk tag */ - if (mapping & METADATA_TAG_MAP_WHOLECHUNK) - metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_EXIF, - adapter); - - if (!(mapping & METADATA_TAG_MAP_INDIVIDUALS)) - goto done; - - buf = gst_adapter_peek (adapter, size); - - exif = exif_data_new_from_data (buf, size); - if (exif == NULL) { - goto done; - } - - exif_data_foreach_content (exif, - metadataparse_exif_data_foreach_content_func, (void *) &user_data); - -done: - - if (exif) - exif_data_unref (exif); - - return; - -} - -/* - * metadatamux_exif_create_chunk_from_tag_list: - * @buf: buffer that will have the created EXIF chunk - * @size: size of the buffer that will be created - * @taglist: list of tags to be added to EXIF chunk - * @opts: write options for exif metadata - * - * Get tags from @taglist, create a EXIF chunk based on it and save to @buf. - * Note: The EXIF chunk is NOT wrapped by any bytes specific to any file format - * - * Returns: nothing - */ - -void -metadatamux_exif_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, - const GstTagList * taglist, const MetaExifWriteOptions * opts) -{ - ExifData *ed = NULL; - GstBuffer *exif_chunk = NULL; - const GValue *val = NULL; - - if (!(buf && size)) - goto done; - - g_free (*buf); - *buf = NULL; - *size = 0; - - val = gst_tag_list_get_value_index (taglist, GST_TAG_EXIF, 0); - if (val) { - exif_chunk = gst_value_get_buffer (val); - if (exif_chunk) { - ed = exif_data_new_from_data (GST_BUFFER_DATA (exif_chunk), - GST_BUFFER_SIZE (exif_chunk)); - } - } - - if (!ed) { - ed = exif_data_new (); - GST_DEBUG ("setting byteorder %d", opts->byteorder); - switch (opts->byteorder) { - case GST_META_EXIF_BYTE_ORDER_MOTOROLA: - exif_data_set_byte_order (ed, EXIF_BYTE_ORDER_MOTOROLA); - break; - case GST_META_EXIF_BYTE_ORDER_INTEL: - exif_data_set_byte_order (ed, EXIF_BYTE_ORDER_INTEL); - break; - default: - break; - } - exif_data_set_data_type (ed, EXIF_DATA_TYPE_COMPRESSED); - exif_data_fix (ed); - } - - gst_tag_list_foreach (taglist, metadatamux_exif_for_each_tag_in_list, ed); - - exif_data_save_data (ed, buf, size); - - -done: - - if (ed) - exif_data_unref (ed); - - return; -} - - -/* - * static helper functions implementation - */ - -/* - * metadataparse_exif_get_tag_from_exif: - * @exif: EXIF tag to look for - * @type: the type of the GStreamer tag mapped to @exif - * - * This returns the GStreamer tag mapped to an EXIF tag. - * - * Returns: - * <itemizedlist> - * <listitem><para>The GStreamer tag mapped to the @exif - * </para></listitem> - * <listitem><para>%NULL if there is no mapped GST tag for @exif - * </para></listitem> - * </itemizedlist> - */ - -static const gchar * -metadataparse_exif_get_tag_from_exif (ExifTag exif, GType * type) -{ - int i = 0; - - while (mappedTags[i].exif) { - if (exif == mappedTags[i].exif) { - *type = gst_tag_get_type (mappedTags[i].str); - break; - } - ++i; - } - - return mappedTags[i].str; - -} - -/* - * metadatamux_exif_get_exif_from_tag: - * @tag: GST tag to look for - * @type: the type of the GStreamer @tag - * @ifd: the place into EXIF chunk @exif belongs to. - * - * This returns thet EXIF tag mapped to an GStreamer @tag. - * - * Returns: - * <itemizedlist> - * <listitem><para>The EXIF tag mapped to the GST @tag - * </para></listitem> - * <listitem><para>0 if there is no mapped EXIF tag for GST @tag - * </para></listitem> - * </itemizedlist> - */ - -static ExifTag -metadatamux_exif_get_exif_from_tag (const gchar * tag, GType * type, - ExifIfd * ifd) -{ - int i = 0; - - while (mappedTags[i].exif) { - if (0 == strcmp (mappedTags[i].str, tag)) { - *type = gst_tag_get_type (tag); - *ifd = mappedTags[i].ifd; - break; - } - ++i; - } - - return mappedTags[i].exif; - -} - -/* - * metadataparse_exif_data_foreach_content_func: - * @content: EXIF structure from libexif containg a IFD - * @user_data: pointer to #MEUserData - * - * This function designed to be called for each EXIF IFD in a EXIF chunk. This - * function gets calls another function for each tag into @content. Then all - * tags into a EXIF chunk can be extracted to a tag list in @user_data. - * @see_also: #metadataparse_exif_tag_list_add - * #metadataparse_exif_content_foreach_entry_func - * - * Returns: nothing - */ - -static void -metadataparse_exif_data_foreach_content_func (ExifContent * content, - void *user_data) -{ - ExifIfd ifd = exif_content_get_ifd (content); - - if (ifd == EXIF_IFD_0 || ifd == EXIF_IFD_EXIF || ifd == EXIF_IFD_GPS) { - - GST_LOG ("\n Content %p: %s (ifd=%d)", content, exif_ifd_get_name (ifd), - ifd); - exif_content_foreach_entry (content, - metadataparse_exif_content_foreach_entry_func, user_data); - } -} - -/* - * metadataparse_exif_content_foreach_entry_func: - * @entry: EXIF structure from libexif having a EXIF tag - * @user_data: pointer to #MEUserData - * - * This function designed to be called for each EXIF tag in a EXIF IFD. This - * function gets the EXIF tag from @entry and then add to the tag list - * in @user_data by using a merge mode also specified in @user_data - * @see_also: #metadataparse_exif_data_foreach_content_func - * - * Returns: nothing - */ - -static void -metadataparse_exif_content_foreach_entry_func (ExifEntry * entry, - void *user_data) -{ - MEUserData *meudata = (MEUserData *) user_data; - GType type = G_TYPE_NONE; - ExifByteOrder byte_order; - const gchar *tag; - - /* We need the byte order */ - if (!entry || !entry->parent || !entry->parent->parent) - return; - - tag = metadataparse_exif_get_tag_from_exif (entry->tag, &type); - byte_order = exif_data_get_byte_order (entry->parent->parent); - - if (metadataparse_handle_unit_tags (entry, meudata, byte_order)) - goto done; - - if (!tag) - goto done; - - if (type == GST_TYPE_FRACTION) { - gint numerator = 0; - gint denominator = 1; - - switch (entry->format) { - case EXIF_FORMAT_SRATIONAL: - { - ExifSRational v_srat; - - v_srat = exif_get_srational (entry->data, byte_order); - if (v_srat.denominator) { - numerator = (gint) v_srat.numerator; - denominator = (gint) v_srat.denominator; - } - } - break; - case EXIF_FORMAT_RATIONAL: - { - ExifRational v_rat; - - v_rat = exif_get_rational (entry->data, byte_order); - if (v_rat.denominator) { - numerator = (gint) v_rat.numerator; - denominator = (gint) v_rat.denominator; - } - if (meudata->resolution_unit == 3) { - /* converts from cm to inches */ - if (entry->tag == EXIF_TAG_X_RESOLUTION - || entry->tag == EXIF_TAG_Y_RESOLUTION) { - numerator *= 2; - denominator *= 5; - } - } - } - break; - default: - GST_ERROR ("Unexpected Tag Type"); - goto done; - break; - } - gst_tag_list_add (meudata->taglist, meudata->mode, tag, numerator, - denominator, NULL); - - } else if (type == GST_TYPE_BUFFER) { - GstBuffer *buf = gst_buffer_new_and_alloc (entry->components); - - memcpy (GST_BUFFER_DATA (buf), entry->data, entry->components); - gst_tag_list_add (meudata->taglist, meudata->mode, tag, buf, NULL); - gst_buffer_unref (buf); - } else { - switch (type) { - case G_TYPE_STRING: - { - char buf[2048]; - const gchar *str = exif_entry_get_value (entry, buf, sizeof (buf)); - GString *value = NULL; - - if (entry->tag == EXIF_TAG_DATE_TIME_DIGITIZED - || entry->tag == EXIF_TAG_DATE_TIME - || entry->tag == EXIF_TAG_DATE_TIME_ORIGINAL) { - value = g_string_new_len (str, 20); - /* 20 is enough memory to hold "YYYY-MM-DDTHH:MM:SS" */ - - if (metadataparse_exif_convert_to_datetime (value)) { - str = value->str; - } else { - GST_ERROR ("Unexpected date & time format for %s", tag); - str = NULL; - } - - } - if (str) - gst_tag_list_add (meudata->taglist, meudata->mode, tag, str, NULL); - if (value) - g_string_free (value, TRUE); - } - break; - case G_TYPE_INT: - /* fall through */ - case G_TYPE_UINT: - { - gint value; - - switch (entry->format) { - case EXIF_FORMAT_SHORT: - value = exif_get_short (entry->data, byte_order); - break; - case EXIF_FORMAT_LONG: - value = exif_get_long (entry->data, byte_order); - break; - default: - GST_ERROR ("Unexpected Exif Tag Type (%s - %s)", - tag, exif_format_get_name (entry->format)); - goto done; - break; - } - if (entry->tag == EXIF_TAG_CONTRAST || - entry->tag == EXIF_TAG_SATURATION) { - switch (value) { - case 0: - break; - case 1: - value = -67; /* -100-34 /2 */ - break; - case 2: - value = 67; /* 100+34 /2 */ - break; - default: - GST_ERROR ("Unexpected value"); - break; - } - } - gst_tag_list_add (meudata->taglist, meudata->mode, tag, value, NULL); - } - break; - case G_TYPE_DOUBLE: - { - gdouble value = 0.0; - - if (entry->tag == EXIF_TAG_GPS_LATITUDE - || entry->tag == EXIF_TAG_GPS_LONGITUDE) { - ExifRational *rt = (ExifRational *) entry->data; - - /* DDD - degrees */ - value = (gdouble) rt->numerator / (gdouble) rt->denominator; - GST_DEBUG ("deg: %lu / %lu", (gulong) rt->numerator, - (gulong) rt->denominator); - rt++; - - /* MM - minutes and SS - seconds */ - GST_DEBUG ("min: %lu / %lu", (gulong) rt->numerator, - (gulong) rt->denominator); - value += (gdouble) rt->numerator / ((gdouble) rt->denominator * 60.0); - rt++; - GST_DEBUG ("sec: %lu / %lu", (gulong) rt->numerator, - (gulong) rt->denominator); - value += - (gdouble) rt->numerator / ((gdouble) rt->denominator * 3600.0); - - /* apply sign */ - if (entry->tag == EXIF_TAG_GPS_LATITUDE) { - if (((meudata->latitude_ref == 'S') && (value > 0.0)) || - ((meudata->latitude_ref == 'N') && (value < 0.0))) { - value = -value; - } - } else { - if (((meudata->longitude_ref == 'W') && (value > 0.0)) || - ((meudata->longitude_ref == 'E') && (value < 0.0))) { - value = -value; - } - } - GST_DEBUG ("long/lat : %lf", value); - } - if (entry->tag == EXIF_TAG_GPS_ALTITUDE) { - ExifRational v_rat = exif_get_rational (entry->data, byte_order); - value = (gdouble) v_rat.numerator / (gdouble) v_rat.denominator; - if (((meudata->altitude_ref == 1) && (value > 0.0)) || - ((meudata->altitude_ref == 0) && (value < 0.0))) { - value = -value; - } - GST_DEBUG ("altitude = %lf", value); - } - gst_tag_list_add (meudata->taglist, meudata->mode, tag, value, NULL); - } - break; - default: - break; - } - } - - -done: - { -#ifndef GST_DISABLE_GST_DEBUG - char buf[2048]; - GST_LOG ("\n Entry %p: %s (%s)\n" - " Size, Comps: %d, %d\n" - " Value: %s\n" - " Title: %s\n" - " Description: %s\n", - entry, - exif_tag_get_name (entry->tag), - exif_format_get_name (entry->format), - entry->size, - (int) (entry->components), - exif_entry_get_value (entry, buf, sizeof (buf)), - exif_tag_get_title (entry->tag), exif_tag_get_description (entry->tag)); -#endif - } - return; - -} - -/* - * metadataparse_handle_unit_tags: - * @entry: The exif entry that is supposed to have a tag that makes reference - * to other tag - * @meudata: contains references that can be used afterwards and the tag list - * @byte_order: used to read Exif values - * - * This function tries to parse Exif tags that are not mapped to Gst tags - * but makes reference to another Exif-Gst mapped tag. For example, - * 'resolution-unit' that says the units of 'image-xresolution', so proper - * conversion is done or a hint to the conversion is stored to @meudata - * to be used afterwards. - * - * Returns: - * <itemizedlist> - * <listitem><para>%TRUE if the @entry->tag was handled - * </para></listitem> - * <listitem><para>%FALSE if this function does'n handle @entry->tag - * </para></listitem> - * </itemizedlist> - */ - -static gboolean -metadataparse_handle_unit_tags (ExifEntry * entry, MEUserData * meudata, - const ExifByteOrder byte_order) -{ - gboolean ret = TRUE; - - /* FIXME: Cast to gint because EXIF_TAG_GPS_ALTITUDE_REF - * and EXIF_TAG_GPS_LONGITUDE_REF are not part of ExifTag - * and gcc warns about this - */ - switch ((gint) entry->tag) { - case EXIF_TAG_RESOLUTION_UNIT: - meudata->resolution_unit = exif_get_short (entry->data, byte_order); - if (meudata->resolution_unit == 3) { - /* if [xy]resolution has alredy been add in cm, replace it in inches */ - GValue cm = { 0, }; - GValue inch = { 0, }; - GValue factor = { 0, }; - - g_value_init (&factor, GST_TYPE_FRACTION); - gst_value_set_fraction (&factor, 2, 5); - - if (gst_tag_list_copy_value (&cm, meudata->taglist, - GST_TAG_IMAGE_XRESOLUTION)) { - g_value_init (&inch, GST_TYPE_FRACTION); - gst_tag_list_add_value (meudata->taglist, GST_TAG_MERGE_REPLACE, - GST_TAG_IMAGE_XRESOLUTION, &inch); - g_value_unset (&inch); - g_value_unset (&cm); - } - if (gst_tag_list_copy_value (&cm, meudata->taglist, - GST_TAG_IMAGE_YRESOLUTION)) { - g_value_init (&inch, GST_TYPE_FRACTION); - gst_tag_list_add_value (meudata->taglist, GST_TAG_MERGE_REPLACE, - GST_TAG_IMAGE_YRESOLUTION, &inch); - g_value_unset (&inch); - g_value_unset (&cm); - } - - g_value_unset (&factor); - } - break; - case EXIF_TAG_GPS_ALTITUDE_REF: - { - gdouble value; - - meudata->altitude_ref = entry->data[0]; - if (gst_tag_list_get_double (meudata->taglist, - GST_TAG_GEO_LOCATION_ELEVATION, &value)) { - GST_DEBUG ("alt-ref: %d", meudata->altitude_ref); - if (((meudata->altitude_ref == 1) && (value > 0.0)) || - ((meudata->altitude_ref == 0) && (value < 0.0))) { - gst_tag_list_add (meudata->taglist, GST_TAG_MERGE_REPLACE, - GST_TAG_GEO_LOCATION_ELEVATION, -value, NULL); - } - } - } - break; - case EXIF_TAG_GPS_LATITUDE_REF: - { - gdouble value; - - meudata->latitude_ref = entry->data[0]; - if (gst_tag_list_get_double (meudata->taglist, - GST_TAG_GEO_LOCATION_LATITUDE, &value)) { - GST_DEBUG ("lat-ref: %c", meudata->latitude_ref); - if (((meudata->latitude_ref == 'S') && (value > 0.0)) || - ((meudata->latitude_ref == 'N') && (value < 0.0))) { - gst_tag_list_add (meudata->taglist, GST_TAG_MERGE_REPLACE, - GST_TAG_GEO_LOCATION_LATITUDE, -value, NULL); - } - } - } - break; - case EXIF_TAG_GPS_LONGITUDE_REF: - { - gdouble value; - - meudata->longitude_ref = entry->data[0]; - if (gst_tag_list_get_double (meudata->taglist, - GST_TAG_GEO_LOCATION_LONGITUDE, &value)) { - GST_DEBUG ("lon-ref: %c", meudata->longitude_ref); - if (((meudata->longitude_ref == 'W') && (value > 0.0)) || - ((meudata->longitude_ref == 'E') && (value < 0.0))) { - gst_tag_list_add (meudata->taglist, GST_TAG_MERGE_REPLACE, - GST_TAG_GEO_LOCATION_LONGITUDE, -value, NULL); - } - } - } - break; - default: - ret = FALSE; - break; - } - - return ret; -} - - -/* - * metadatamux_exif_for_each_tag_in_list: - * @list: GStreamer tag list from which @tag belongs to - * @tag: GStreamer tag to be added to the EXIF chunk - * @user_data: pointer to #ExifData in which the tag will be added - * - * This function designed to be called for each tag in GST tag list. This - * function adds get the tag value from tag @list and then add it to the EXIF - * chunk by using #ExifData and related functions from libexif - * @see_also: #metadatamux_exif_create_chunk_from_tag_list - * - * Returns: nothing - */ - -static void -metadatamux_exif_for_each_tag_in_list (const GstTagList * list, - const gchar * tag, gpointer user_data) -{ - ExifData *ed = (ExifData *) user_data; - ExifTag exif_tag; - GType type = G_TYPE_INVALID; - ExifEntry *entry = NULL; - ExifIfd ifd = EXIF_IFD_COUNT; - const ExifByteOrder byte_order = exif_data_get_byte_order (ed); - - exif_tag = metadatamux_exif_get_exif_from_tag (tag, &type, &ifd); - - if (!exif_tag) - goto done; - - entry = exif_data_get_entry (ed, exif_tag); - - if (entry) - exif_entry_ref (entry); - else { - entry = exif_entry_new (); - exif_content_add_entry (ed->ifd[ifd], entry); - exif_entry_initialize (entry, exif_tag); - } - - if (entry->data == NULL) { - if (entry->tag == EXIF_TAG_GPS_ALTITUDE) { - entry->format = EXIF_FORMAT_RATIONAL; - entry->components = 1; - entry->size = exif_format_get_size (entry->format) * entry->components; - entry->data = g_malloc (entry->size); - } else if (entry->tag == EXIF_TAG_GPS_LATITUDE - || entry->tag == EXIF_TAG_GPS_LONGITUDE) { - entry->format = EXIF_FORMAT_RATIONAL; - entry->components = 3; - entry->size = exif_format_get_size (entry->format) * entry->components; - entry->data = g_malloc (entry->size); - } - } - - if (type == GST_TYPE_FRACTION) { - const GValue *gvalue = gst_tag_list_get_value_index (list, tag, 0); - gint numerator = gst_value_get_fraction_numerator (gvalue); - gint denominator = gst_value_get_fraction_denominator (gvalue); - - switch (entry->format) { - case EXIF_FORMAT_SRATIONAL: - { - ExifSRational sr = { numerator, denominator }; - - exif_set_srational (entry->data, byte_order, sr); - } - break; - case EXIF_FORMAT_RATIONAL: - { - ExifRational r; - - if (entry->tag == EXIF_TAG_X_RESOLUTION || - entry->tag == EXIF_TAG_Y_RESOLUTION) { - ExifEntry *unit_entry = NULL; - - unit_entry = exif_data_get_entry (ed, EXIF_TAG_RESOLUTION_UNIT); - - if (unit_entry) { - ExifShort vsh = exif_get_short (unit_entry->data, byte_order); - - if (vsh != 2) /* inches */ - exif_set_short (unit_entry->data, byte_order, 2); - } - } - r.numerator = numerator; - r.denominator = denominator; - if (numerator < 0) - r.numerator = -numerator; - if (denominator < 0) - r.denominator = -denominator; - exif_set_rational (entry->data, byte_order, r); - } - break; - default: - break; - } - } else if (type == GST_TYPE_BUFFER) { - const GValue *val = NULL; - GstBuffer *buf; - - val = gst_tag_list_get_value_index (list, tag, 0); - buf = gst_value_get_buffer (val); - entry->components = GST_BUFFER_SIZE (buf); - entry->size = GST_BUFFER_SIZE (buf); - entry->data = g_malloc (entry->size); - memcpy (entry->data, GST_BUFFER_DATA (buf), entry->size); - } else { - switch (type) { - case G_TYPE_STRING: - { - gchar *value = NULL; - - if (gst_tag_list_get_string (list, tag, &value)) { - if (entry->tag == EXIF_TAG_DATE_TIME_DIGITIZED - || entry->tag == EXIF_TAG_DATE_TIME - || entry->tag == EXIF_TAG_DATE_TIME_ORIGINAL) { - GString *datetime = g_string_new_len (value, - 20); /* enough memory to hold "YYYY:MM:DD HH:MM:SS" */ - - if (metadatamux_exif_convert_from_datetime (datetime)) { - } else { - GST_ERROR ("Unexpected date & time format for %s", tag); - } - g_free (value); - value = datetime->str; - g_string_free (datetime, FALSE); - } else if (value) { - entry->components = strlen (value) + 1; - entry->size = - exif_format_get_size (entry->format) * entry->components; - entry->data = (guint8 *) value; - value = NULL; - } - } - } - break; - case G_TYPE_UINT: - case G_TYPE_INT: - { - gint value; - ExifShort v_short; - - if (G_TYPE_UINT == type) { - gst_tag_list_get_uint (list, tag, (guint *) & value); - } else { - gst_tag_list_get_int (list, tag, &value); - } - - switch (entry->format) { - case EXIF_FORMAT_SHORT: - if (entry->tag == EXIF_TAG_CONTRAST - || entry->tag == EXIF_TAG_SATURATION) { - if (value < -33) - value = 1; /* low */ - else if (value < 34) - value = 0; /* normal */ - else - value = 2; /* high */ - } - v_short = value; - exif_set_short (entry->data, byte_order, v_short); - break; - case EXIF_FORMAT_LONG: - exif_set_long (entry->data, byte_order, value); - break; - default: - break; - } - - } - break; - case G_TYPE_DOUBLE: - { - gdouble value; - - gst_tag_list_get_double (list, tag, &value); - if (entry->tag == EXIF_TAG_GPS_LATITUDE - || entry->tag == EXIF_TAG_GPS_LONGITUDE) { - ExifRational *rt = (ExifRational *) entry->data; - gdouble v = fabs (value); - ExifEntry *ref_entry = NULL; - char ref; - const ExifTag ref_tag = entry->tag == EXIF_TAG_GPS_LATITUDE ? - EXIF_TAG_GPS_LATITUDE_REF : EXIF_TAG_GPS_LONGITUDE_REF; - - /* DDD - degrees */ - rt->numerator = (gulong) v; - rt->denominator = 1; - GST_DEBUG ("deg: %lf : %lu / %lu", v, (gulong) rt->numerator, - (gulong) rt->denominator); - v -= rt->numerator; - rt++; - - /* MM - minutes */ - rt->numerator = (gulong) (v * 60.0); - rt->denominator = 1; - GST_DEBUG ("min: %lf : %lu / %lu", v, (gulong) rt->numerator, - (gulong) rt->denominator); - v -= ((gdouble) rt->numerator / 60.0); - rt++; - - /* SS - seconds */ - rt->numerator = (gulong) (0.5 + v * 3600.0); - rt->denominator = 1; - GST_DEBUG ("sec: %lf : %lu / %lu", v, (gulong) rt->numerator, - (gulong) rt->denominator); - - if (entry->tag == EXIF_TAG_GPS_LONGITUDE) { - GST_DEBUG ("longitude : %lf", value); - ref = (value < 0.0) ? 'W' : 'E'; - } else { - GST_DEBUG ("latitude : %lf", value); - ref = (value < 0.0) ? 'S' : 'N'; - } - - ref_entry = exif_data_get_entry (ed, ref_tag); - if (ref_entry) { - exif_entry_ref (ref_entry); - } else { - ref_entry = exif_entry_new (); - exif_content_add_entry (ed->ifd[EXIF_IFD_GPS], ref_entry); - exif_entry_initialize (ref_entry, ref_tag); - } - if (ref_entry->data == NULL) { - ref_entry->format = EXIF_FORMAT_ASCII; - ref_entry->components = 2; - ref_entry->size = 2; - ref_entry->data = g_malloc (2); - } - ref_entry->data[0] = ref; - ref_entry->data[1] = 0; - exif_entry_unref (ref_entry); - } else if (entry->tag == EXIF_TAG_GPS_ALTITUDE) { - ExifEntry *ref_entry = NULL; - ExifRational *rt = (ExifRational *) entry->data; - - rt->numerator = (gulong) fabs (10.0 * value); - rt->denominator = 10; - - GST_DEBUG ("altitude : %lf", value); - - ref_entry = exif_data_get_entry (ed, EXIF_TAG_GPS_ALTITUDE_REF); - if (ref_entry) { - exif_entry_ref (ref_entry); - } else { - ref_entry = exif_entry_new (); - exif_content_add_entry (ed->ifd[EXIF_IFD_GPS], ref_entry); - exif_entry_initialize (ref_entry, EXIF_TAG_GPS_ALTITUDE_REF); - } - if (ref_entry->data == NULL) { - ref_entry->format = EXIF_FORMAT_BYTE; - ref_entry->components = 1; - ref_entry->size = 1; - ref_entry->data = g_malloc (1); - } - if (value > 0.0) { - ref_entry->data[0] = 0; - } else { - ref_entry->data[0] = 1; - } - exif_entry_unref (ref_entry); - } - } - break; - default: - break; - } - } - -done: - - if (entry) - exif_entry_unref (entry); - -} - -/* - * metadataparse_exif_convert_to_datetime: - * @dt: string containing date_time in format "YYYY:MM:DD HH:MM:SS" - * - * This function converts a exif date_and_time string @dt into the format - * specified by http://www.w3.org/TR/1998/NOTE-datetime-19980827, in which a - * subset of ISO RFC 8601 used by XMP. - * @dt->allocated_len must be not less than 21 to hold enough memory - * hold "YYYY:MM:DD HH:MM:SS" without additional allocation - * - * Returns: - * <itemizedlist> - * <listitem><para>#TRUE if succeded - * </para></listitem> - * <listitem><para>#FALSE if failed - * </para></listitem> - * </itemizedlist> - */ - -static gboolean -metadataparse_exif_convert_to_datetime (GString * dt) -{ - - /* "YYYY:MM:DD HH:MM:SS" */ - /* 012345678901234567890 */ - - if (dt->allocated_len < 20) - return FALSE; - - /* Fix me: Ideally would be good to get the time zone from othe Exif tag - * for the time being, just use local time as explained in XMP specification - * (converting from EXIF to XMP date and time) */ - - dt->str[4] = '-'; - dt->str[7] = '-'; - dt->str[10] = 'T'; - dt->str[19] = '\0'; - - return TRUE; - -} - - -/* - * metadatamux_exif_convert_from_datetime: - * @dt: string containing date_time in format specified by - * http://www.w3.org/TR/1998/NOTE-datetime-19980827 - * - * This function converts a date_and_time string @dt as specified by - * http://www.w3.org/TR/1998/NOTE-datetime-19980827, in which a - * subset of ISO RFC 8601 used by XMP, into Exif date_time format. - * @dt->allocated_len must be not less than 20 to hold enough memory - * hold "YYYY:MM:DD HH:MM:SS" without additional allocation - * - * Returns: - * <itemizedlist> - * <listitem><para>#TRUE if succeded - * </para></listitem> - * <listitem><para>#FALSE if failed - * </para></listitem> - * </itemizedlist> - */ - -static gboolean -metadatamux_exif_convert_from_datetime (GString * dt) -{ - gboolean ret = TRUE; - char *p = dt->str; - - if (dt->allocated_len < 20) - goto error; - - /* check YYYY */ - - if (IS_NUMBER (*p)) - p++; - else - goto error; - if (IS_NUMBER (*p)) - p++; - else - goto error; - if (IS_NUMBER (*p)) - p++; - else - goto error; - if (IS_NUMBER (*p)) - p++; - else - goto error; - - if (*p == '\0') { - sprintf (p, ":01:01 00:00:00"); - goto done; - } else if (*p == '-') { - *p++ = ':'; - } else - goto error; - - /* check MM */ - - if (IS_NUMBER (*p)) - p++; - else - goto error; - if (IS_NUMBER (*p)) - p++; - else - goto error; - - if (*p == '\0') { - sprintf (p, ":01 00:00:00"); - goto done; - } else if (*p == '-') { - *p++ = ':'; - } else - goto error; - - /* check DD */ - - if (IS_NUMBER (*p)) - p++; - else - goto error; - if (IS_NUMBER (*p)) - p++; - else - goto error; - - if (*p == '\0') { - sprintf (p, " 00:00:00"); - goto done; - } else if (*p == 'T') { - *p++ = ' '; - } else - goto error; - - /* check hh */ - - if (IS_NUMBER (*p)) - p++; - else - goto error; - if (IS_NUMBER (*p)) - p++; - else - goto error; - - if (*p++ != ':') - goto error; - - /* check mm */ - - if (IS_NUMBER (*p)) - p++; - else - goto error; - if (IS_NUMBER (*p)) - p++; - else - goto error; - - if (*p == ':') { - p++; - } else if (*p == 'Z' || *p == '+' || *p == '-') { - /* FIXME: in case of '+' or '-', it would be better to also fill another - * EXIF tag in order to save, somehow the time zone info */ - sprintf (p, ":00"); - goto done; - } else - goto error; - - /* check ss */ - - if (IS_NUMBER (*p)) - p++; - else - goto error; - if (IS_NUMBER (*p)) - p++; - else - goto error; - - *p = '\0'; - - /* if here, everything is ok */ - goto done; -error: - - ret = FALSE; - -done: - - /* FIXME: do we need to check if the date is valid ? */ - - if (ret) - dt->len = 19; - return ret; - -} - -#endif /* else (ifndef HAVE_EXIF) */ diff --git a/ext/metadata/metadataexif.h b/ext/metadata/metadataexif.h deleted file mode 100644 index 6040ef4de..000000000 --- a/ext/metadata/metadataexif.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_METADATA_EXIF_H__ -#define __GST_METADATA_EXIF_H__ - -#include <gst/gst.h> -#include <gst/base/gstadapter.h> -#include "metadatatags.h" - -G_BEGIN_DECLS - -/* - * defines - */ - -#define EXIF_HEADER "Exif\0" - -typedef enum { - GST_META_EXIF_BYTE_ORDER_MOTOROLA, - GST_META_EXIF_BYTE_ORDER_INTEL -} MetaExifByteOrder; - -typedef struct _MetaExifWriteOptions MetaExifWriteOptions; - -/** - * MetaExifWriteOptions: - * @byteorder: byte-ordering for exif chunk - * - * Options for Exif metadata writing - */ -struct _MetaExifWriteOptions -{ - MetaExifByteOrder byteorder; -}; - -#define GST_TYPE_META_EXIF_BYTE_ORDER (gst_meta_exif_byte_order_get_type()) -GType gst_meta_exif_byte_order_get_type (void); - -/* - * external function prototypes - */ - -extern void -metadataparse_exif_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, - GstAdapter * adapter, MetadataTagMapping mapping); - -extern void -metadatamux_exif_create_chunk_from_tag_list (guint8 ** buf, guint32 *size, - const GstTagList * taglist, const MetaExifWriteOptions *opts); - -G_END_DECLS -#endif /* __GST_METADATA_EXIF_H__ */ diff --git a/ext/metadata/metadataiptc.c b/ext/metadata/metadataiptc.c deleted file mode 100644 index 106ac291a..000000000 --- a/ext/metadata/metadataiptc.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * SECTION: metadataiptc - * @short_description: This module provides functions to extract tags from - * IPTC metadata chunks and create IPTC chunks from metadata tags. - * @see_also: #metadatatags.[c/h] - * - * If libiptcdata isn't available at compilation time, only the whole chunk - * (#METADATA_TAG_MAP_WHOLECHUNK) tags is created. It means that individual - * tags aren't mapped. - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "metadataiptc.h" -#include "metadataparseutil.h" -#include "metadatatags.h" - -/* - * defines - */ - -GST_DEBUG_CATEGORY (gst_metadata_iptc_debug); -#define GST_CAT_DEFAULT gst_metadata_iptc_debug - -/* - * Implementation when libiptcdata isn't available at compilation time - */ - -#ifndef HAVE_IPTC - -/* - * extern functions implementations - */ - -void -metadataparse_iptc_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, - GstAdapter * adapter, MetadataTagMapping mapping) -{ - - if (mapping & METADATA_TAG_MAP_WHOLECHUNK) { - GST_LOG ("IPTC not defined, sending just one tag as whole chunk"); - metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_IPTC, - adapter); - } - -} - - -void -metadatamux_iptc_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, - const GstTagList * taglist) -{ - /* do nothing */ -} - -#else /* ifndef HAVE_IPTC */ - -/* - * Implementation when libiptcdata is available at compilation time - */ - -/* - * includes - */ - -#include <iptc-data.h> -#include <iptc-tag.h> -#include <string.h> -#include <gst/gsttaglist.h> - -/* - * enum and types - */ - -typedef struct _tag_MEUserData -{ - GstTagList *taglist; - GstTagMergeMode mode; -} MEUserData; - -typedef struct _tag_MapIntStr -{ - IptcRecord record; - IptcTag iptc; - const gchar *str; -} MapIntStr; - -/* - * defines and static global vars - */ - -/* *INDENT-OFF* */ -/* When changing this table, update 'metadata_mapping.htm' file too. */ -static MapIntStr mappedTags[] = { - {IPTC_RECORD_APP_2, IPTC_TAG_OBJECT_NAME, /*ASCII*/ - GST_TAG_TITLE /*STRING*/}, - {IPTC_RECORD_APP_2, IPTC_TAG_BYLINE, /*ASCII*/ - GST_TAG_COMPOSER /*STRING*/}, - {IPTC_RECORD_APP_2, IPTC_TAG_CAPTION, /*ASCII*/ - GST_TAG_DESCRIPTION /*STRING*/}, - {IPTC_RECORD_APP_2, IPTC_TAG_COPYRIGHT_NOTICE, /*ASCII*/ - GST_TAG_COPYRIGHT /*STRING*/}, - {0, 0, NULL} -}; -/* *INDENT-ON* */ - -/* - * static helper functions declaration - */ - -static const gchar *metadataparse_iptc_get_tag_from_iptc (IptcTag iptc, - GType * type, IptcRecord * record); - - -static IptcTag -metadatamux_iptc_get_iptc_from_tag (const gchar * tag, GType * type, - IptcRecord * record); - -static void -metadataparse_iptc_data_foreach_dataset_func (IptcDataSet * dataset, - void *user_data); - -static void -metadatamux_iptc_for_each_tag_in_list (const GstTagList * list, - const gchar * tag, gpointer user_data); - -/* - * extern functions implementations - */ - -/* - * metadataparse_iptc_tag_list_add: - * @taglist: tag list in which extracted tags will be added - * @mode: tag list merge mode - * @adapter: contains the IPTC metadata chunk - * @mapping: if is to extract individual tags and/or the whole chunk. - * - * This function gets a IPTC chunk (@adapter) and extract tags form it - * and then add to @taglist. - * Note: The IPTC chunk (@adapetr) must NOT be wrapped by any bytes specific - * to any file format - * - * Returns: nothing - */ - -void -metadataparse_iptc_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, - GstAdapter * adapter, MetadataTagMapping mapping) -{ - const guint8 *buf; - guint32 size; - IptcData *iptc = NULL; - MEUserData user_data = { taglist, mode }; - - if (adapter == NULL || (size = gst_adapter_available (adapter)) == 0) { - goto done; - } - - /* add chunk tag */ - if (mapping & METADATA_TAG_MAP_WHOLECHUNK) - metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_IPTC, - adapter); - - if (!(mapping & METADATA_TAG_MAP_INDIVIDUALS)) - goto done; - - buf = gst_adapter_peek (adapter, size); - - iptc = iptc_data_new_from_data (buf, size); - if (iptc == NULL) { - goto done; - } - - iptc_data_foreach_dataset (iptc, - metadataparse_iptc_data_foreach_dataset_func, (void *) &user_data); - -done: - - if (iptc) - iptc_data_unref (iptc); - - return; - -} - -/* - * metadatamux_iptc_create_chunk_from_tag_list: - * @buf: buffer that will have the created IPTC chunk - * @size: size of the buffer that will be created - * @taglist: list of tags to be added to IPTC chunk - * - * Get tags from @taglist, create a IPTC chunk based on it and save to @buf. - * Note: The IPTC chunk is NOT wrapped by any bytes specific to any file format - * - * Returns: nothing - */ - -void -metadatamux_iptc_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, - const GstTagList * taglist) -{ - IptcData *iptc = NULL; - GstBuffer *iptc_chunk = NULL; - const GValue *val = NULL; - - if (!(buf && size)) - goto done; - - g_free (*buf); - *buf = NULL; - *size = 0; - - val = gst_tag_list_get_value_index (taglist, GST_TAG_IPTC, 0); - if (val) { - iptc_chunk = gst_value_get_buffer (val); - if (iptc_chunk) { - iptc = iptc_data_new_from_data (GST_BUFFER_DATA (iptc_chunk), - GST_BUFFER_SIZE (iptc_chunk)); - } - } - - if (!iptc) { - iptc = iptc_data_new (); - } - - gst_tag_list_foreach (taglist, metadatamux_iptc_for_each_tag_in_list, iptc); - - iptc_data_save (iptc, buf, size); - - -done: - - if (iptc) - iptc_data_unref (iptc); - - return; -} - -/* - * static helper functions implementation - */ - -/* - * metadataparse_iptc_get_tag_from_iptc: - * @iptc: IPTC tag to look for - * @type: the type of the GStreamer tag mapped to @iptc - * @record: the place into IPTC chunk @iptc belongs to. - * - * This returns the GStreamer tag mapped to an IPTC tag. - * - * Returns: - * <itemizedlist> - * <listitem><para>The GStreamer tag mapped to the @iptc - * </para></listitem> - * <listitem><para>%NULL if there is no mapped GST tag for @iptc - * </para></listitem> - * </itemizedlist> - */ - -static const gchar * -metadataparse_iptc_get_tag_from_iptc (IptcTag iptc, GType * type, - IptcRecord * record) -{ - int i = 0; - - while (mappedTags[i].iptc) { - if (iptc == mappedTags[i].iptc) { - *type = gst_tag_get_type (mappedTags[i].str); - *record = mappedTags[i].record; - break; - } - ++i; - } - - return mappedTags[i].str; - -} - -/* - * metadatamux_iptc_get_iptc_from_tag: - * @tag: GST tag to look for - * @type: the type of the GStreamer @tag - * @record: the place into IPTC chunk @iptc belongs to. - * - * This returns thet IPTC tag mapped to an GStreamer @tag. - * - * Returns: - * <itemizedlist> - * <listitem><para>The IPTC tag mapped to the GST @tag - * </para></listitem> - * <listitem><para>0 if there is no mapped IPTC tag for GST @tag - * </para></listitem> - * </itemizedlist> - */ - -static IptcTag -metadatamux_iptc_get_iptc_from_tag (const gchar * tag, GType * type, - IptcRecord * record) -{ - int i = 0; - - while (mappedTags[i].iptc) { - if (0 == strcmp (mappedTags[i].str, tag)) { - *type = gst_tag_get_type (tag); - *record = mappedTags[i].record; - break; - } - ++i; - } - - return mappedTags[i].iptc; - -} - -/* - * metadataparse_iptc_data_foreach_dataset_func: - * @dataset: IPTC structure from libiptcdata having IPTC tag - * @user_data: pointer to #MEUserData - * - * This function designed to be called for each IPTC tag in a IPTC chunk. This - * function gets the IPTC tag from @dataset and then add to the tag list - * in @user_data by using a merge mode also specified in @user_data - * @see_also: #metadataparse_iptc_tag_list_add - * - * Returns: nothing - */ - -static void -metadataparse_iptc_data_foreach_dataset_func (IptcDataSet * dataset, - void *user_data) -{ - - char buf[1024]; - MEUserData *meudata = (MEUserData *) user_data; - GType type; - IptcRecord record; - const gchar *tag = - metadataparse_iptc_get_tag_from_iptc (dataset->tag, &type, &record); - const gchar *value = iptc_dataset_get_as_str (dataset, buf, 1024); - - if (!tag) - goto done; - - gst_tag_list_add (meudata->taglist, meudata->mode, tag, value, NULL); - -done: - - GST_LOG ("name -> %s", iptc_tag_get_name (dataset->record, dataset->tag)); - GST_LOG ("title -> %s", iptc_tag_get_title (dataset->record, dataset->tag)); - GST_LOG ("description -> %s", iptc_tag_get_description (dataset->record, - dataset->tag)); - GST_LOG ("value = %s", value); - GST_LOG ("record = %d", dataset->record); - - return; - -} - -/* - * metadatamux_iptc_for_each_tag_in_list: - * @list: GStreamer tag list from which @tag belongs to - * @tag: GStreamer tag to be added to the IPTC chunk - * @user_data: pointer to #IptcData in which the tag will be added - * - * This function designed to be called for each tag in GST tag list. This - * function adds get the tag value from tag @list and then add it to the IPTC - * chunk by using #IptcData and related functions from libiptcdata - * @see_also: #metadatamux_iptc_create_chunk_from_tag_list - * - * Returns: nothing - */ - -static void -metadatamux_iptc_for_each_tag_in_list (const GstTagList * list, - const gchar * tag, gpointer user_data) -{ - IptcData *iptc = (IptcData *) user_data; - IptcTag iptc_tag; - IptcRecord record; - GType type; - IptcDataSet *dataset = NULL; - gboolean new_dataset = FALSE; - gchar *tag_value = NULL; - - iptc_tag = metadatamux_iptc_get_iptc_from_tag (tag, &type, &record); - - if (!iptc_tag) - goto done; - - dataset = iptc_data_get_dataset (iptc, record, iptc_tag); - - if (!dataset) { - dataset = iptc_dataset_new (); - new_dataset = TRUE; - } - - iptc_dataset_set_tag (dataset, record, iptc_tag); - - if (gst_tag_list_get_string (list, tag, &tag_value)) { - iptc_dataset_set_data (dataset, (guint8 *) tag_value, strlen (tag_value), - IPTC_DONT_VALIDATE); - g_free (tag_value); - tag_value = NULL; - } - - - if (new_dataset) - iptc_data_add_dataset (iptc, dataset); - -done: - - if (dataset) - iptc_dataset_unref (dataset); -} - - -#endif /* else (ifndef HAVE_IPTC) */ diff --git a/ext/metadata/metadataiptc.h b/ext/metadata/metadataiptc.h deleted file mode 100644 index 843a4925a..000000000 --- a/ext/metadata/metadataiptc.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_METADATA_IPTC_H__ -#define __GST_METADATA_IPTC_H__ - -#include <gst/gst.h> -#include <gst/base/gstadapter.h> -#include "metadatatags.h" - -G_BEGIN_DECLS - -/* - * defines - */ -#define PHOTOSHOP_HEADER "Photoshop 3.0" - - -/* - * external function prototypes - */ - -extern void -metadataparse_iptc_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, - GstAdapter * adapter, MetadataTagMapping mapping); - -extern void -metadatamux_iptc_create_chunk_from_tag_list (guint8 ** buf, guint32 *size, - const GstTagList * taglist); - -G_END_DECLS -#endif /* __GST_METADATA_IPTC_H__ */ diff --git a/ext/metadata/metadatamuxjpeg.c b/ext/metadata/metadatamuxjpeg.c deleted file mode 100644 index 6ced3d7c0..000000000 --- a/ext/metadata/metadatamuxjpeg.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * SECTION: metadatamuxjpeg - * @short_description: This module provides functions to parse JPEG files in - * order to write metadata to it. - * - * This module parses a JPEG stream to find the places in which metadata (EXIF, - * IPTC, XMP) chunks would be written. It also wraps metadata chunks with JPEG - * marks according to the specification. - * - * <refsect2> - * <para> - * #metadatamux_jpeg_init must be called before any other function in this - * module and must be paired with a call to #metadatamux_jpeg_dispose. - * #metadatamux_jpeg_parse is used to parse the stream (find the place - * metadata chunks should be written to). - * #metadatamux_jpeg_lazy_update do nothing. - * </para> - * <para> - * EXIF chunks will always be the first chunk (replaces JFIF). IPTC and XMP - * chunks will be placed or second chunk (after JFIF or EXIF) or third chunk - * if both (IPTC and XMP) are written to the file. - * </para> - * <para> - * When a EXIF chunk is written to the JPEG stream, if there is a JFIF chunk - * as the first chunk, it will be stripped out. - * </para> - * </refsect2> - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "metadatamuxjpeg.h" -#include "metadataxmp.h" - -#include <string.h> - -#ifdef HAVE_IPTC -#include <libiptcdata/iptc-jpeg.h> -#endif - -GST_DEBUG_CATEGORY_EXTERN (gst_metadata_mux_debug); -#define GST_CAT_DEFAULT gst_metadata_mux_debug - -/* - * defines and macros - */ - -#define READ(buf, size) ( (size)--, *((buf)++) ) - -/* - * static helper functions declaration - */ - -static MetadataParsingReturn -metadatamux_jpeg_reading (JpegMuxData * jpeg_data, guint8 ** buf, - guint32 * bufsize, const guint32 offset, const guint8 * step_buf, - guint8 ** next_start, guint32 * next_size); - -static void -metadatamux_wrap_chunk (MetadataChunk * chunk, const guint8 * buf, - guint32 buf_size, guint8 a, guint8 b); - -#ifdef HAVE_IPTC -static gboolean -metadatamux_wrap_iptc_with_ps3 (unsigned char **buf, unsigned int *buf_size); -#endif /* #ifdef HAVE_IPTC */ - - -/* - * extern functions implementations - */ - -/* - * metadatamux_jpeg_init: - * @jpeg_data: [in] jpeg data handler to be inited - * @strip_chunks: Array of chunks (offset and size) marked for removal - * @inject_chunks: Array of chunks (offset, data, size) marked for injection - * adapter (@exif_adpt, @iptc_adpt, @xmp_adpt). Or FALSE if should also put - * them on @strip_chunks. - * - * Init jpeg data handle. - * This function must be called before any other function from this module. - * This function must not be called twice without call to - * #metadatamux_jpeg_dispose beteween them. - * @see_also: #metadatamux_jpeg_dispose #metadatamux_jpeg_parse - * - * Returns: nothing - */ - -void -metadatamux_jpeg_init (JpegMuxData * jpeg_data, - MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks) -{ - jpeg_data->state = JPEG_MUX_NULL; - - jpeg_data->strip_chunks = strip_chunks; - jpeg_data->inject_chunks = inject_chunks; - -} - -/* - * metadatamux_jpeg_dispose: - * @jpeg_data: [in] jpeg data handler to be freed - * - * Call this function to free any resource allocated by #metadatamux_jpeg_init - * @see_also: #metadatamux_jpeg_init - * - * Returns: nothing - */ - -void -metadatamux_jpeg_dispose (JpegMuxData * jpeg_data) -{ - jpeg_data->inject_chunks = NULL; - jpeg_data->strip_chunks = NULL; - - jpeg_data->state = JPEG_MUX_NULL; -} - -/* - * metadatamux_jpeg_parse: - * @jpeg_data: [in] jpeg data handle - * @buf: [in] data to be parsed - * @bufsize: [in] size of @buf in bytes - * @offset: is the offset where @buf starts from the beginnig of the whole - * stream - * @next_start: is a pointer after @buf which indicates where @buf should start - * on the next call to this function. It means, that after returning, this - * function has consumed *@next_start - @buf bytes. Which also means - * that @offset should also be incremanted by (*@next_start - @buf) for the - * next time. - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * This function is used to parse a JPEG stream step-by-step incrementally. - * Basically this function works like a state machine, that will run in a loop - * while there is still bytes in @buf to be read or it has finished parsing. - * If the it hasn't parsed yet and there is no more data in @buf, then the - * current state is saved and a indication will be make about the buffer to - * be passed by the caller function. - * @see_also: #metadatamux_jpeg_init - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if parse has finished. Now strip and - * inject chunks has been found - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -MetadataParsingReturn -metadatamux_jpeg_parse (JpegMuxData * jpeg_data, guint8 * buf, - guint32 * bufsize, const guint32 offset, guint8 ** next_start, - guint32 * next_size) -{ - - int ret = META_PARSING_DONE; - const guint8 *step_buf = buf; - - *next_start = buf; - - if (jpeg_data->state == JPEG_MUX_NULL) { - guint8 mark[2]; - - if (*bufsize < 2) { - GST_INFO ("need more data"); - *next_size = (buf - *next_start) + 2; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - mark[0] = READ (buf, *bufsize); - mark[1] = READ (buf, *bufsize); - - if (mark[0] != 0xFF || mark[1] != 0xD8) { - GST_INFO ("missing marker"); - ret = META_PARSING_ERROR; - goto done; - } - - jpeg_data->state = JPEG_MUX_READING; - - } - - while (ret == META_PARSING_DONE) { - switch (jpeg_data->state) { - case JPEG_MUX_READING: - GST_DEBUG ("start reading"); - ret = - metadatamux_jpeg_reading (jpeg_data, &buf, bufsize, - offset, step_buf, next_start, next_size); - break; - case JPEG_MUX_DONE: - goto done; - break; - default: - GST_INFO ("invalid parser state"); - ret = META_PARSING_ERROR; - break; - } - } - -done: - GST_INFO ("finishing: %d", ret); - return ret; -} - -/* - * metadatamux_jpeg_lazy_update: - * @jpeg_data: [in] jpeg data handle - * - * This function wrap metadata chunk with proper JPEG marks. In case of IPTC - * it will be wrapped by PhotoShop and then by JPEG mark. - * @see_also: #metadata_lazy_update - * - * Returns: nothing - */ - -void -metadatamux_jpeg_lazy_update (JpegMuxData * jpeg_data) -{ - gsize i; - gboolean has_exif = FALSE; - MetadataChunkArray *chunks = jpeg_data->inject_chunks; - - GST_INFO ("checking %" G_GSIZE_FORMAT " chunks", chunks->len); - - for (i = 0; i < chunks->len; ++i) { - - GST_INFO ("checking chunk[%" G_GSIZE_FORMAT "], type=%d, len=%u", - i, chunks->chunk[i].type, chunks->chunk[i].size); - - if (chunks->chunk[i].size > 0 && chunks->chunk[i].data) { - switch (chunks->chunk[i].type) { - case MD_CHUNK_EXIF: - metadatamux_wrap_chunk (&chunks->chunk[i], NULL, 0, 0xFF, 0xE1); - has_exif = TRUE; - break; - case MD_CHUNK_IPTC: -#ifdef HAVE_IPTC - if (metadatamux_wrap_iptc_with_ps3 (&chunks->chunk[i].data, - &chunks->chunk[i].size)) { - metadatamux_wrap_chunk (&chunks->chunk[i], NULL, 0, 0xFF, 0xED); - } else { - GST_ERROR ("Invalid IPTC chunk\n"); - metadata_chunk_array_remove_by_index (chunks, i); - continue; - } -#endif /* #ifdef HAVE_IPTC */ - break; - case MD_CHUNK_XMP: - metadatamux_wrap_chunk (&chunks->chunk[i], - (guint8 *) XMP_HEADER, sizeof (XMP_HEADER), 0xFF, 0xE1); - break; - default: - break; - } - } - } - - if (!has_exif) { - /* EXIF not injected so not strip JFIF anymore */ - metadata_chunk_array_clear (jpeg_data->strip_chunks); - } - -} - - - -/* - * static helper functions implementation - */ - -/* - * metadatamux_jpeg_reading: - * @jpeg_data: [in] jpeg data handle - * @buf: [in] data to be parsed. @buf will increment during the parsing step. - * So it will hold the next byte to be read inside a parsing function or on - * the next nested parsing function. And so, @bufsize will decrement. - * @bufsize: [in] size of @buf in bytes. This value will decrement during the - * parsing for the same reason that @buf will advance. - * @offset: is the offset where @step_buf starts from the beginnig of the - * stream - * @step_buf: holds the pointer to the buffer passed to - * #metadatamux_jpeg_parse. It means that any point inside this function - * the offset (related to the beginning of the whole stream) after the last - * byte read so far is "(*buf - step_buf) + offset" - * @next_start: is a pointer after @step_buf which indicates where the next - * call to #metadatamux_jpeg_parse should start on the next call to this - * function. It means, that after return, this function has - * consumed *@next_start - @buf bytes. Which also means that @offset should - * also be incremanted by (*@next_start - @buf) for the next time. - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * This function is used to parse a JPEG stream step-by-step incrementally. - * If this function quickly finds the place (offset) in which EXIF, IPTC and - * XMP chunk should be written to. - * The found places are written to @jpeg_data->inject_chunks - * @see_also: #metadatamux_jpeg_init - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if parse has finished. Now strip and - * inject chunks has been found. Or some chunk has been found and should be - * held or jumped. - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -static MetadataParsingReturn -metadatamux_jpeg_reading (JpegMuxData * jpeg_data, guint8 ** buf, - guint32 * bufsize, const guint32 offset, const guint8 * step_buf, - guint8 ** next_start, guint32 * next_size) -{ - - int ret = META_PARSING_ERROR; - guint8 mark[2] = { 0x00, 0x00 }; - guint16 chunk_size = 0; - gint64 new_chunk_offset = 0; - MetadataChunk chunk; - gboolean jfif_found = FALSE; - - static const char JfifHeader[] = "JFIF"; - - *next_start = *buf; - - if (*bufsize < 2) { - GST_INFO ("need more data"); - *next_size = (*buf - *next_start) + 2; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - mark[0] = READ (*buf, *bufsize); - mark[1] = READ (*buf, *bufsize); - - GST_DEBUG ("parsing JPEG marker : 0x%02x%02x", mark[0], mark[1]); - - if (mark[0] == 0xFF) { - - chunk_size = READ (*buf, *bufsize) << 8; - chunk_size += READ (*buf, *bufsize); - - if (mark[1] == 0xE0) { /* APP0 - may be JFIF */ - - /* FIXME: whats the 14 ? according to - * http://en.wikipedia.org/wiki/JFIF#JFIF_segment_format - * its the jfif segment without thumbnails - */ - if (chunk_size >= 14 + 2) { - if (*bufsize < sizeof (JfifHeader)) { - GST_INFO ("need more data"); - *next_size = (*buf - *next_start) + sizeof (JfifHeader); - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - if (0 == memcmp (JfifHeader, *buf, sizeof (JfifHeader))) { - jfif_found = TRUE; - } - } else { - /* FIXME: should we check if the first chunk is EXIF? */ - GST_INFO ("chunk size too small %u", chunk_size); - } - - } - if (!jfif_found) { - GST_INFO ("no jfif found, will insert it as needed"); - } - - new_chunk_offset = 2; - - /* EXIF will always be in the begining */ - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - chunk.offset_orig = 2; - chunk.type = MD_CHUNK_EXIF; - metadata_chunk_array_append_sorted (jpeg_data->inject_chunks, &chunk); - - if (jfif_found) { - /* remove JFIF chunk */ - /* this acation can be canceled with lazy update if no Exif is add */ - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - chunk.offset_orig = 2; - chunk.size = chunk_size + 2; /* chunk size plus app marker */ - chunk.type = MD_CHUNK_UNKNOWN; - - metadata_chunk_array_append_sorted (jpeg_data->strip_chunks, &chunk); - - new_chunk_offset = chunk.offset_orig + chunk.size; - } - - /* IPTC */ - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - chunk.offset_orig = new_chunk_offset; - chunk.type = MD_CHUNK_IPTC; - metadata_chunk_array_append_sorted (jpeg_data->inject_chunks, &chunk); - - /* XMP */ - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - chunk.offset_orig = new_chunk_offset; - chunk.type = MD_CHUNK_XMP; - metadata_chunk_array_append_sorted (jpeg_data->inject_chunks, &chunk); - - jpeg_data->state = JPEG_MUX_DONE; - ret = META_PARSING_DONE; - - } else { - GST_INFO ("invalid JPEG chunk"); - ret = META_PARSING_ERROR; - } - - -done: - - return ret; - - -} - -/* - * metadatamux_wrap_chunk: - * @chunk: chunk to be wrapped - * @buf: data to inject in the beginning of @chunk->data and after @a and @b - * @buf_size: size in bytes of @buf - * @a: together with @b forms the JPEG mark to be injected in the beginning - * @b: look at @a - * - * Wraps a chunk if a JPEG mark (@a@b) and, if @buf_size > 0, with some data - * (@buf) - * - * Returns: nothing - */ - -static void -metadatamux_wrap_chunk (MetadataChunk * chunk, const guint8 * buf, - guint32 buf_size, guint8 a, guint8 b) -{ - guint8 *data = g_new (guint8, 4 + buf_size + chunk->size); - - memcpy (data + 4 + buf_size, chunk->data, chunk->size); - g_free (chunk->data); - chunk->data = data; - chunk->size += 4 + buf_size; - data[0] = a; - data[1] = b; - data[2] = ((chunk->size - 2) >> 8) & 0xFF; - data[3] = (chunk->size - 2) & 0xFF; - if (buf && buf_size) { - memcpy (data + 4, buf, buf_size); - } -} - -#ifdef HAVE_IPTC -static gboolean -metadatamux_wrap_iptc_with_ps3 (unsigned char **buf, unsigned int *buf_size) -{ - unsigned int out_size = *buf_size + 4096; - unsigned char *outbuf = g_new (unsigned char, out_size); - int size_written; - gboolean ret = TRUE; - - size_written = - iptc_jpeg_ps3_save_iptc (NULL, 0, *buf, *buf_size, outbuf, out_size); - - g_free (*buf); - *buf = NULL; - *buf_size = 0; - - if (size_written < 0) { - g_free (outbuf); - ret = FALSE; - } else { - *buf_size = size_written; - *buf = outbuf; - } - - return ret; - -} -#endif /* #ifdef HAVE_IPTC */ diff --git a/ext/metadata/metadatamuxjpeg.h b/ext/metadata/metadatamuxjpeg.h deleted file mode 100644 index 018583285..000000000 --- a/ext/metadata/metadatamuxjpeg.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __METADATAMUX_JPEG_H__ -#define __METADATAMUX_JPEG_H__ - -/* - * includes - */ - -#include <gst/base/gstadapter.h> - -#include "metadatatypes.h" - -/* - * enum and types - */ - -G_BEGIN_DECLS - -typedef enum _tag_JpegMuxState -{ - JPEG_MUX_NULL, - JPEG_MUX_READING, - JPEG_MUX_DONE -} JpegMuxState; - - -typedef struct _tag_JpegMuxData -{ - JpegMuxState state; - - MetadataChunkArray * strip_chunks; - MetadataChunkArray * inject_chunks; - -} JpegMuxData; - -/* - * external function prototypes - */ - -extern void -metadatamux_jpeg_init (JpegMuxData * jpeg_data, - MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks); - -extern void metadatamux_jpeg_dispose (JpegMuxData * jpeg_data); - -extern MetadataParsingReturn -metadatamux_jpeg_parse (JpegMuxData * jpeg_data, guint8 * buf, - guint32 * bufsize, const guint32 offset, guint8 ** next_start, - guint32 * next_size); - -extern void metadatamux_jpeg_lazy_update (JpegMuxData * jpeg_data); - -G_END_DECLS -#endif /* __METADATAMUX_JPEG_H__ */ diff --git a/ext/metadata/metadatamuxpng.c b/ext/metadata/metadatamuxpng.c deleted file mode 100644 index 091b9b1e0..000000000 --- a/ext/metadata/metadatamuxpng.c +++ /dev/null @@ -1,558 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * SECTION: metadatamuxpng - * @short_description: This module provides functions to parse PNG files in - * order to write metadata to it. - * - * This module parses a PNG stream to find the places in which XMP metadata - * chunks would be written. It also wraps metadata chunks with PNG marks - * according to the specification. - * - * <refsect2> - * <para> - * #metadatamux_png_init must be called before any other function in this - * module and must be paired with a call to #metadatamux_png_dispose. - * #metadatamux_png_parse is used to parse the stream (find the place - * metadata chunks should be written to). - * #metadatamux_png_lazy_update do nothing. - * </para> - * <para> - * EXIF chunks will always be the first chunk (replaces JFIF). IPTC and XMP - * chunks will be placed or second chunk (after JFIF or EXIF) or third chunk - * if both (IPTC and XMP) are written to the file. - * </para> - * <para> - * When a EXIF chunk is written to the PNG stream, if there is a JFIF chunk - * as the first chunk, it will be stripped out. - * </para> - * </refsect2> - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "metadatamuxpng.h" - -#include <string.h> - -GST_DEBUG_CATEGORY_EXTERN (gst_metadata_mux_debug); -#define GST_CAT_DEFAULT gst_metadata_mux_debug - -/* - * defines and macros - */ - -#define READ(buf, size) ( (size)--, *((buf)++) ) - -/* - * static global vars - */ - -static const guint32 metadatamux_crc_table[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, - 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, - 0x7eb17cbd, - 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, - 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, - 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, - 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, - 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, - 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, - 0xc1611dab, - 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, - 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, - 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, - 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, - 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, - 0x3ab551ce, - 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, - 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, - 0xb966d409, - 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, - 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, - 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, - 0x1e01f268, - 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, - 0x89d32be0, - 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, - 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, - 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, - 0xbb0b4703, - 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, - 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, - 0x7bb12bae, - 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, - 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, - 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, - 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, - 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, - 0xdebb9ec5, - 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, - 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d -}; - - -/* - * static helper functions declaration - */ - -static MetadataParsingReturn -metadatamux_png_reading (PngMuxData * png_data, guint8 ** buf, - guint32 * bufsize, const guint32 offset, const guint8 * step_buf, - guint8 ** next_start, guint32 * next_size); - -static guint32 metadatamux_update_crc (guint32 crc, guint8 * buf, guint32 len); - -static guint32 metadatamux_calc_crc (guint8 * buf, guint32 len); - -static void metadatamux_wrap_xmp_chunk (MetadataChunk * chunk); - -/* - * extern functions implementations - */ - -/* - * metadatamux_png_init: - * @png_data: [in] png data handler to be inited - * @strip_chunks: Array of chunks (offset and size) marked for removal - * @inject_chunks: Array of chunks (offset, data, size) marked for injection - * adapter (@exif_adpt, @iptc_adpt, @xmp_adpt). Or FALSE if should also put - * them on @strip_chunks. - * - * Init png data handle. - * This function must be called before any other function from this module. - * This function must not be called twice without call to - * #metadatamux_png_dispose beteween them. - * @see_also: #metadatamux_png_dispose #metadatamux_png_parse - * - * Returns: nothing - */ - -void -metadatamux_png_init (PngMuxData * png_data, - MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks) -{ - png_data->state = PNG_MUX_NULL; - - png_data->strip_chunks = strip_chunks; - png_data->inject_chunks = inject_chunks; -} - -/* - * metadatamux_png_dispose: - * png_data: [in] png data handler to be freed - * - * Call this function to free any resource allocated by #metadatamux_png_init - * @see_also: #metadatamux_png_init - * - * Returns: nothing - */ - -void -metadatamux_png_dispose (PngMuxData * png_data) -{ - png_data->strip_chunks = NULL; - png_data->inject_chunks = NULL; - - png_data->state = PNG_MUX_NULL; -} - -/* - * metadatamux_png_parse: - * @png_data: [in] png data handle - * @buf: [in] data to be parsed - * @bufsize: [in] size of @buf in bytes - * @offset: is the offset where @buf starts from the beginnig of the whole - * stream - * @next_start: is a pointer after @buf which indicates where @buf should start - * on the next call to this function. It means, that after returning, this - * function has consumed *@next_start - @buf bytes. Which also means - * that @offset should also be incremanted by (*@next_start - @buf) for the - * next time. - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * This function is used to parse a PNG stream step-by-step incrementally. - * Basically this function works like a state machine, that will run in a loop - * while there is still bytes in @buf to be read or it has finished parsing. - * If the it hasn't parsed yet and there is no more data in @buf, then the - * current state is saved and a indication will be make about the buffer to - * be passed by the caller function. - * @see_also: #metadatamux_png_init - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if parse has finished. Now strip and - * inject chunks has been found - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -MetadataParsingReturn -metadatamux_png_parse (PngMuxData * png_data, guint8 * buf, - guint32 * bufsize, const guint32 offset, guint8 ** next_start, - guint32 * next_size) -{ - - int ret = META_PARSING_DONE; - guint8 mark[8]; - const guint8 *step_buf = buf; - - *next_start = buf; - - if (png_data->state == PNG_MUX_NULL) { - - if (*bufsize < 8) { - *next_size = (buf - *next_start) + 8; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - mark[0] = READ (buf, *bufsize); - mark[1] = READ (buf, *bufsize); - mark[2] = READ (buf, *bufsize); - mark[3] = READ (buf, *bufsize); - mark[4] = READ (buf, *bufsize); - mark[5] = READ (buf, *bufsize); - mark[6] = READ (buf, *bufsize); - mark[7] = READ (buf, *bufsize); - - if (mark[0] != 0x89 || mark[1] != 0x50 || mark[2] != 0x4E || mark[3] != 0x47 - || mark[4] != 0x0D || mark[5] != 0x0A || mark[6] != 0x1A - || mark[7] != 0x0A) { - ret = META_PARSING_ERROR; - goto done; - } - - png_data->state = PNG_MUX_READING; - - } - - while (ret == META_PARSING_DONE) { - switch (png_data->state) { - case PNG_MUX_READING: - ret = - metadatamux_png_reading (png_data, &buf, bufsize, - offset, step_buf, next_start, next_size); - break; - case PNG_MUX_DONE: - goto done; - break; - default: - ret = META_PARSING_ERROR; - break; - } - } - -done: - - return ret; - -} - -/* - * metadatamux_png_lazy_update: - * @png_data: [in] png data handle - * - * This function wrap metadata chunk with proper PNG bytes. - * @see_also: #metadata_lazy_update - * - * Returns: nothing - */ - -void -metadatamux_png_lazy_update (PngMuxData * png_data) -{ - gsize i; - MetadataChunkArray *chunks = png_data->inject_chunks; - - GST_INFO ("checking %" G_GSIZE_FORMAT " chunks", chunks->len); - - for (i = 0; i < chunks->len; ++i) { - - GST_INFO ("checking chunk[%" G_GSIZE_FORMAT "], type=%d, len=%u", - i, chunks->chunk[i].type, chunks->chunk[i].size); - - if (chunks->chunk[i].size > 0 && chunks->chunk[i].data) { - switch (chunks->chunk[i].type) { - case MD_CHUNK_XMP: - metadatamux_wrap_xmp_chunk (&chunks->chunk[i]); - break; - default: - GST_ERROR ("Unexpected chunk for PNG muxer."); - break; - } - } - } -} - - -/* - * static helper functions implementation - */ - -/* - * metadatamux_png_reading: - * @png_data: [in] png data handle - * @buf: [in] data to be parsed. @buf will increment during the parsing step. - * So it will hold the next byte to be read inside a parsing function or on - * the next nested parsing function. And so, @bufsize will decrement. - * @bufsize: [in] size of @buf in bytes. This value will decrement during the - * parsing for the same reason that @buf will advance. - * @offset: is the offset where @step_buf starts from the beginnig of the - * stream - * @step_buf: holds the pointer to the buffer passed to - * #metadatamux_png_parse. It means that any point inside this function - * the offset (related to the beginning of the whole stream) after the last - * byte read so far is "(*buf - step_buf) + offset" - * @next_start: is a pointer after @step_buf which indicates where the next - * call to #metadatamux_png_parse should start on the next call to this - * function. It means, that after return, this function has - * consumed *@next_start - @buf bytes. Which also means that @offset should - * also be incremanted by (*@next_start - @buf) for the next time. - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * This function is used to parse a PNG stream step-by-step incrementally. - * If this function quickly finds the place (offset) in which EXIF, IPTC and - * XMP chunk should be written to. - * The found places are written to @png_data->inject_chunks - * @see_also: #metadatamux_png_init - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if parse has finished. Now strip and - * inject chunks has been found. Or some chunk has been found and should be - * held or jumped. - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - - -static MetadataParsingReturn -metadatamux_png_reading (PngMuxData * png_data, guint8 ** buf, - guint32 * bufsize, const guint32 offset, const guint8 * step_buf, - guint8 ** next_start, guint32 * next_size) -{ - - int ret = META_PARSING_ERROR; - guint8 mark[4]; - guint32 chunk_size = 0; - MetadataChunk chunk; - - *next_start = *buf; - - if (*bufsize < 8) { - *next_size = (*buf - *next_start) + 8; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - chunk_size = READ (*buf, *bufsize) << 24; - chunk_size += READ (*buf, *bufsize) << 16; - chunk_size += READ (*buf, *bufsize) << 8; - chunk_size += READ (*buf, *bufsize); - - mark[0] = READ (*buf, *bufsize); - mark[1] = READ (*buf, *bufsize); - mark[2] = READ (*buf, *bufsize); - mark[3] = READ (*buf, *bufsize); - - if (!(mark[0] == 'I' && mark[1] == 'H' && mark[2] == 'D' && mark[3] == 'R')) { - ret = META_PARSING_ERROR; - png_data->state = PNG_MUX_NULL; - goto done; - } - - /* always inject after first chunk (IHDR) */ - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - /* 8(header) + 4(size) +4(id) + chunksize + 4(crc) */ - chunk.offset_orig = chunk_size + 20; - chunk.type = MD_CHUNK_XMP; - - metadata_chunk_array_append_sorted (png_data->inject_chunks, &chunk); - - png_data->state = PNG_MUX_DONE; - ret = META_PARSING_DONE; - -done: - - return ret; - - -} - -/* - * metadatamux_update_crc: - * @crc: seed to calculate the CRC - * @buf: data to calculate the CRC for - * @len: size in bytes of @buf - * - * Calculates the CRC of a data buffer for a seed @crc. - * @see_also: #metadatamux_calc_crc - * - * Returns: the CRC of the bytes buf[0..len-1]. - */ - -static guint32 -metadatamux_update_crc (guint32 crc, guint8 * buf, guint32 len) -{ - guint32 c = crc; - guint32 n; - - for (n = 0; n < len; n++) { - c = metadatamux_crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); - } - return c; -} - -/* - * metadatamux_calc_crc: - * @buf: data to calculate the CRC for - * @len: size in bytes of @buf - * - * Calculates the CRC of a data buffer. - * - * Returns: the CRC of the bytes buf[0..len-1]. - */ - -static guint32 -metadatamux_calc_crc (guint8 * buf, guint32 len) -{ - return metadatamux_update_crc (0xffffffffL, buf, len) ^ 0xffffffffL; -} - - -/* - * metadatamux_wrap_xmp_chunk: - * @chunk: chunk to be wrapped - * - * Wraps a XMP chunk with proper PNG bytes (mark, size and crc in the end) - * - * Returns: nothing - */ - -static void -metadatamux_wrap_xmp_chunk (MetadataChunk * chunk) -{ - static const char XmpHeader[] = "XML:com.adobe.xmp"; - guint8 *data = NULL; - guint32 crc; - - data = g_new (guint8, 12 + 18 + 4 + chunk->size); - - memcpy (data + 8, XmpHeader, 18); - memset (data + 8 + 18, 0x00, 4); - memcpy (data + 8 + 18 + 4, chunk->data, chunk->size); - g_free (chunk->data); - chunk->data = data; - chunk->size += 18 + 4; - data[0] = (chunk->size >> 24) & 0xFF; - data[1] = (chunk->size >> 16) & 0xFF; - data[2] = (chunk->size >> 8) & 0xFF; - data[3] = chunk->size & 0xFF; - data[4] = 'i'; - data[5] = 'T'; - data[6] = 'X'; - data[7] = 't'; - crc = metadatamux_calc_crc (data + 4, chunk->size + 4); - data[chunk->size + 8] = (crc >> 24) & 0xFF; - data[chunk->size + 9] = (crc >> 16) & 0xFF; - data[chunk->size + 10] = (crc >> 8) & 0xFF; - data[chunk->size + 11] = crc & 0xFF; - - chunk->size += 12; - -} diff --git a/ext/metadata/metadatamuxpng.h b/ext/metadata/metadatamuxpng.h deleted file mode 100644 index 8680ca57b..000000000 --- a/ext/metadata/metadatamuxpng.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __METADATAMUX_PNG_H__ -#define __METADATAMUX_PNG_H__ - -/* - * includes - */ - -#include <gst/base/gstadapter.h> - -#include "metadatatypes.h" - -G_BEGIN_DECLS - -/* - * enum and types - */ - -typedef enum _tag_PngMuxState -{ - PNG_MUX_NULL, - PNG_MUX_READING, - PNG_MUX_JUMPING, - PNG_MUX_XMP, - PNG_MUX_DONE -} PngMuxState; - - -typedef struct _tag_PngMuxData -{ - PngMuxState state; - - MetadataChunkArray * strip_chunks; - MetadataChunkArray * inject_chunks; - -} PngMuxData; - -/* - * external function prototypes - */ - -extern void -metadatamux_png_init (PngMuxData * png_data, - MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks); - -extern void metadatamux_png_dispose (PngMuxData * png_data); - -extern void metadatamux_png_lazy_update (PngMuxData * png_data); - -extern MetadataParsingReturn -metadatamux_png_parse (PngMuxData * png_data, guint8 * buf, - guint32 * bufsize, const guint32 offset, guint8 ** next_start, - guint32 * next_size); - -G_END_DECLS -#endif /* __METADATAMUX_PNG_H__ */ diff --git a/ext/metadata/metadataparsejpeg.c b/ext/metadata/metadataparsejpeg.c deleted file mode 100644 index bcc2f3167..000000000 --- a/ext/metadata/metadataparsejpeg.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * SECTION: metadataparsejpeg - * @short_description: This module provides functions to parse JPEG files - * - * This module parses a JPEG stream finding metadata chunks, and marking them - * to be removed from the stream and saving them in a adapter. - * - * <refsect2> - * <para> - * #metadataparse_jpeg_init must be called before any other function in this - * module and must be paired with a call to #metadataparse_jpeg_dispose. - * #metadataparse_jpeg_parse is used to parse the stream (find the metadata - * chunks and the place it should be written to. - * #metadataparse_jpeg_lazy_update do nothing. - * </para> - * <para> - * This module tries to find metadata chunk until it reaches the "start of scan - * image". So if the metadata chunk, which could be EXIF, XMP or IPTC (inside - * Photoshop), is after the "start of scan image" it will not be found. This is - * 'cause of performance reason and 'cause we believe that files with metadata - * chunk after the "scan of image" chunk are very bad practice, so we don't - * worry about them. - * </para> - * <para> - * If it is working in non-parse_only mode, and the first chunk is a EXIF - * instead of a JFIF chunk, the EXIF chunk will be marked for removal and a new - * JFIF chunk will be create and marked to be injected as the first chunk. - * </para> - * </refsect2> - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include <string.h> - -#include "metadataparsejpeg.h" -#include "metadataparseutil.h" -#include "metadataexif.h" -#include "metadataxmp.h" - -#ifdef HAVE_IPTC -#include <libiptcdata/iptc-jpeg.h> -#include "metadataiptc.h" -#endif - -GST_DEBUG_CATEGORY_EXTERN (gst_metadata_demux_debug); -#define GST_CAT_DEFAULT gst_metadata_demux_debug - -/* - * defines and macros - */ - -/* returns the current byte, advance to the next one and decrease the size */ -#define READ(buf, size) ( (size)--, *((buf)++) ) - -/* - * static helper functions declaration - */ - -static MetadataParsingReturn -metadataparse_jpeg_reading (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, const guint32 offset, const guint8 * step_buf, - guint8 ** next_start, guint32 * next_size); - -static MetadataParsingReturn -metadataparse_jpeg_exif (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size); - -#ifdef HAVE_IPTC -static MetadataParsingReturn -metadataparse_jpeg_iptc (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size); -#endif - -static MetadataParsingReturn -metadataparse_jpeg_xmp (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size); - -static MetadataParsingReturn -metadataparse_jpeg_jump (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size); - -/* - * extern functions implementations - */ - -/* - * metadataparse_jpeg_init: - * @jpeg_data: [in] jpeg data handler to be inited - * @exif_adpt: where to create/write an adapter to hold the EXIF chunk found - * @iptc_adpt: where to create/write an adapter to hold the IPTC chunk found - * @xmp_adpt: where to create/write an adapter to hold the XMP chunk found - * @strip_chunks: Array of chunks (offset and size) marked for removal - * @inject_chunks: Array of chunks (offset, data, size) marked for injection - * @parse_only: TRUE if it should only find the chunks and write then to the - * adapter (@exif_adpt, @iptc_adpt, @xmp_adpt). Or FALSE if should also put - * them on @strip_chunks. - * - * Init jpeg data handle. - * This function must be called before any other function from this module. - * This function must not be called twice without call to - * #metadataparse_jpeg_dispose beteween them. - * @see_also: #metadataparse_jpeg_dispose #metadataparse_jpeg_parse - * - * Returns: nothing - */ - -void -metadataparse_jpeg_init (JpegParseData * jpeg_data, GstAdapter ** exif_adpt, - GstAdapter ** iptc_adpt, GstAdapter ** xmp_adpt, - MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks, - gboolean parse_only) -{ - jpeg_data->state = JPEG_PARSE_NULL; - jpeg_data->exif_adapter = exif_adpt; - jpeg_data->iptc_adapter = iptc_adpt; - jpeg_data->xmp_adapter = xmp_adpt; - jpeg_data->read = 0; - jpeg_data->jfif_found = FALSE; - - jpeg_data->strip_chunks = strip_chunks; - jpeg_data->inject_chunks = inject_chunks; - - jpeg_data->parse_only = parse_only; - -} - -/* - * metadataparse_jpeg_dispose: - * @jpeg_data: [in] jpeg data handler to be freed - * - * Call this function to free any resource allocated by - * #metadataparse_jpeg_init - * @see_also: #metadataparse_jpeg_init - * - * Returns: nothing - */ - -void -metadataparse_jpeg_dispose (JpegParseData * jpeg_data) -{ - jpeg_data->exif_adapter = NULL; - jpeg_data->iptc_adapter = NULL; - jpeg_data->xmp_adapter = NULL; -} - -/* - * metadataparse_jpeg_parse: - * @jpeg_data: [in] jpeg data handle - * @buf: [in] data to be parsed - * @bufsize: [in] size of @buf in bytes - * @offset: is the offset where @buf starts from the beginnig of the whole - * stream - * @next_start: is a pointer after @buf which indicates where @buf should start - * on the next call to this function. It means, that after returning, this - * function has consumed *@next_start - @buf bytes. Which also means - * that @offset should also be incremanted by (*@next_start - @buf) for the - * next time. - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * This function is used to parse a JPEG stream step-by-step incrementally. - * Basically this function works like a state machine, that will run in a loop - * while there is still bytes in @buf to be read or it has finished parsing. - * If the it hasn't parsed yet and there is no more data in @buf, then the - * current state is saved and a indication will be make about the buffer to - * be passed by the caller function. - * @see_also: #metadataparse_jpeg_init - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if parse has finished. Now strip and - * inject chunks has been found - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -MetadataParsingReturn -metadataparse_jpeg_parse (JpegParseData * jpeg_data, guint8 * buf, - guint32 * bufsize, const guint32 offset, guint8 ** next_start, - guint32 * next_size) -{ - int ret = META_PARSING_DONE; - const guint8 *step_buf = buf; - - /* step_buf holds where buf starts. this const value will be passed to - the nested parsing function, so those function knows how far they from - the initial buffer. This is not related to the beginning of the whole - stream, it is just related to the buf passed in this step to this - function */ - - *next_start = buf; - - if (jpeg_data->state == JPEG_PARSE_NULL) { - guint8 mark[2]; - - /* only the first time this function is called it will verify the stream - type to be sure it is a JPEG */ - - if (*bufsize < 2) { - GST_INFO ("need more data"); - *next_size = (buf - *next_start) + 2; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - mark[0] = READ (buf, *bufsize); - mark[1] = READ (buf, *bufsize); - - if (mark[0] != 0xFF || mark[1] != 0xD8) { - GST_INFO ("missing marker"); - ret = META_PARSING_ERROR; - goto done; - } - jpeg_data->state = JPEG_PARSE_READING; - } - - while (ret == META_PARSING_DONE) { - switch (jpeg_data->state) { - case JPEG_PARSE_READING: - GST_DEBUG ("start reading"); - ret = - metadataparse_jpeg_reading (jpeg_data, &buf, bufsize, - offset, step_buf, next_start, next_size); - break; - case JPEG_PARSE_JUMPING: - GST_DEBUG ("jump"); - ret = - metadataparse_jpeg_jump (jpeg_data, &buf, bufsize, next_start, - next_size); - break; - case JPEG_PARSE_EXIF: - GST_DEBUG ("parse exif"); - ret = - metadataparse_jpeg_exif (jpeg_data, &buf, bufsize, next_start, - next_size); - break; - case JPEG_PARSE_IPTC: - GST_DEBUG ("parse iptc"); -#ifdef HAVE_IPTC - ret = - metadataparse_jpeg_iptc (jpeg_data, &buf, bufsize, next_start, - next_size); -#endif - break; - case JPEG_PARSE_XMP: - GST_DEBUG ("parse xmp"); - ret = - metadataparse_jpeg_xmp (jpeg_data, &buf, bufsize, next_start, - next_size); - break; - case JPEG_PARSE_DONE: - goto done; - break; - default: - GST_INFO ("invalid parser state"); - ret = META_PARSING_ERROR; - break; - } - } - -done: - GST_INFO ("finishing: %d", ret); - return ret; -} - -/* - * metadataparse_jpeg_lazy_update: - * @jpeg_data: [in] jpeg data handle - * - * This function do nothing - * @see_also: #metadata_lazy_update - * - * Returns: nothing - */ - -void -metadataparse_jpeg_lazy_update (JpegParseData * jpeg_data) -{ - /* nothing to do */ -} - -/* - * static helper functions implementation - */ - -/* - * metadataparse_jpeg_reading: - * @jpeg_data: [in] jpeg data handle - * @buf: [in] data to be parsed. @buf will increment during the parsing step. - * So it will hold the next byte to be read inside a parsing function or on - * the next nested parsing function. And so, @bufsize will decrement. - * @bufsize: [in] size of @buf in bytes. This value will decrement during the - * parsing for the same reason that @buf will advance. - * @offset: is the offset where @step_buf starts from the beginnig of the - * stream - * @step_buf: holds the pointer to the buffer passed to - * #metadataparse_jpeg_parse. It means that any point inside this function - * the offset (related to the beginning of the whole stream) after the last - * byte read so far is "(*buf - step_buf) + offset" - * @next_start: is a pointer after @step_buf which indicates where the next - * call to #metadataparse_jpeg_parse should start on the next call to this - * function. It means, that after return, this function has - * consumed *@next_start - @buf bytes. Which also means that @offset should - * also be incremanted by (*@next_start - @buf) for the next time. - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * This function is used to parse a JPEG stream step-by-step incrementally. - * If this function finds a EXIF, IPTC or XMP chunk (or a chunk that should be - * jumped), then it changes the state of the parsing process so that the - * remaing parsing can be done by another more specialized function. - * @see_also: #metadataparse_jpeg_init #metadataparse_jpeg_exif - * #metadataparse_jpeg_iptc #metadataparse_jpeg_xmp #metadataparse_jpeg_jump - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if parse has finished. Now strip and - * inject chunks has been found. Or some chunk has been found and should be - * held or jumped. - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -/* look for markers */ -static MetadataParsingReturn -metadataparse_jpeg_reading (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, const guint32 offset, const guint8 * step_buf, - guint8 ** next_start, guint32 * next_size) -{ - - int ret = META_PARSING_ERROR; - guint8 mark[2] = { 0x00, 0x00 }; - guint16 chunk_size = 0; - - static const char JfifHeader[] = "JFIF"; - - *next_start = *buf; - - if (*bufsize < 2) { - *next_size = (*buf - *next_start) + 2; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - mark[0] = READ (*buf, *bufsize); - mark[1] = READ (*buf, *bufsize); - - GST_DEBUG ("parsing JPEG marker : 0x%02x%02x", mark[0], mark[1]); - - if (mark[0] == 0xFF) { - if (mark[1] == 0xD9) { /* EOI - end of image */ - ret = META_PARSING_DONE; - jpeg_data->state = JPEG_PARSE_DONE; - goto done; - } else if (mark[1] == 0xDA) { /* SOS - start of scan */ - /* start of scan image, lets not look behind of this */ - ret = META_PARSING_DONE; - jpeg_data->state = JPEG_PARSE_DONE; - goto done; - } - - if (*bufsize < 2) { - *next_size = (*buf - *next_start) + 2; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - chunk_size = READ (*buf, *bufsize) << 8; - chunk_size += READ (*buf, *bufsize); - - if (mark[1] == 0xE0) { /* APP0 - may be JFIF */ - - /* FIXME: whats the 14 ? according to - * http://en.wikipedia.org/wiki/JFIF#JFIF_segment_format - * its the jfif segment without thumbnails - */ - if (chunk_size >= 14 + 2) { - if (*bufsize < 14) { - *next_size = (*buf - *next_start) + 14; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - if (0 == memcmp (JfifHeader, *buf, sizeof (JfifHeader))) { - jpeg_data->jfif_found = TRUE; - } - } - - } else if (mark[1] == 0xE1) { /* APP1 - may be it is Exif or XMP */ - - if (chunk_size >= sizeof (EXIF_HEADER) + 2) { - if (*bufsize < sizeof (EXIF_HEADER)) { - *next_size = (*buf - *next_start) + sizeof (EXIF_HEADER); - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - if (0 == memcmp (EXIF_HEADER, *buf, sizeof (EXIF_HEADER))) { - MetadataChunk chunk; - - if (!jpeg_data->parse_only) { - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - - chunk.offset_orig = (*buf - step_buf) + offset - 4; /* 4 == maker + size */ - - chunk.size = chunk_size + 2; /* chunk size plus app marker */ - chunk.type = MD_CHUNK_EXIF; - - metadata_chunk_array_append_sorted (jpeg_data->strip_chunks, - &chunk); - - } - - if (!jpeg_data->jfif_found) { - /* only inject if no JFIF has been found */ - - if (!jpeg_data->parse_only) { - - static const guint8 segment[] = { 0xff, 0xe0, 0x00, 0x10, - 0x4a, 0x46, 0x49, 0x46, 0x00, - 0x01, 0x02, - 0x00, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x00 - }; - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - chunk.offset_orig = 2; - chunk.size = 18; - chunk.type = MD_CHUNK_UNKNOWN; - chunk.data = g_new (guint8, 18); - memcpy (chunk.data, segment, 18); - - metadata_chunk_array_append_sorted (jpeg_data->inject_chunks, - &chunk); - - } - - } - - if (jpeg_data->exif_adapter) { - - jpeg_data->read = chunk_size - 2; - jpeg_data->state = JPEG_PARSE_EXIF; - ret = META_PARSING_DONE; - goto done; - } - } - if (chunk_size >= sizeof (XMP_HEADER) + 2) { - if (*bufsize < sizeof (XMP_HEADER)) { - *next_size = (*buf - *next_start) + sizeof (XMP_HEADER); - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - if (0 == memcmp (XMP_HEADER, *buf, sizeof (XMP_HEADER))) { - - if (!jpeg_data->parse_only) { - - MetadataChunk chunk; - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - chunk.offset_orig = (*buf - step_buf) + offset - 4; /* 4 == maker + size */ - chunk.size = chunk_size + 2; /* chunk size plus app marker */ - chunk.type = MD_CHUNK_XMP; - - metadata_chunk_array_append_sorted (jpeg_data->strip_chunks, - &chunk); - - } - - /* if adapter has been provided, prepare to hold chunk */ - if (jpeg_data->xmp_adapter) { - *buf += sizeof (XMP_HEADER); - *bufsize -= sizeof (XMP_HEADER); - jpeg_data->read = chunk_size - 2 - sizeof (XMP_HEADER); - jpeg_data->state = JPEG_PARSE_XMP; - ret = META_PARSING_DONE; - goto done; - } - } - } - } - } -#ifdef HAVE_IPTC - else if (mark[1] == 0xED) { - /* may be it is photoshop and may be there is iptc */ - - if (chunk_size >= 16) { /* size2 "Photoshop 3.0" */ - - if (*bufsize < 14) { - *next_size = (*buf - *next_start) + 14; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - if (0 == memcmp (PHOTOSHOP_HEADER, *buf, sizeof (PHOTOSHOP_HEADER))) { - - if (!jpeg_data->parse_only) { - - MetadataChunk chunk; - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - chunk.offset_orig = (*buf - step_buf) + offset - 4; /* 4 == maker + size */ - chunk.size = chunk_size + 2; /* chunk size plus app marker */ - chunk.type = MD_CHUNK_IPTC; - - metadata_chunk_array_append_sorted (jpeg_data->strip_chunks, - &chunk); - - } - - /* if adapter has been provided, prepare to hold chunk */ - if (jpeg_data->iptc_adapter) { - jpeg_data->read = chunk_size - 2; - jpeg_data->state = JPEG_PARSE_IPTC; - ret = META_PARSING_DONE; - goto done; - } - } - } - } -#endif /* #ifdef HAVE_IPTC */ - - /* just set jump sise */ - jpeg_data->read = chunk_size - 2; - jpeg_data->state = JPEG_PARSE_JUMPING; - ret = META_PARSING_DONE; - - } else { - /* invalid JPEG chunk */ - ret = META_PARSING_ERROR; - } - - -done: - - return ret; - - -} - -/* - * metadataparse_jpeg_exif: - * @jpeg_data: [in] jpeg data handle - * @buf: [in] data to be parsed - * @bufsize: [in] size of @buf in bytes - * @next_start: look at #metadataparse_jpeg_reading - * @next_size: look at #metadataparse_jpeg_reading - * NOTE: To have a explanation of each parameters of this function look at - * the documentation of #metadataparse_jpeg_reading - * - * This function saves the EXIF chunk to @jpeg_data->exif_adapter and makes the - * parsing process point to the next buffer after the EXIF chunk. - * This function will be called by the parsing process 'cause at some point - * #metadataparse_jpeg_reading found out the EXIF chunk, skipped the JPEG - * wrapper bytes and changed the state of parsing process to JPEG_PARSE_EXIF. - * Which just happens if @jpeg_data->parse_only is FALSE and there is a EXIF - * chunk into the stream and @jpeg_data->exif_adapter is not NULL. - * This function will just be called once even if there is more than one EXIF - * chunk in the stream. This function do it by setting @jpeg_data->exif_adapter - * to NULL. - * After this function has completely parsed (hold) the chunk, it changes the - * parsing state back to JPEG_PARSE_READING which makes - * #metadataparse_jpeg_reading to be called again - * @see_also: #metadataparse_util_hold_chunk #metadataparse_jpeg_reading - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if the chunk bas been completely hold - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -static MetadataParsingReturn -metadataparse_jpeg_exif (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size) -{ - int ret; - - ret = metadataparse_util_hold_chunk (&jpeg_data->read, buf, - bufsize, next_start, next_size, jpeg_data->exif_adapter); - if (ret == META_PARSING_DONE) { - - jpeg_data->state = JPEG_PARSE_READING; - - /* if there is a second Exif chunk in the file it will be jumped */ - jpeg_data->exif_adapter = NULL; - } - return ret; - -} - -/* - * metadataparse_jpeg_iptc: - * - * Look at #metadataparse_jpeg_exif. This function has the same behavior as - * that. The only difference is that this function also cut out others - * PhotoShop data and only holds IPTC data in it. - * - */ - -#ifdef HAVE_IPTC -static MetadataParsingReturn -metadataparse_jpeg_iptc (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size) -{ - - int ret; - - ret = metadataparse_util_hold_chunk (&jpeg_data->read, buf, - bufsize, next_start, next_size, jpeg_data->iptc_adapter); - - - if (ret == META_PARSING_DONE) { - - const guint8 *buf; - guint32 size; - unsigned int iptc_len; - int res; - - jpeg_data->state = JPEG_PARSE_READING; - - size = gst_adapter_available (*jpeg_data->iptc_adapter); - buf = gst_adapter_peek (*jpeg_data->iptc_adapter, size); - - /* FIXME: currently we are throwing away others PhotoShop data */ - res = iptc_jpeg_ps3_find_iptc (buf, size, &iptc_len); - - if (res < 0) { - /* error */ - ret = META_PARSING_ERROR; - } else if (res == 0) { - /* no iptc data found */ - gst_adapter_clear (*jpeg_data->iptc_adapter); - } else { - gst_adapter_flush (*jpeg_data->iptc_adapter, res); - size = gst_adapter_available (*jpeg_data->iptc_adapter); - if (size > iptc_len) { - GstBuffer *buf; - - buf = gst_adapter_take_buffer (*jpeg_data->iptc_adapter, iptc_len); - gst_adapter_clear (*jpeg_data->iptc_adapter); - gst_adapter_push (*jpeg_data->iptc_adapter, buf); - } - } - - /* if there is a second Iptc chunk in the file it will be jumped */ - jpeg_data->iptc_adapter = NULL; - - } - - return ret; - -} -#endif - -/* - * metadataparse_jpeg_xmp: - * - * Look at #metadataparse_jpeg_exif. This function has the same behavior as - * that. - * - */ - -static MetadataParsingReturn -metadataparse_jpeg_xmp (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size) -{ - int ret; - - ret = metadataparse_util_hold_chunk (&jpeg_data->read, buf, - bufsize, next_start, next_size, jpeg_data->xmp_adapter); - - if (ret == META_PARSING_DONE) { - jpeg_data->state = JPEG_PARSE_READING; - /* if there is a second XMP chunk in the file it will be jumped */ - jpeg_data->xmp_adapter = NULL; - } - return ret; -} - -/* - * metadataparse_jpeg_jump: - * @jpeg_data: [in] jpeg data handle - * @buf: [in] data to be parsed - * @bufsize: [in] size of @buf in bytes - * @next_start: look at #metadataparse_jpeg_reading - * @next_size: look at #metadataparse_jpeg_reading - * NOTE: To have a explanation of each parameters of this function look at - * the documentation of #metadataparse_jpeg_reading - * - * This function just makes a chunk we are not interested in to be jumped. - * This is done basically by incrementing @next_start and @buf, - * and decreasing @bufsize and setting the next parsing state properly. - * @see_also: #metadataparse_jpeg_reading #metadataparse_util_jump_chunk - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_DONE if bytes has been skiped and there is - * still data in @buf - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if the skiped bytes end at - * some point after @buf + @bufsize - * </para></listitem> - * </itemizedlist> - */ - -static MetadataParsingReturn -metadataparse_jpeg_jump (JpegParseData * jpeg_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size) -{ - jpeg_data->state = JPEG_PARSE_READING; - return metadataparse_util_jump_chunk (&jpeg_data->read, buf, - bufsize, next_start, next_size); -} diff --git a/ext/metadata/metadataparsejpeg.h b/ext/metadata/metadataparsejpeg.h deleted file mode 100644 index 5f85d8f89..000000000 --- a/ext/metadata/metadataparsejpeg.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __METADATAPARSE_JPEG_H__ -#define __METADATAPARSE_JPEG_H__ - -/* - * includes - */ - -#include <gst/base/gstadapter.h> - -#include "metadatatypes.h" - -G_BEGIN_DECLS - -/* - * enum and types - */ - -typedef enum _tag_JpegParseState -{ - JPEG_PARSE_NULL, - JPEG_PARSE_READING, - JPEG_PARSE_JUMPING, - JPEG_PARSE_EXIF, - JPEG_PARSE_IPTC, - JPEG_PARSE_XMP, - JPEG_PARSE_DONE -} JpegParseState; - - -typedef struct _tag_JpegParseData -{ - JpegParseState state; - - GstAdapter ** exif_adapter; - GstAdapter ** iptc_adapter; - GstAdapter ** xmp_adapter; - - MetadataChunkArray * strip_chunks; - MetadataChunkArray * inject_chunks; - - gboolean parse_only; - - guint32 read; - gboolean jfif_found; -} JpegParseData; - -/* - * external function prototypes - */ - -extern void -metadataparse_jpeg_init (JpegParseData * jpeg_data, GstAdapter ** exif_adpt, - GstAdapter ** iptc_adpt, GstAdapter ** xmp_adpt, - MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks, - gboolean parse_only); - -extern void metadataparse_jpeg_dispose (JpegParseData * jpeg_data); - -extern MetadataParsingReturn -metadataparse_jpeg_parse (JpegParseData * jpeg_data, guint8 * buf, - guint32 * bufsize, const guint32 offset, guint8 ** next_start, - guint32 * next_size); - -extern void metadataparse_jpeg_lazy_update (JpegParseData * jpeg_data); - -G_END_DECLS -#endif /* __METADATAPARSE_JPEG_H__ */ diff --git a/ext/metadata/metadataparsepng.c b/ext/metadata/metadataparsepng.c deleted file mode 100644 index ece079793..000000000 --- a/ext/metadata/metadataparsepng.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * SECTION: metadataparsepng - * @short_description: This module provides functions to parse PNG files - * - * This module parses a PNG stream finding XMP metadata chunks, and marking - * them to be removed from the stream and saving the XMP chunk in a adapter. - * - * <refsect2> - * <para> - * #metadataparse_png_init must be called before any other function in this - * module and must be paired with a call to #metadataparse_png_dispose. - * #metadataparse_png_parse is used to parse the stream (find the metadata - * chunks and the place it should be written to. - * #metadataparse_png_lazy_update do nothing. - * </para> - * </refsect2> - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "metadataparsepng.h" -#include "metadataparseutil.h" - -#include <string.h> - -GST_DEBUG_CATEGORY_EXTERN (gst_metadata_demux_debug); -#define GST_CAT_DEFAULT gst_metadata_demux_debug - -/* - * defines and macros - */ - -/* returns the current byte, advance to the next one and decrease the size */ -#define READ(buf, size) ( (size)--, *((buf)++) ) - -/* - * static helper functions declaration - */ - -static MetadataParsingReturn -metadataparse_png_reading (PngParseData * png_data, guint8 ** buf, - guint32 * bufsize, const guint32 offset, const guint8 * step_buf, - guint8 ** next_start, guint32 * next_size); - -static MetadataParsingReturn -metadataparse_png_xmp (PngParseData * png_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size); - -static MetadataParsingReturn -metadataparse_png_jump (PngParseData * png_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size); - -/* - * extern functions implementations - */ - -/* - * metadataparse_png_init: - * @png_data: [in] png data handler to be inited - * @exif_adpt: ignored - * @iptc_adpt: ignored - * @xmp_adpt: where to create/write an adapter to hold the XMP chunk found - * @strip_chunks: Array of chunks (offset and size) marked for removal - * @inject_chunks: Array of chunks (offset, data, size) marked for injection - * @parse_only: TRUE if it should only find the chunks and write then to the - * adapter (@xmp_adpt). Or FALSE if should also put - * them on @strip_chunks. - * - * Init png data handle. - * This function must be called before any other function from this module. - * This function must not be called twice without call to - * #metadataparse_png_dispose beteween them. - * @see_also: #metadataparse_png_dispose #metadataparse_png_parse - * - * Returns: nothing - */ - -void -metadataparse_png_init (PngParseData * png_data, GstAdapter ** exif_adpt, - GstAdapter ** iptc_adpt, GstAdapter ** xmp_adpt, - MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks, - gboolean parse_only) -{ - png_data->state = PNG_PARSE_NULL; - png_data->xmp_adapter = xmp_adpt; - png_data->read = 0; - - png_data->strip_chunks = strip_chunks; - - png_data->parse_only = parse_only; - -} - -/* - * metadataparse_png_dispose: - * @png_data: [in] png data handler to be freed - * - * Call this function to free any resource allocated by - * #metadataparse_png_init - * @see_also: #metadataparse_png_init - * - * Returns: nothing - */ - -void -metadataparse_png_dispose (PngParseData * png_data) -{ - png_data->xmp_adapter = NULL; -} - -/* - * metadataparse_png_parse: - * @png_data: [in] png data handle - * @buf: [in] data to be parsed - * @bufsize: [in] size of @buf in bytes - * @offset: is the offset where @buf starts from the beginnig of the whole - * stream. - * @next_start: is a pointer after @buf which indicates where @buf should start - * on the next call to this function. It means, that after returning, this - * function has consumed *@next_start - @buf bytes. Which also means - * that @offset should also be incremanted by (*@next_start - @buf) for the - * next time. - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * This function is used to parse a PNG stream step-by-step incrementally. - * Basically this function works like a state machine, that will run in a loop - * while there is still bytes in @buf to be read or it has finished parsing. - * If the it hasn't parsed yet and there is no more data in @buf, then the - * current state is saved and a indication will be make about the buffer to - * be passed by the caller function. - * @see_also: #metadataparse_png_init - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if parse has finished. Now strip and - * inject chunks has been found - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -MetadataParsingReturn -metadataparse_png_parse (PngParseData * png_data, guint8 * buf, - guint32 * bufsize, const guint32 offset, guint8 ** next_start, - guint32 * next_size) -{ - - int ret = META_PARSING_DONE; - guint8 mark[8]; - const guint8 *step_buf = buf; - - /* step_buf holds where buf starts. this const value will be passed to - the nested parsing function, so those function knows how far they from - the initial buffer. This is not related to the beginning of the whole - stream, it is just related to the buf passed in this step to this - function */ - - *next_start = buf; - - if (png_data->state == PNG_PARSE_NULL) { - - /* only the first time this function is called it will verify the stream - type to be sure it is a PNG */ - - if (*bufsize < 8) { - *next_size = (buf - *next_start) + 8; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - mark[0] = READ (buf, *bufsize); - mark[1] = READ (buf, *bufsize); - mark[2] = READ (buf, *bufsize); - mark[3] = READ (buf, *bufsize); - mark[4] = READ (buf, *bufsize); - mark[5] = READ (buf, *bufsize); - mark[6] = READ (buf, *bufsize); - mark[7] = READ (buf, *bufsize); - - if (mark[0] != 0x89 || mark[1] != 0x50 || mark[2] != 0x4E || - mark[3] != 0x47 || mark[4] != 0x0D || mark[5] != 0x0A || - mark[6] != 0x1A || mark[7] != 0x0A) { - ret = META_PARSING_ERROR; - goto done; - } - - png_data->state = PNG_PARSE_READING; - - } - - while (ret == META_PARSING_DONE) { - switch (png_data->state) { - case PNG_PARSE_READING: - ret = - metadataparse_png_reading (png_data, &buf, bufsize, - offset, step_buf, next_start, next_size); - break; - case PNG_PARSE_JUMPING: - ret = - metadataparse_png_jump (png_data, &buf, bufsize, next_start, - next_size); - break; - case PNG_PARSE_XMP: - ret = - metadataparse_png_xmp (png_data, &buf, bufsize, next_start, - next_size); - break; - case PNG_PARSE_DONE: - goto done; - break; - default: - ret = META_PARSING_ERROR; - break; - } - } - -done: - - return ret; - -} - -/* - * metadataparse_png_lazy_update: - * @png_data: [in] png data handle - * - * This function do nothing - * @see_also: #metadata_lazy_update - * - * Returns: nothing - */ - -void -metadataparse_png_lazy_update (PngParseData * png_data) -{ - /* nothing to do */ -} - -/* - * static helper functions implementation - */ - -/* - * metadataparse_png_reading: - * @png_data: [in] png data handle - * @buf: [in] data to be parsed. @buf will increment during the parsing step. - * So it will hold the next byte to be read inside a parsing function or on - * the next nested parsing function. And so, @bufsize will decrement. - * @bufsize: [in] size of @buf in bytes. This value will decrement during the - * parsing for the same reason that @buf will advance. - * @offset: is the offset where @step_buf starts from the beginnig of the - * stream - * @step_buf: holds the pointer to the buffer passed to - * #metadataparse_png_parse. It means that any point inside this function - * the offset (related to the beginning of the whole stream) after the last - * byte read so far is "(*buf - step_buf) + offset" - * @next_start: is a pointer after @step_buf which indicates where the next - * call to #metadataparse_png_parse should start on the next call to this - * function. It means, that after return, this function has - * consumed *@next_start - @buf bytes. Which also means that @offset should - * also be incremanted by (*@next_start - @buf) for the next time. - * @next_size: [out] number of minimal bytes in @buf for the next call to this - * function - * - * This function is used to parse a PNG stream step-by-step incrementally. - * If this function finds a XMP chunk (or a chunk that should be - * jumped), then it changes the state of the parsing process so that the - * remaing parsing can be done by another more specialized function. - * @see_also: #metadataparse_png_init #metadataparse_png_xmp - * #metadataparse_png_jump - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if parse has finished. Now strip and - * inject chunks has been found. Or some chunk has been found and should be - * held or jumped. - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -/* look for markers */ -static MetadataParsingReturn -metadataparse_png_reading (PngParseData * png_data, guint8 ** buf, - guint32 * bufsize, const guint32 offset, const guint8 * step_buf, - guint8 ** next_start, guint32 * next_size) -{ - - int ret = META_PARSING_ERROR; - guint8 mark[4]; - guint32 chunk_size = 0; - - static const char XmpHeader[] = "XML:com.adobe.xmp"; - - *next_start = *buf; - - if (*bufsize < 8) { - *next_size = (*buf - *next_start) + 8; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - chunk_size = READ (*buf, *bufsize) << 24; - chunk_size += READ (*buf, *bufsize) << 16; - chunk_size += READ (*buf, *bufsize) << 8; - chunk_size += READ (*buf, *bufsize); - - mark[0] = READ (*buf, *bufsize); - mark[1] = READ (*buf, *bufsize); - mark[2] = READ (*buf, *bufsize); - mark[3] = READ (*buf, *bufsize); - - /* FIXME: use FOURCECC macros */ - - GST_DEBUG ("parsing png : 0x%02x%02x%02x%02x", - mark[0], mark[1], mark[2], mark[3]); - - if (mark[0] == 'I' && mark[1] == 'E' && mark[2] == 'N' && mark[3] == 'D') { - ret = META_PARSING_DONE; - png_data->state = PNG_PARSE_DONE; - goto done; - } - - if (mark[0] == 'i' && mark[1] == 'T' && mark[2] == 'X' && mark[3] == 't') { - if (chunk_size >= 22) { /* "XML:com.adobe.xmp" plus some flags */ - if (*bufsize < 22) { - *next_size = (*buf - *next_start) + 22; - ret = META_PARSING_NEED_MORE_DATA; - goto done; - } - - if (0 == memcmp (XmpHeader, *buf, 18)) { - - if (!png_data->parse_only) { - MetadataChunk chunk; - - memset (&chunk, 0x00, sizeof (MetadataChunk)); - chunk.offset_orig = (*buf - step_buf) + offset - 8; /* maker + size */ - chunk.size = chunk_size + 12; /* chunk size + app marker + crc */ - chunk.type = MD_CHUNK_XMP; - - metadata_chunk_array_append_sorted (png_data->strip_chunks, &chunk); - } - - /* if adapter has been provided, prepare to hold chunk */ - if (png_data->xmp_adapter) { - *buf += 22; /* jump "XML:com.adobe.xmp" + some flags */ - *bufsize -= 22; - /* four CRC bytes at the end will be jumped after */ - png_data->read = chunk_size - 22; - png_data->state = PNG_PARSE_XMP; - ret = META_PARSING_DONE; - goto done; - } - } - } - } - - /* just set jump sise */ - png_data->read = chunk_size + 4; /* four CRC bytes at the end */ - png_data->state = PNG_PARSE_JUMPING; - ret = META_PARSING_DONE; - -done: - - return ret; - - -} - -/* - * metadataparse_png_xmp: - * @png_data: [in] png data handle - * @buf: [in] data to be parsed - * @bufsize: [in] size of @buf in bytes - * @next_start: look at #metadataparse_png_reading - * @next_size: look at #metadataparse_png_reading - * NOTE: To have a explanation of each parameters of this function look at - * the documentation of #metadataparse_png_reading - * - * This function saves the XMP chunk to @png_data->xmp_adapter and makes the - * parsing process point to the next buffer after the XMP chunk. - * This function will be called by the parsing process 'cause at some point - * #metadataparse_png_reading found out the XMP chunk, skipped the PNG - * wrapper bytes and changed the state of parsing process to PNG_PARSE_XMP. - * Which just happens if @png_data->parse_only is FALSE and there is a XMP - * chunk into the stream and @png_data->xmp_adapter is not NULL. - * This function will just be called once even if there is more than one XMP - * chunk in the stream. This function do it by setting @png_data->xmp_adapter - * to NULL. - * After this function has completely parsed (hold) the chunk, it changes the - * parsing state to PNG_PARSE_JUMP which makes - * #metadataparse_png_jump to be called in order to jumo the remaing 4 CRC - * bytes - * @see_also: #metadataparse_util_hold_chunk #metadataparse_png_reading - * #metadataparse_png_jump - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if the chunk bas been completely hold - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -static MetadataParsingReturn -metadataparse_png_xmp (PngParseData * png_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size) -{ - int ret; - - ret = metadataparse_util_hold_chunk (&png_data->read, buf, - bufsize, next_start, next_size, png_data->xmp_adapter); - if (ret == META_PARSING_DONE) { - /* jump four CRC bytes at the end of chunk */ - png_data->read = 4; - png_data->state = PNG_PARSE_JUMPING; - /* if there is a second XMP chunk in the file it will be jumped */ - png_data->xmp_adapter = NULL; - } - return ret; - -} - -/* - * metadataparse_png_jump: - * @png_data: [in] png data handle - * @buf: [in] data to be parsed - * @bufsize: [in] size of @buf in bytes - * @next_start: look at #metadataparse_png_reading - * @next_size: look at #metadataparse_png_reading - * NOTE: To have a explanation of each parameters of this function look at - * the documentation of #metadataparse_png_reading - * - * This function just makes a chunk we are not interested in to be jumped. - * This is done basically by incrementing @next_start and @buf, - * and decreasing @bufsize and setting the next parsing state properly. - * @see_also: #metadataparse_png_reading #metadataparse_util_jump_chunk - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_DONE if bytes has been skiped and there is - * still data in @buf - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if the skiped bytes end at - * some point after @buf + @bufsize - * </para></listitem> - * </itemizedlist> - */ - -static MetadataParsingReturn -metadataparse_png_jump (PngParseData * png_data, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size) -{ - png_data->state = PNG_PARSE_READING; - return metadataparse_util_jump_chunk (&png_data->read, buf, - bufsize, next_start, next_size); -} diff --git a/ext/metadata/metadataparsepng.h b/ext/metadata/metadataparsepng.h deleted file mode 100644 index 8e2b1d628..000000000 --- a/ext/metadata/metadataparsepng.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __METADATAPARSE_PNG_H__ -#define __METADATAPARSE_PNG_H__ - -/* - * includes - */ - -#include <gst/base/gstadapter.h> - -#include "metadatatypes.h" - -G_BEGIN_DECLS - -/* - * enum and types - */ - -typedef enum _tag_PngParseState -{ - PNG_PARSE_NULL, - PNG_PARSE_READING, - PNG_PARSE_JUMPING, - PNG_PARSE_XMP, - PNG_PARSE_DONE -} PngParseState; - - -typedef struct _tag_PngParseData -{ - PngParseState state; - - GstAdapter ** xmp_adapter; - - MetadataChunkArray * strip_chunks; - - gboolean parse_only; - - guint32 read; -} PngParseData; - -/* - * external function prototypes - */ - -extern void -metadataparse_png_init (PngParseData * png_data, GstAdapter ** exif_adpt, - GstAdapter ** iptc_adpt, GstAdapter ** xmp_adpt, - MetadataChunkArray * strip_chunks, MetadataChunkArray * inject_chunks, - gboolean parse_only); - -extern void metadataparse_png_dispose (PngParseData * png_data); - -extern void metadataparse_png_lazy_update (PngParseData * png_data); - -extern MetadataParsingReturn -metadataparse_png_parse (PngParseData * png_data, guint8 * buf, - guint32 * bufsize, const guint32 offset, guint8 ** next_start, - guint32 * next_size); - -G_END_DECLS -#endif /* __METADATAPARSE_PNG_H__ */ diff --git a/ext/metadata/metadataparseutil.c b/ext/metadata/metadataparseutil.c deleted file mode 100644 index c12bff5c7..000000000 --- a/ext/metadata/metadataparseutil.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * SECTION: metadataparseutil - * @short_description: This module has some util function for parsing. - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "metadataparseutil.h" -#include <string.h> - -GST_DEBUG_CATEGORY_EXTERN (gst_metadata_demux_debug); -#define GST_CAT_DEFAULT gst_metadata_demux_debug - -/* - * extern functions implementations - */ - -/* - * metadataparse_util_tag_list_add_chunk: - * @taglist: tag list in which the whole chunk tag will be added - * @mode: GStreamer merge mode - * @name: name of the tag (ex: GST_TAG_EXIF, GST_TAG_IPTC, GST_TAG_XMP) - * @adapter: contains the whole chunk to be added as tag to @taglist - * - * This function get all the bytes from @adapter, create a GST_BUFFER, copy - * the bytes to it and then add it to @taglist as a tage @name using a - * merge @mode. - * - * Returns: nothing. - */ - -void -metadataparse_util_tag_list_add_chunk (GstTagList * taglist, - GstTagMergeMode mode, const gchar * name, GstAdapter * adapter) -{ - GstBuffer *buf; - guint size; - - if (adapter && (size = gst_adapter_available (adapter))) { - - buf = gst_buffer_new_and_alloc (size); - - gst_adapter_copy (adapter, GST_BUFFER_DATA (buf), 0, size); - - gst_tag_list_add (taglist, mode, name, buf, NULL); - - gst_buffer_unref (buf); - } - -} - -/* - * metadataparse_util_hold_chunk: - * @read: number of bytes that still need to be hold - * @buf: [in] data to be parsed - * @bufsize: [in] size of @buf in bytes - * @next_start: indicates a pointer after the @buf where the next parsing step - * should start from - * @next_size: indicates the minimal size of the the buffer to be given on - * the next call to the parser - * @adapter: adapter to hold the chunk - * NOTE: To have a explanation of each parameters of this function look at the - * documentation of #metadataparse_jpeg_reading or #metadataparse_png_reading - * - * This function holds a chunk into the adapter. If there is enough bytes - * (*@read > *@bufsize), then it just hold and make the parser continue after - * the chunk by setting @next_start properly. Otherwise, if there is not - * enough bytes in @buf, it just set @next_start and @next_size, to make the - * parse return META_PARSING_NEED_MORE_DATA and request the caller the proper - * offset and size, so in the sencond time this function is called it should - * (or must) have enough data hold the whole chunk. - * - * Returns: - * <itemizedlist> - * <listitem><para>%META_PARSING_ERROR - * </para></listitem> - * <listitem><para>%META_PARSING_DONE if the chunk bas been completely hold - * </para></listitem> - * <listitem><para>%META_PARSING_NEED_MORE_DATA if this function should be - * called again (look @next_start and @next_size) - * </para></listitem> - * </itemizedlist> - */ - -MetadataParsingReturn -metadataparse_util_hold_chunk (guint32 * read, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, - guint32 * next_size, GstAdapter ** adapter) -{ - int ret; - - if (*read > *bufsize) { - *next_start = *buf; - *next_size = *read; - ret = META_PARSING_NEED_MORE_DATA; - } else { - GstBuffer *gst_buf; - - if (NULL == *adapter) { - *adapter = gst_adapter_new (); - } - gst_buf = gst_buffer_new_and_alloc (*read); - memcpy (GST_BUFFER_DATA (gst_buf), *buf, *read); - gst_adapter_push (*adapter, gst_buf); - - *next_start = *buf + *read; - *buf += *read; - *bufsize -= *read; - *read = 0; - ret = META_PARSING_DONE; - } - - return ret; -} - -/* - * metadataparse_util_jump_chunk: - * NOTE: To have a explanation of each parameters of this function look at - * the documentation of #metadataparse_util_hold_chunk - * - * This function works in the same way as #metadataparse_util_hold_chunk, but - * just skip the bytes instead of also hold it - * - */ - -MetadataParsingReturn -metadataparse_util_jump_chunk (guint32 * read, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size) -{ - int ret; - - if (*read > *bufsize) { - *read -= *bufsize; - *next_size = 2; - *next_start = *buf + *bufsize + *read; - *read = 0; - *bufsize = 0; - ret = META_PARSING_NEED_MORE_DATA; - } else { - *next_start = *buf + *read; - *buf += *read; - *bufsize -= *read; - *read = 0; - ret = META_PARSING_DONE; - } - return ret; -} diff --git a/ext/metadata/metadataparseutil.h b/ext/metadata/metadataparseutil.h deleted file mode 100644 index e24341bdc..000000000 --- a/ext/metadata/metadataparseutil.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_METADATAPARSE_UTIL_H__ -#define __GST_METADATAPARSE_UTIL_H__ - -/* - * includes - */ - -#include <gst/gst.h> -#include <gst/base/gstadapter.h> - -#include "metadatatypes.h" - -G_BEGIN_DECLS - -/* - * external function prototypes - */ - -extern void -metadataparse_util_tag_list_add_chunk (GstTagList * taglist, - GstTagMergeMode mode, const gchar * name, GstAdapter * adapter); - -extern MetadataParsingReturn -metadataparse_util_hold_chunk (guint32 * read, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size, - GstAdapter ** adapter); - -extern MetadataParsingReturn -metadataparse_util_jump_chunk (guint32 * read, guint8 ** buf, - guint32 * bufsize, guint8 ** next_start, guint32 * next_size); - -G_END_DECLS -#endif /* __GST_METADATAPARSE_UTIL_H__ */ diff --git a/ext/metadata/metadatatags.c b/ext/metadata/metadatatags.c deleted file mode 100644 index a634025fd..000000000 --- a/ext/metadata/metadatatags.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * SECTION: metadatatags - * @short_description: This module contains has tag definitions to be mapped - * to EXIF, IPTC and XMP tags. - * - * This module register tags need for image metadata but aren't already define - * in GStreamer base. So, the EXIF, IPTC and XMP tags can be mapped to tags - * not registered in this file (tags already in GST base) - * - * When changing this file, update 'metadata_mapping.htm' file too. - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "metadatatags.h" - -/* - * static helper functions declaration - */ - -static void metadata_tags_exif_register (void); - -static void metadata_tags_iptc_register (void); - -static void metadata_tags_xmp_register (void); - -/* - * extern functions implementations - */ - -void -metadata_tags_register (void) -{ - - /* whole chunk tags */ - - gst_tag_register (GST_TAG_EXIF, GST_TAG_FLAG_META, - GST_TYPE_BUFFER, GST_TAG_EXIF, "exif metadata chunk", NULL); - - gst_tag_register (GST_TAG_IPTC, GST_TAG_FLAG_META, - GST_TYPE_BUFFER, GST_TAG_IPTC, "iptc metadata chunk", NULL); - - gst_tag_register (GST_TAG_XMP, GST_TAG_FLAG_META, - GST_TYPE_BUFFER, GST_TAG_XMP, "xmp metadata chunk", NULL); - - /* tags related to some metadata */ - - metadata_tags_exif_register (); - metadata_tags_iptc_register (); - metadata_tags_xmp_register (); - -} - - -/* - * static helper functions implementation - */ - - -/* - * EXIF tags - */ - -static void -metadata_tags_exif_register (void) -{ - - /* capture tags */ - - gst_tag_register (GST_TAG_CAPTURE_APERTURE, GST_TAG_FLAG_META, - GST_TYPE_FRACTION, GST_TAG_CAPTURE_APERTURE, - "Aperture (in APEX units)", NULL); - - /* The unit is the APEX value. - Ordinarily it is given in the range of -99.99 to 99.99. - if numerator is 0xFFFFFFFF means unknown - */ - gst_tag_register (GST_TAG_CAPTURE_BRIGHTNESS, GST_TAG_FLAG_META, - GST_TYPE_FRACTION, GST_TAG_CAPTURE_BRIGHTNESS, - "Brightness (APEX from -99.99 to 99.99)", NULL); - - /* - * 1- sRGB - * 0xFFFF - Uncalibrated - */ - - gst_tag_register (GST_TAG_CAPTURE_COLOR_SPACE, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_CAPTURE_COLOR_SPACE, "Color Space", NULL); - - /* - from -100 to 100 - [-100, -34] - soft - [-33, 33] - normal - [34, 100] - hard - *** exif is just 0, 1, 2 (normal, soft and hard) - */ - gst_tag_register (GST_TAG_CAPTURE_CONTRAST, GST_TAG_FLAG_META, G_TYPE_INT, - GST_TAG_CAPTURE_CONTRAST, "Contrast", NULL); - - /* - * 0- Normal process - * 1- Custom process - */ - - gst_tag_register (GST_TAG_CAPTURE_CUSTOM_RENDERED, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_CAPTURE_CUSTOM_RENDERED, - "Indicates the use of special processing on image data", NULL); - - /* if Zero ZOOM not used - */ - gst_tag_register (GST_TAG_CAPTURE_DIGITAL_ZOOM, GST_TAG_FLAG_META, - GST_TYPE_FRACTION, GST_TAG_CAPTURE_DIGITAL_ZOOM, "Digital zoom ratio", - NULL); - - /* - * 0 - Auto exposure - * 1 - Manual exposure - * 2 - Auto bracket (the camera shoots a series of frames of the same scene - * at different exposure settings) - */ - - gst_tag_register (GST_TAG_CAPTURE_EXPOSURE_MODE, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_CAPTURE_EXPOSURE_MODE, "Exposure Mode", NULL); - - /* - 0 - not defined - 1- Manual - 2- Normal program - 3- Aperture priority - 4- Shutter priority - 5- Creative program (biased toward death of field) - 6- Action program (biased toward fast shutter speed) - 7- Portrait mode (for closeup photos with the background out of focus) - 8- Landscape mode (for landscape photos with the background in focus) - *** exif is until here *** - 9- Night - 10- Back-light - 11- Spotlight - 12- Snow - 13- Beach - */ - gst_tag_register (GST_TAG_CAPTURE_EXPOSURE_PROGRAM, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_CAPTURE_EXPOSURE_PROGRAM, - "Class of program used for exposure", NULL); - - gst_tag_register (GST_TAG_CAPTURE_EXPOSURE_TIME, GST_TAG_FLAG_META, - GST_TYPE_FRACTION, GST_TAG_CAPTURE_EXPOSURE_TIME, - "Exposure time in seconds", NULL); - - /* - * bits (76543210) indicating the flash status: - * 0- Flash firing - * 0- Flash did not fire - * 1- Flash fired - * 1,2- Flash return - * 00- No strobe return detection function - * 01- reserved - * 10- Strobe return light not detected - * 11- Strobe return light detected. - * 3,4- Flash mode - * 00- unknown - * 01- Compulsory flash firing - * 10- Compulsory flash suppression - * 11- Auto mode - * 5- if flash function is present - * 0- Flash function present - * 1- No flash function - * 6- Red-eye mode - * 0- No red-eye reduction mode or unknown - * 1- Red-eye reduction supported - * So, we have the following possible values: - * - * 0000.H = Flash did not fire. - * 0001.H = Flash fired. - * 0005.H = Strobe return light not detected. - * 0007.H = Strobe return light detected. - * 0009.H = Flash fired, compulsory flash mode - * 000D.H = Flash fired, compulsory flash mode, return light not detected - * 000F.H = Flash fired, compulsory flash mode, return light detected - * 0010.H = Flash did not fire, compulsory flash mode - * 0018.H = Flash did not fire, auto mode - * 0019.H = Flash fired, auto mode - * 001D.H = Flash fired, auto mode, return light not detected - * 001F.H = Flash fired, auto mode, return light detected - * 0020.H = No flash function - * 0041.H = Flash fired, red-eye reduction mode - * 0045.H = Flash fired, red-eye reduction mode, return light not detected - * 0047.H = Flash fired, red-eye reduction mode, return light detected - * 0049.H = Flash fired, compulsory flash mode, red-eye reduction mode - * 004D.H = Flash fired, compulsory flash mode, red-eye reduction mode, - * return light not detected - * 004F.H = Flash fired, compulsory flash mode, red-eye reduction mode, - * return light detected - * 0059.H = Flash fired, auto mode, red-eye reduction mode - * 005D.H = Flash fired, auto mode, return light not detected, - * red-eye reduction mode - * 005F.H = Flash fired, auto mode, return light detected, - * red-eye reduction mode - * Other = reserved - */ - - - gst_tag_register (GST_TAG_CAPTURE_FLASH, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_CAPTURE_FLASH, "Flash status", NULL); - - gst_tag_register (GST_TAG_CAPTURE_FNUMBER, GST_TAG_FLAG_META, - GST_TYPE_FRACTION, GST_TAG_CAPTURE_FNUMBER, "F number (focal ratio)", - NULL); - - gst_tag_register (GST_TAG_CAPTURE_FOCAL_LEN, GST_TAG_FLAG_META, - GST_TYPE_FRACTION, GST_TAG_CAPTURE_FOCAL_LEN, - "Focal length of lens used to take image. Unit is millimeter", NULL); - - /* - 0- None - 1- Low gain up - 2- High gain up - 3- Low gain down - 4- High gain down - */ - gst_tag_register (GST_TAG_CAPTURE_GAIN, GST_TAG_FLAG_META, G_TYPE_UINT, - GST_TAG_CAPTURE_GAIN, "", NULL); - - gst_tag_register (GST_TAG_CAPTURE_ISO_SPEED_RATINGS, GST_TAG_FLAG_META, - G_TYPE_INT, GST_TAG_CAPTURE_ISO_SPEED_RATINGS, - "ISO Speed and ISO Latitude as specified in ISO 12232", NULL); - - - /* - 0- unknown (default) - 1- Daylight - 2- Fluorescent - 3- Tungsten (incandescent light) - 4- Flash - 9- Fine weather - 10- Cloudy weather - 11- Shade - 12- Daylight fluorescent (D 5700 %G–%@ 7100K) - 13- Day white fluorescent (N 4600 %G–%@ 5400K) - 14- Cool white fluorescent (W 3900 %G–%@ 4500K) - 15- White fluorescent (WW 3200 %G–%@ 3700K) - 17- Standard light A - 18- Standard light B - 19- Standard light C - 20- D55 - 21- D65 - 22- D75 - 23- D50 - 24- ISO studio tungsten - 255- other light source - Other = reserved - */ - - gst_tag_register (GST_TAG_CAPTURE_LIGHT_SOURCE, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_CAPTURE_LIGHT_SOURCE, - "The kind of light source.", NULL); - - /* - * The relation of the '0th row' and '0th column' to visual position: - * 1- top-left - * 2- top-right - * 3- bottom-right - * 4- bottom-left - * 5- left-top - * 6- right-top - * 7- right-bottom - * 8- left-bottom - */ - - gst_tag_register (GST_TAG_CAPTURE_ORIENTATION, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_CAPTURE_ORIENTATION, - "The orientation of the camera.", NULL); - - /* - from -100 to 100 - [-100, -34] - low - [-33, 33] - normal - [34, 100] - high - *** exif is just 0, 1, 2 (normal, low and high) - */ - gst_tag_register (GST_TAG_CAPTURE_SATURATION, GST_TAG_FLAG_META, G_TYPE_INT, - GST_TAG_CAPTURE_SATURATION, "The saturation", NULL); - - /* - * 0 - Standard - * 1 - Landscape - * 2 - Portrait - * 3 - Night scene - */ - gst_tag_register (GST_TAG_CAPTURE_SCENE_CAPTURE_TYPE, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_CAPTURE_SCENE_CAPTURE_TYPE, "Scene Type", NULL); - - gst_tag_register (GST_TAG_CAPTURE_SHUTTER_SPEED, GST_TAG_FLAG_META, - GST_TYPE_FRACTION, GST_TAG_CAPTURE_SHUTTER_SPEED, "Shutter speed (APEX)", - NULL); - - /* - 0- Auto - 1- Off - *** exif is until here *** - 2- Sunlight - 3- Cloudy - 4- Shade - 5- Tungsten - 6- Fluorescent - 7- Incandescent - 8- Flash - 9- Horizon (sun on the horizon) - */ - gst_tag_register (GST_TAG_CAPTURE_WHITE_BALANCE, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_CAPTURE_WHITE_BALANCE, "White balance mode", NULL); - - /* generic tags */ - - gst_tag_register (GST_TAG_CREATOR_TOOL, GST_TAG_FLAG_META, G_TYPE_STRING, - GST_TAG_CREATOR_TOOL, - "The name of the first known tool used to create the resource." - " Or firmware or driver version of device", NULL); - - /* date and time tags */ - /* formated as subset of ISO RFC 8601 as described in - * http://www.w3.org/TR/1998/NOTE-datetime-19980827 - * which is: - * YYYY - * YYYY-MM - * YYYY-MM-DD - * YYYY-MM-DDThh:mmTZD - * YYYY-MM-DDThh:mm:ssTZD - * YYYY-MM-DDThh:mm:ss.sTZD - * where: - * YYYY = four-digit year - * MM = two-digit month (01=January) - * DD = two-digit day of month (01 through 31) - * hh = two digits of hour (00 through 23) - * mm = two digits of minute (00 through 59) - * ss = two digits of second (00 through 59) - * s = one or more digits representing a decimal fraction of a second - * TZD = time zone designator (Z or +hh:mm or -hh:mm) - */ - - gst_tag_register (GST_TAG_DATE_TIME_DIGITIZED, GST_TAG_FLAG_META, - G_TYPE_STRING, GST_TAG_DATE_TIME_DIGITIZED, - "Date/Time of image digitized", NULL); - - gst_tag_register (GST_TAG_DATE_TIME_MODIFIED, GST_TAG_FLAG_META, - G_TYPE_STRING, GST_TAG_DATE_TIME_MODIFIED, - "Date/Time of image was last modified", NULL); - - gst_tag_register (GST_TAG_DATE_TIME_ORIGINAL, GST_TAG_FLAG_META, - G_TYPE_STRING, GST_TAG_DATE_TIME_ORIGINAL, - "Date/Time of original image taken", NULL); - - /* devices tags */ - - gst_tag_register (GST_TAG_DEVICE_MAKE, GST_TAG_FLAG_META, - G_TYPE_STRING, GST_TAG_DEVICE_MAKE, - "The manufacturer of the recording equipment", NULL); - - gst_tag_register (GST_TAG_DEVICE_MODEL, GST_TAG_FLAG_META, G_TYPE_STRING, - GST_TAG_DEVICE_MODEL, "The model name or model number of the equipment", - NULL); - - /* exif specific tags */ - - gst_tag_register (GST_TAG_EXIF_MAKER_NOTE, GST_TAG_FLAG_META, - GST_TYPE_BUFFER, GST_TAG_EXIF_MAKER_NOTE, "Camera private data", NULL); - - /* image tags */ - - gst_tag_register (GST_TAG_IMAGE_HEIGHT, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_IMAGE_HEIGHT, "Image height in pixels", NULL); - - gst_tag_register (GST_TAG_IMAGE_WIDTH, GST_TAG_FLAG_META, - G_TYPE_UINT, GST_TAG_IMAGE_WIDTH, "Image width in pixels", NULL); - - gst_tag_register (GST_TAG_IMAGE_XRESOLUTION, GST_TAG_FLAG_META, - GST_TYPE_FRACTION, GST_TAG_IMAGE_XRESOLUTION, - "Horizontal resolution in pixels per inch", NULL); - - gst_tag_register (GST_TAG_IMAGE_YRESOLUTION, GST_TAG_FLAG_META, - GST_TYPE_FRACTION, GST_TAG_IMAGE_YRESOLUTION, - "Vertical resolution in pixels per inch", NULL); -} - -/* - * IPTC tags - */ - -static void -metadata_tags_iptc_register (void) -{ - -} - -/* - * XMP tags - */ - -static void -metadata_tags_xmp_register (void) -{ - -} diff --git a/ext/metadata/metadatatags.h b/ext/metadata/metadatatags.h deleted file mode 100644 index 8500f15aa..000000000 --- a/ext/metadata/metadatatags.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_METADATA_TAGS_H__ -#define __GST_METADATA_TAGS_H__ - -/* - * includes - */ - -#include <gst/gst.h> -#include <gst/base/gstadapter.h> - -G_BEGIN_DECLS - -/* - * enum and types - */ - -/* set bit to desired mapping */ -typedef enum { - METADATA_TAG_MAP_INDIVIDUALS = 1 << 0, - METADATA_TAG_MAP_WHOLECHUNK = 1 << 1 -} MetadataTagMapping; - -/* - * defines - */ - -/* *INDENT-OFF* */ - -/* whole chunk tags */ - -#define GST_TAG_EXIF "exif" - -#define GST_TAG_IPTC "iptc" - -#define GST_TAG_XMP "xmp" - -/* individual tags */ - -#define GST_TAG_CAPTURE_APERTURE "capture-aperture" -#define GST_TAG_CAPTURE_BRIGHTNESS "capture-brightness" -#define GST_TAG_CAPTURE_COLOR_SPACE "capture-color-space" -#define GST_TAG_CAPTURE_CONTRAST "capture-contrast" -#define GST_TAG_CAPTURE_CUSTOM_RENDERED "capture-custom-rendered" -#define GST_TAG_CAPTURE_DIGITAL_ZOOM "capture-digital-zoom" -#define GST_TAG_CAPTURE_EXPOSURE_MODE "capture-exposure-mode" -#define GST_TAG_CAPTURE_EXPOSURE_PROGRAM "capture-exposure-program" -#define GST_TAG_CAPTURE_EXPOSURE_TIME "capture-exposure-time" -#define GST_TAG_CAPTURE_FLASH "capture-flash" -#define GST_TAG_CAPTURE_FNUMBER "capture-fnumber" -#define GST_TAG_CAPTURE_FOCAL_LEN "capture-focal-len" -#define GST_TAG_CAPTURE_GAIN "capture-gain" -#define GST_TAG_CAPTURE_ISO_SPEED_RATINGS "capture-iso-speed-ratings" -#define GST_TAG_CAPTURE_LIGHT_SOURCE "capture-light-source" -#define GST_TAG_CAPTURE_ORIENTATION "capture-orientation" -#define GST_TAG_CAPTURE_SATURATION "capture-saturation" -#define GST_TAG_CAPTURE_SCENE_CAPTURE_TYPE "capture-scene-capture-type" -#define GST_TAG_CAPTURE_SHUTTER_SPEED "capture-shutter-speed" -#define GST_TAG_CAPTURE_WHITE_BALANCE "capture-white-balance" - -#define GST_TAG_CREATOR_TOOL "creator-tool" - -#define GST_TAG_DATE_TIME_DIGITIZED "date-time-digitized" -#define GST_TAG_DATE_TIME_MODIFIED "date-time-modified" -#define GST_TAG_DATE_TIME_ORIGINAL "date-time-original" - -#define GST_TAG_DEVICE_MAKE "device-make" -#define GST_TAG_DEVICE_MODEL "device-model" - -#define GST_TAG_EXIF_MAKER_NOTE "exif-maker-note" - -#define GST_TAG_IMAGE_HEIGHT "image-height" -#define GST_TAG_IMAGE_WIDTH "image-width" -#define GST_TAG_IMAGE_XRESOLUTION "image-xresolution" -#define GST_TAG_IMAGE_YRESOLUTION "image-yresolution" - -#define GST_TAG_GPS_AREA_INFORMATION "" -#define GST_TAG_GPS_DIFFERENTIAL "" -#define GST_TAG_GPS_DOP "" -#define GST_TAG_GPS_IMAGE_DIRECTION "" -#define GST_TAG_GPS_MEASURE_MODE "" -#define GST_TAG_GPS_PROCESSING_METHOD "" -#define GST_TAG_GPS_SATELLITES "" -#define GST_TAG_GPS_SPEED "" -#define GST_TAG_GPS_TRACK "" - -/* *INDENT-ON* */ - -/* - * external function prototypes - */ - -extern void -metadata_tags_register (void); - -G_END_DECLS -#endif /* __GST_METADATA_TAGS_H__ */ diff --git a/ext/metadata/metadatatypes.c b/ext/metadata/metadatatypes.c deleted file mode 100644 index f2fcb7027..000000000 --- a/ext/metadata/metadatatypes.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * SECTION: metadatatypes - * @short_description: This module contains function to operates a list of - * chunks - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "metadatatypes.h" - -#include <string.h> - -/* - * extern functions implementations - */ - -/* - * metadata_chunk_array_init: - * @array: an array of chunks - * @alloc_size: number of chunks that can be added to the array without futher - * allocation - * - * Call this function before any other function in this module. - * Nerver call this function a second time without call - * #metadata_chunk_array_free beteween them - * An example of use is: - * int test() { MetadataChunkArray a; metadata_chunk_array_init(&a, 1); ... } - * - * Returns: nothing - */ - -void -metadata_chunk_array_init (MetadataChunkArray * array, gsize alloc_size) -{ - array->len = 0; - array->chunk = g_new0 (MetadataChunk, alloc_size); - array->allocated_len = alloc_size; -} - -/* - * metadata_chunk_array_free: - * @array: an array of chunks - * - * Call this function after have finished using the @array to free any internal - * memory alocated by it. - * - * Returns: nothing - */ - -void -metadata_chunk_array_free (MetadataChunkArray * array) -{ - metadata_chunk_array_clear (array); - array->allocated_len = 0; - g_free (array->chunk); - array->chunk = NULL; -} - -/* - * metadata_chunk_array_clear: - * @array: an array of chunks - * - * Free memory allocated internally by each chunk and set the @array->len to 0 - * (zero). So, the number of chunks into the array will be zero, - * but the number of slots into the array to strore chunks will be kept - * - * Returns: nothing - */ - -void -metadata_chunk_array_clear (MetadataChunkArray * array) -{ - while (array->len) { - array->len--; - g_free (array->chunk[array->len].data); - } -} - -/* - * metadata_chunk_array_append: - * @array: an array of chunks - * @chunk: chunk to be append - * - * Just append a @chunk to the end of the @array. The @array now will be the - * owner of @chunk->data. Just call this function if you a sure the @array - * chunks will be sorted by @chunk->offset_orig anyway. - * @see_also: #metadata_chunk_array_append_sorted - * - * Returns: nothing - */ - -void -metadata_chunk_array_append (MetadataChunkArray * array, MetadataChunk * chunk) -{ - if (array->len == array->allocated_len) { - array->allocated_len += 2; - array->chunk = - g_realloc (array->chunk, sizeof (MetadataChunk) * array->allocated_len); - } - memcpy (&array->chunk[array->len], chunk, sizeof (MetadataChunk)); - ++array->len; -} - -/* - * metadata_chunk_array_append_sorted: - * @array: an array of chunks - * @chunk: chunk to be append - * - * Append a @chunk sorted by @chunk->offset_orig the @array. The @array now - * will be the owner of @chunk->data. This function supposes that @array - * is already sorted by @chunk->offset_orig. - * @see_also: #metadata_chunk_array_append - * - * Returns: nothing - */ - -void -metadata_chunk_array_append_sorted (MetadataChunkArray * array, - MetadataChunk * chunk) -{ - gint32 i, pos; - - if (array->len == array->allocated_len) { - array->allocated_len += 2; - array->chunk = - g_realloc (array->chunk, sizeof (MetadataChunk) * array->allocated_len); - } - pos = array->len; - for (i = array->len - 1; i >= 0; --i) { - if (chunk->offset_orig >= array->chunk[i].offset_orig) { - break; - } - } - pos = i + 1; - if (pos < array->len) { - memmove (&array->chunk[pos + 1], &array->chunk[pos], - sizeof (MetadataChunk) * (array->len - pos)); - } - memcpy (&array->chunk[pos], chunk, sizeof (MetadataChunk)); - ++array->len; - - return; - -} - -/* - * metadata_chunk_array_remove_zero_size: - * @array: an array of chunks - * - * This function removes all the chunks in @array that has 'chunk.size == 0'. - * It is possible to have the 'chunk.data==NULL' and 'chunk.size != 0', those - * chunks are used by muxer for lazy 'filling' and are not removed by this - * function. - * - * Returns: nothing - */ - -void -metadata_chunk_array_remove_zero_size (MetadataChunkArray * array) -{ - - int i; - - for (i = 0; i < array->len;) { - if (array->chunk[i].size == 0) { - if (i < --array->len) { - memmove (&array->chunk[i], &array->chunk[i + 1], - sizeof (MetadataChunk) * (array->len - i)); - } - } else { - ++i; - } - } -} - -/* - * metadata_chunk_array_remove_by_index: - * @array: an array of chunks - * @i: index of chunk to be removed - * - * This function removes the chunk at index @i from @array - * - * Returns: nothing - */ - -void -metadata_chunk_array_remove_by_index (MetadataChunkArray * array, guint32 i) -{ - - if (i < array->len) { - g_free (array->chunk[i].data); - if (i < --array->len) { - memmove (&array->chunk[i], &array->chunk[i + 1], - sizeof (MetadataChunk) * (array->len - i)); - } - } -} diff --git a/ext/metadata/metadatatypes.h b/ext/metadata/metadatatypes.h deleted file mode 100644 index 7c0b00a94..000000000 --- a/ext/metadata/metadatatypes.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __METADATATYPES_H__ -#define __METADATATYPES_H__ - -/* - * includes - */ - -#include <glib.h> - -G_BEGIN_DECLS -/* - * enum and types - */ -/* *INDENT-OFF* */ - -typedef enum _tag_MetadataParsingReturn { - META_PARSING_ERROR = -1, - META_PARSING_DONE = 0, - META_PARSING_NEED_MORE_DATA = 1 -} MetadataParsingReturn; - -/* *INDENT-ON* */ - typedef enum _tag_MetadataChunkType -{ - MD_CHUNK_UNKNOWN, - MD_CHUNK_EXIF, - MD_CHUNK_IPTC, - MD_CHUNK_XMP -} MetadataChunkType; - -typedef struct _tag_MetadataChunk -{ - gint64 offset_orig; /* from the beginning of original file */ - /*here just for convinience (filled by element) offset in new stream */ - gint64 offset; - guint32 size; /* chunk or buffer size */ - guint8 *data; - MetadataChunkType type; /* used by mux to see what tags to insert here */ -} MetadataChunk; - -typedef struct _tag_MetadataChunkArray -{ - MetadataChunk *chunk; - gsize len; /* number of chunks into aray */ - gsize allocated_len; /* number of slots into the array to store chunks */ -} MetadataChunkArray; - -/* - * external function prototypes - */ - -extern void -metadata_chunk_array_init (MetadataChunkArray * array, gsize alloc_size); - -extern void metadata_chunk_array_free (MetadataChunkArray * array); - -extern void metadata_chunk_array_clear (MetadataChunkArray * array); - -extern void -metadata_chunk_array_append (MetadataChunkArray * array, MetadataChunk * chunk); - -extern void -metadata_chunk_array_append_sorted (MetadataChunkArray * array, - MetadataChunk * chunk); - -extern void metadata_chunk_array_remove_zero_size (MetadataChunkArray * array); - -extern void -metadata_chunk_array_remove_by_index (MetadataChunkArray * array, guint32 i); - -G_END_DECLS -#endif /* __METADATATYPES_H__ */ diff --git a/ext/metadata/metadataxmp.c b/ext/metadata/metadataxmp.c deleted file mode 100644 index 6e0c8f4b0..000000000 --- a/ext/metadata/metadataxmp.c +++ /dev/null @@ -1,904 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * SECTION: metadataxmp - * @short_description: This module provides functions to extract tags from - * XMP metadata chunks and create XMP chunks from metadata tags. - * @see_also: #metadatatags.[c/h] - * - * If lib exempi isn't available at compilation time, only the whole chunk - * (#METADATA_TAG_MAP_WHOLECHUNK) tags is created. It means that individual - * tags aren't mapped. - * - * <refsect2> - * <para> - * #metadata_xmp_init must be called before any other function in this - * module and must be paired with a call to #metadata_xmp_dispose - * </para> - * </refsect2> - * - * Last reviewed on 2008-01-24 (0.10.15) - */ - -/* - * includes - */ - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif -#include "metadataxmp.h" -#include "metadataparseutil.h" -#include "metadatatags.h" - -/* - * defines - */ - -GST_DEBUG_CATEGORY (gst_metadata_xmp_debug); -#define GST_CAT_DEFAULT gst_metadata_xmp_debug - -/* - * Implementation when lib exempi isn't available at compilation time - */ - -#ifndef HAVE_XMP - -/* - * extern functions implementations - */ - -gboolean -metadata_xmp_init (void) -{ - return TRUE; -} - -void -metadata_xmp_dispose (void) -{ - return; -} - -void -metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, - GstAdapter * adapter, MetadataTagMapping mapping) -{ - - if (mapping & METADATA_TAG_MAP_WHOLECHUNK) { - GST_LOG ("XMP not defined, sending just one tag as whole chunk"); - metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_XMP, adapter); - } - -} - -void -metadatamux_xmp_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, - const GstTagList * taglist) -{ - /* do nothing */ -} - -#else /* ifndef HAVE_XMP */ - -/* - * Implementation when lib exempi isn't available at compilation time - */ - -/* - * includes - */ - -#include <exempi/xmp.h> -#include <string.h> - -/* - * enum and types - */ - -typedef struct _tag_SchemaTagMap -{ - const gchar *xmp_tag; - const gchar *gst_tag; -} SchemaTagMap; - -typedef struct _tag_SchemaMap -{ - const gchar *schema; - const gchar *prefix; - const guint8 prefix_len; - const SchemaTagMap *tags_map; -} SchemaMap; - -/* - * defines and static global vars - */ - -#define XMP_SCHEMA_NODE 0x80000000UL - -/* *INDENT-OFF* */ -/* When changing these tables, update 'metadata_mapping.htm' file too. */ -static const SchemaTagMap schema_map_dublin_tags_map[] = { - {"creator", GST_TAG_ARTIST }, - {"description", GST_TAG_DESCRIPTION }, - {"format", GST_TAG_VIDEO_CODEC }, - {"rights", GST_TAG_COPYRIGHT }, - {"subject", GST_TAG_KEYWORDS }, - {"title", GST_TAG_TITLE }, - {"type", GST_TAG_CODEC }, - {NULL, NULL} -}; - -static const SchemaTagMap schema_map_photoshop_tags_map[] = { - {"Country", GST_TAG_GEO_LOCATION_COUNTRY }, - {"City", GST_TAG_GEO_LOCATION_CITY }, - {NULL, NULL} -}; - -static const SchemaTagMap schema_map_iptc4xmpcore_tags_map[] = { - {"location", GST_TAG_GEO_LOCATION_SUBLOCATION }, - {NULL, NULL} -}; -/* *INDENT-ON* */ - -static const SchemaMap schema_map_dublin = { - "http://purl.org/dc/elements/1.1/", - "dc:", - 3, - schema_map_dublin_tags_map -}; - -/* http://www.adobe.com/devnet/xmp/pdfs/xmp_specification.pdf */ -static const SchemaMap schema_map_photoshop = { - "http://ns.adobe.com/photoshop/1.0/", - "photoshop:", - 10, - schema_map_photoshop_tags_map -}; - -/* http://www.iptc.org/std/Iptc4xmpCore/1.0/specification/Iptc4xmpCore_1.0-spec-XMPSchema_8.pdf */ -static const SchemaMap schema_map_iptc4xmpcore = { - "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/", - "Iptc4xmpCore:", - 13, - schema_map_iptc4xmpcore_tags_map -}; - -static const SchemaMap *schemas_map[] = { - &schema_map_dublin, - &schema_map_photoshop, - &schema_map_iptc4xmpcore, - NULL -}; - -/* - * static helper functions declaration - */ - -static const SchemaTagMap *metadataparse_xmp_get_tagsmap_from_path (const - SchemaMap * schema_map, const gchar * path, uint32_t opt); - -static const SchemaTagMap *metadatamux_xmp_get_tagsmap_from_gsttag (const - SchemaMap * schema_map, const gchar * tag); - -static void -metadataparse_xmp_iter (GstTagList * taglist, GstTagMergeMode mode, XmpPtr xmp); - -static void -metadataparse_xmp_iter_node_schema (GstTagList * taglist, GstTagMergeMode mode, - XmpPtr xmp, const char *schema, const char *path); - -static void -metadataparse_xmp_iter_array (GstTagList * taglist, GstTagMergeMode mode, - XmpPtr xmp, const char *schema, const char *path, - const SchemaMap * schema_map); - -static void -metadataparse_xmp_iter_simple_qual (GstTagList * taglist, GstTagMergeMode mode, - const char *path, const char *value, const SchemaMap * schema_map); - -static void -metadataparse_xmp_iter_simple (GstTagList * taglist, GstTagMergeMode mode, - const char *path, const char *value, const SchemaMap * schema_map); - -static void -metadataparse_xmp_iter_add_to_tag_list (GstTagList * taglist, - GstTagMergeMode mode, const char *path, const char *value, - const SchemaMap * schema_map, const uint32_t opt); - -static void -metadatamux_xmp_for_each_tag_in_list (const GstTagList * list, - const gchar * tag, gpointer user_data); - -/* - * extern functions implementations - */ - -/* - * metadata_xmp_init: - * - * Init lib exempi (if present in compilation time) - * This function must be called before any other function from this module. - * This function must not be called twice without call - * to #metadata_xmp_dispose beteween them. - * @see_also: #metadata_xmp_dispose - * - * Returns: nothing - */ - -gboolean -metadata_xmp_init (void) -{ - return xmp_init (); -} - -/* - * metadata_xmp_dispose: - * - * Call this function to free any resource allocated by #metadata_xmp_init - * @see_also: #metadata_xmp_init - * - * Returns: nothing - */ - -void -metadata_xmp_dispose (void) -{ - xmp_terminate (); -} - -/* - * metadataparse_xmp_tag_list_add: - * @taglist: tag list in which extracted tags will be added - * @mode: tag list merge mode - * @adapter: contains the XMP metadata chunk - * @mapping: if is to extract individual tags and/or the whole chunk. - * - * This function gets a XMP chunk (@adapter) and extract tags from it - * and then to add to @taglist. - * Note: The XMP chunk (@adapetr) must NOT be wrapped by any bytes specific - * to any file format - * @see_also: #metadataparse_xmp_iter - * - * Returns: nothing - */ - -void -metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, - GstAdapter * adapter, MetadataTagMapping mapping) -{ - const guint8 *buf; - guint32 size; - XmpPtr xmp = NULL; - - if (adapter == NULL || (size = gst_adapter_available (adapter)) == 0) { - goto done; - } - - /* add chunk tag */ - if (mapping & METADATA_TAG_MAP_WHOLECHUNK) { - metadataparse_util_tag_list_add_chunk (taglist, mode, GST_TAG_XMP, adapter); - } - - if (!(mapping & METADATA_TAG_MAP_INDIVIDUALS)) - goto done; - - buf = gst_adapter_peek (adapter, size); - - xmp = xmp_new ((gchar *) buf, size); - if (!xmp) - goto done; - - metadataparse_xmp_iter (taglist, mode, xmp); - -done: - - if (xmp) { - xmp_free (xmp); - } - - return; - -} - -/* - * metadatamux_xmp_create_chunk_from_tag_list: - * @buf: buffer that will have the created XMP chunk - * @size: size of the buffer that will be created - * @taglist: list of tags to be added to XMP chunk - * - * Get tags from @taglist, create a XMP chunk based on it and save to @buf. - * Note: The XMP chunk is NOT wrapped by any bytes specific to any file format - * - * Returns: nothing - */ - -void -metadatamux_xmp_create_chunk_from_tag_list (guint8 ** buf, guint32 * size, - const GstTagList * taglist) -{ - GstBuffer *xmp_chunk = NULL; - const GValue *val = NULL; - XmpPtr xmp = NULL; - XmpStringPtr xmp_str_buf = xmp_string_new (); - - if (!(buf && size)) - goto done; - - g_free (*buf); - *buf = NULL; - *size = 0; - - val = gst_tag_list_get_value_index (taglist, GST_TAG_XMP, 0); - if (val) { - xmp_chunk = gst_value_get_buffer (val); - if (xmp_chunk) - xmp = - xmp_new ((gchar *) GST_BUFFER_DATA (xmp_chunk), - GST_BUFFER_SIZE (xmp_chunk)); - } - - if (NULL == xmp) - xmp = xmp_new_empty (); - - gst_tag_list_foreach (taglist, metadatamux_xmp_for_each_tag_in_list, xmp); - - if (!xmp_serialize (xmp, xmp_str_buf, 0, 2)) { - GST_ERROR ("failed to serialize xmp into chunk\n"); - } else if (xmp_str_buf) { - const gchar *text = xmp_string_cstr (xmp_str_buf); - - *buf = (guint8 *) g_strdup (text); - *size = strlen (text); - } else { - GST_ERROR ("failed to serialize xmp into chunk\n"); - } - -done: - - if (xmp_str_buf) - xmp_string_free (xmp_str_buf); - - if (xmp) - xmp_free (xmp); - - return; -} - -/* - * static helper functions implementation - */ - -/* - * metadataparse_xmp_get_tagsmap_from_path: - * @schema_map: Structure containg a map beteween GST tags and tags into a XMP - * schema - * @path: string describing a XMP tag - * @opt: indicates if the string (@path) has extras caracters like '[' and ']' - * - * This returns a structure that contains the GStreamer tag mapped to an XMP - * tag. - * - * Returns: - * <itemizedlist> - * <listitem><para>Structure containing the GST tag mapped - * to the XMP tag (@path) - * </para></listitem> - * <listitem><para>%NULL if there is no mapped GST tag for XMP tag (@path) - * </para></listitem> - * </itemizedlist> - */ - -static const SchemaTagMap * -metadataparse_xmp_get_tagsmap_from_path (const SchemaMap * schema_map, - const gchar * path, uint32_t opt) -{ - - GString *string = NULL; - gchar *ch; - SchemaTagMap *tags_map = NULL; - - if (NULL == schema_map) - goto done; - - tags_map = (SchemaTagMap *) schema_map->tags_map; - - if (XMP_HAS_PROP_QUALIFIERS (opt) || XMP_IS_ARRAY_ALTTEXT (opt)) { - - string = g_string_new (path); - - /* remove the language qualifier "[xxx]" */ - ch = string->str + string->len - 3; - while (ch != string->str + schema_map->prefix_len) { - if (*ch == '[') { - *ch = '\0'; - } - --ch; - } - - } else { - ch = (gchar *) path + schema_map->prefix_len; - } - - while (tags_map->xmp_tag) { - if (0 == strcmp (tags_map->xmp_tag, ch)) - break; - tags_map++; - } - -done: - - if (string) - g_string_free (string, TRUE); - - return tags_map; - -} - -/* - * metadatamux_xmp_get_tagsmap_from_gsttag: - * @schema_map: Structure containg a map beteween GST tags and tags into a XMP - * schema - * @tag: GStreaner tag to look for - * - * This returns a structure that contains the XMP tag mapped to a GStreamer - * tag. - * - * Returns: - * <itemizedlist> - * <listitem><para>Structure containing the XMP tag mapped - * to the GST tag (@path) - * </para></listitem> - * <listitem><para>%NULL if there is no mapped XMP tag for GST @tag - * </para></listitem> - * </itemizedlist> - */ - -static const SchemaTagMap * -metadatamux_xmp_get_tagsmap_from_gsttag (const SchemaMap * schema_map, - const gchar * tag) -{ - SchemaTagMap *tags_map = NULL; - int i; - - if (NULL == schema_map) - goto done; - - for (i = 0; schema_map->tags_map[i].gst_tag; i++) { - if (0 == strcmp (schema_map->tags_map[i].gst_tag, tag)) { - tags_map = (SchemaTagMap *) & schema_map->tags_map[i]; - break; - } - } - -done: - - return tags_map; - -} - -/* - * metadataparse_xmp_iter: - * @taglist: tag list in which extracted tags will be added - * @mode: tag list merge mode - * @xmp: handle to XMP data from lib exempi - * - * This function looks all the shemas in a XMP data (@xmp) and then calls - * #metadataparse_xmp_iter_node_schema for each schema. In the end, the idea is - * to add all XMP mapped tags to @taglist by unsing a specified merge @mode - * @see_also: #metadataparse_xmp_tag_list_add - * #metadataparse_xmp_iter_node_schema - * - * Returns: nothing - */ - -void -metadataparse_xmp_iter (GstTagList * taglist, GstTagMergeMode mode, XmpPtr xmp) -{ - XmpStringPtr xstr_schema = xmp_string_new (); - XmpStringPtr xstr_path = xmp_string_new (); - XmpStringPtr xstr_prop = xmp_string_new (); - uint32_t opt = 0; - XmpIteratorPtr xmp_iter = NULL; - - xmp_iter = xmp_iterator_new (xmp, NULL, NULL, XMP_ITER_JUSTCHILDREN); - - if (NULL == xmp_iter) - goto done; - - while (xmp_iterator_next (xmp_iter, xstr_schema, xstr_path, xstr_prop, &opt)) { - const char *schema = xmp_string_cstr (xstr_schema); - const char *path = xmp_string_cstr (xstr_path); - - if (XMP_IS_NODE_SCHEMA (opt)) { - GST_LOG ("%s", schema); - metadataparse_xmp_iter_node_schema (taglist, mode, xmp, schema, path); - } else { - GST_LOG ("Unexpected iteraction"); - } - } - -done: - - if (xmp_iter) - xmp_iterator_free (xmp_iter); - - if (xstr_prop) - xmp_string_free (xstr_prop); - - if (xstr_path) - xmp_string_free (xstr_path); - - if (xstr_schema) - xmp_string_free (xstr_schema); -} - -/* - * metadataparse_xmp_iter_node_schema: - * @taglist: tag list in which extracted tags will be added - * @mode: tag list merge mode - * @xmp: handle to XMP data from lib exempi - * @schema: schema name string - * @path: schema path - * - * This function gets a @schema, finds the #SchemaMap (structure - * containing @schema description and map with GST tags) to it. And then call - * #metadataparse_xmp_iter_array. In the end, the idea is - * to add all XMP Schema mapped tags to @taglist by unsing a specified - * merge @mode - * @see_also: #metadataparse_xmp_iter - * #metadataparse_xmp_iter_array - * - * Returns: nothing - */ - -void -metadataparse_xmp_iter_node_schema (GstTagList * taglist, GstTagMergeMode mode, - XmpPtr xmp, const char *schema, const char *path) -{ - const SchemaMap *schema_map = NULL; - gint i; - - for (i = 0; schemas_map[i]; i++) { - if (0 == strcmp (schema, schemas_map[i]->schema)) { - schema_map = schemas_map[i]; - break; - } - } - - metadataparse_xmp_iter_array (taglist, mode, xmp, schema, path, schema_map); -} - -/* - * metadataparse_xmp_iter_array: - * @taglist: tag list in which extracted tags will be added - * @mode: tag list merge mode - * @xmp: handle to XMP data from lib exempi - * @schema: schema name string - * @path: schema path - * @schema_map: structure containing @schema description and map with GST tags - * - * This function looks all the tags into a @schema and call other functions in - * order to add the mapped ones to @taglist by using a specified merge @mode - * @see_also: #metadataparse_xmp_iter_node_schema - * #metadataparse_xmp_iter_simple_qual metadataparse_xmp_iter_simple - * - * Returns: nothing - */ - -void -metadataparse_xmp_iter_array (GstTagList * taglist, GstTagMergeMode mode, - XmpPtr xmp, const char *schema, const char *path, - const SchemaMap * schema_map) -{ - XmpStringPtr xstr_schema = xmp_string_new (); - XmpStringPtr xstr_path = xmp_string_new (); - XmpStringPtr xstr_prop = xmp_string_new (); - uint32_t opt = 0; - XmpIteratorPtr xmp_iter = NULL; - - xmp_iter = xmp_iterator_new (xmp, schema, path, XMP_ITER_JUSTCHILDREN); - - if (NULL == xmp_iter) - goto done; - - while (xmp_iterator_next (xmp_iter, xstr_schema, xstr_path, xstr_prop, &opt)) { - const char *schema = xmp_string_cstr (xstr_schema); - const char *path = xmp_string_cstr (xstr_path); - const char *value = xmp_string_cstr (xstr_prop); - - if (XMP_IS_NODE_SCHEMA (opt)) { - GST_LOG ("Unexpected iteraction"); - } else if (XMP_IS_PROP_SIMPLE (opt)) { - if (strcmp (path, "") != 0) { - if (XMP_HAS_PROP_QUALIFIERS (opt)) { - /* ignore language qualifier, just get the first */ - metadataparse_xmp_iter_simple_qual (taglist, mode, path, value, - schema_map); - } else { - metadataparse_xmp_iter_simple (taglist, mode, path, value, - schema_map); - } - } - } else if (XMP_IS_PROP_ARRAY (opt)) { - /* FIXME: array with merge mode */ - GstTagMergeMode new_mode = mode; - -#if 0 - //const gchar *tag = ; - if (mode == GST_TAG_MERGE_REPLACE) { - //gst_tag_list_remove_tag(taglist, ); - } -#endif - if (XMP_IS_ARRAY_ALTTEXT (opt)) { - metadataparse_xmp_iter_array (taglist, new_mode, xmp, schema, path, - schema_map); - xmp_iterator_skip (xmp_iter, XMP_ITER_SKIPSUBTREE); - } else { - metadataparse_xmp_iter_array (taglist, new_mode, xmp, schema, path, - schema_map); - xmp_iterator_skip (xmp_iter, XMP_ITER_SKIPSUBTREE); - } - } - - } - -done: - - if (xmp_iter) - xmp_iterator_free (xmp_iter); - - if (xstr_prop) - xmp_string_free (xstr_prop); - - if (xstr_path) - xmp_string_free (xstr_path); - - if (xstr_schema) - xmp_string_free (xstr_schema); - -} - -/* - * metadataparse_xmp_iter_simple_qual: - * @taglist: tag list in which extracted tags will be added - * @mode: tag list merge mode - * @path: schema path - * @value: value of the (@path) tag - * @schema_map: structure containing @schema description and map with GST tags - * - * This function gets a XMP tag (@path) with quilifiers and try to add it - * to @taglist by calling #metadataparse_xmp_iter_add_to_tag_list - * @see_also: #metadataparse_xmp_iter_array - * #metadataparse_xmp_iter_simple #metadataparse_xmp_iter_add_to_tag_list - * - * Returns: nothing - */ - -void -metadataparse_xmp_iter_simple_qual (GstTagList * taglist, GstTagMergeMode mode, - const char *path, const char *value, const SchemaMap * schema_map) -{ - GString *string = g_string_new (path); - -#ifndef GST_DISABLE_GST_DEBUG - gchar *ch; - - /* remove the language qualifier */ - ch = string->str + string->len - 3; - while (ch != string->str + schema_map->prefix_len) { - if (*ch == '[') { - *ch = '\0'; - } - --ch; - } - GST_LOG (" %s = %s", string->str, value); -#endif /* #ifndef GST_DISABLE_GST_DEBUG */ - - metadataparse_xmp_iter_add_to_tag_list (taglist, mode, path, value, - schema_map, XMP_PROP_HAS_QUALIFIERS); - - g_string_free (string, TRUE); -} - -/* - * metadataparse_xmp_iter_simple: - * @taglist: tag list in which extracted tags will be added - * @mode: tag list merge mode - * @path: schema path - * @value: value of the (@path) tag - * @schema_map: structure containing @schema description and map with GST tags - * - * This function gets a simple XMP tag (@path) and try to add it to @taglist by - * calling # metadataparse_xmp_iter_add_to_tag_list - * @see_also: #metadataparse_xmp_iter_array - * #metadataparse_xmp_iter_simple_qual #metadataparse_xmp_iter_add_to_tag_list - * - * Returns: nothing - */ - -void -metadataparse_xmp_iter_simple (GstTagList * taglist, GstTagMergeMode mode, - const char *path, const char *value, const SchemaMap * schema_map) -{ - GST_LOG (" %s = %s", path, value); - - metadataparse_xmp_iter_add_to_tag_list (taglist, mode, path, value, - schema_map, 0); - -} - -/* - * metadataparse_xmp_iter_add_to_tag_list: - * @taglist: tag list in which extracted tags will be added - * @mode: tag list merge mode - * @path: schema path - * @value: value of the (@path) tag - * @schema_map: structure containing @schema description and map with GST tags - * @opt: indicates if the string (@path) has extras caracters like '[' and ']' - * - * This function gets a XMP tag (@path) and see if it is mapped to a GST tag by - * calling #metadataparse_xmp_get_tagsmap_from_path, if so, add it to @taglist - * by using a specified merge @mode - * @see_also: #metadataparse_xmp_iter_simple_qual - * #metadataparse_xmp_iter_simple #metadataparse_xmp_get_tagsmap_from_path - * - * Returns: nothing - */ - -static void -metadataparse_xmp_iter_add_to_tag_list (GstTagList * taglist, - GstTagMergeMode mode, const char *path, const char *value, - const SchemaMap * schema_map, const uint32_t opt) -{ - GType type; - const SchemaTagMap *smaptag = - metadataparse_xmp_get_tagsmap_from_path (schema_map, path, opt); - - if (NULL == smaptag) - goto done; - - if (NULL == smaptag->gst_tag) - goto done; - - type = gst_tag_get_type (smaptag->gst_tag); - - switch (type) { - case G_TYPE_STRING: - gst_tag_list_add (taglist, mode, smaptag->gst_tag, value, NULL); - break; - default: - break; - } - -done: - - return; - -} - -/* - * metadatamux_xmp_for_each_tag_in_list: - * @list: GStreamer tag list from which @tag belongs to - * @tag: GStreamer tag to be added to the XMP chunk - * @user_data: pointer to #XmpPtr in which the tag will be added - * - * This function designed to be called for each tag in GST tag list. This - * function adds get the tag value from tag @list and then add it to the XMP - * chunk by using #XmpPtr and related functions from lib exempi - * @see_also: #metadatamux_xmp_create_chunk_from_tag_list - * - * Returns: nothing - */ - -static void -metadatamux_xmp_for_each_tag_in_list (const GstTagList * list, - const gchar * tag, gpointer user_data) -{ - XmpPtr xmp = (XmpPtr) user_data; - int i; - - GST_DEBUG ("trying to map tag '%s' to xmp", tag); - - for (i = 0; schemas_map[i]; i++) { - - /* FIXME: should try to get all of values (index) for the tag */ - - const SchemaMap *smap = schemas_map[i]; - const SchemaTagMap *stagmap = - metadatamux_xmp_get_tagsmap_from_gsttag (smap, tag); - - if (stagmap) { - gchar *value = NULL; - GType type = gst_tag_get_type (tag); - - switch (type) { - case G_TYPE_STRING: - gst_tag_list_get_string (list, tag, &value); - break; - default: - break; - } - - GST_DEBUG ("found mapping for tag '%s' in schema %s", tag, - schemas_map[i]->prefix); - - if (value) { - uint32_t options = 0; - -#ifdef XMP_1_99_5 - if (xmp_get_property (xmp, smap->schema, stagmap->xmp_tag, - NULL, &options)) { -#else - if (xmp_get_property_and_bits (xmp, smap->schema, stagmap->xmp_tag, - NULL, &options)) { -#endif - if (XMP_IS_PROP_SIMPLE (options)) { -#ifdef XMP_1_99_5 - xmp_set_property (xmp, smap->schema, stagmap->xmp_tag, value, 0); -#else - xmp_set_property (xmp, smap->schema, stagmap->xmp_tag, value); -#endif - } else { - xmp_set_array_item (xmp, smap->schema, stagmap->xmp_tag, 1, - value, 0); - } - } else { -#ifdef XMP_1_99_5 - xmp_set_property (xmp, smap->schema, stagmap->xmp_tag, value, 0); -#else - xmp_set_property (xmp, smap->schema, stagmap->xmp_tag, value); -#endif - } - - g_free (value); - } - } else { - GST_DEBUG ("no xmp mapping for tag '%s' in schema %s found", tag, - schemas_map[i]->prefix); - } - } -} - -#endif /* else (ifndef HAVE_XMP) */ diff --git a/ext/metadata/metadataxmp.h b/ext/metadata/metadataxmp.h deleted file mode 100644 index 47e4f1161..000000000 --- a/ext/metadata/metadataxmp.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * GStreamer - * Copyright 2007 Edgard Lima <edgard.lima@indt.org.br> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Alternatively, the contents of this file may be used under the - * GNU Lesser General Public License Version 2.1 (the "LGPL"), in - * which case the following provisions apply instead of the ones - * mentioned above: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_METADATA_XMP_H__ -#define __GST_METADATA_XMP_H__ - -#include <gst/gst.h> -#include <gst/base/gstadapter.h> -#include "metadatatags.h" - -G_BEGIN_DECLS - -/* - * defines - */ -#define XMP_HEADER "http://ns.adobe.com/xap/1.0/" - -/* - * external function prototypes - */ - -extern gboolean metadata_xmp_init (void); - -extern void metadata_xmp_dispose (void); - -extern void -metadataparse_xmp_tag_list_add (GstTagList * taglist, GstTagMergeMode mode, - GstAdapter * adapter, MetadataTagMapping mapping); - -extern void -metadatamux_xmp_create_chunk_from_tag_list (guint8 ** buf, guint32 *size, - const GstTagList * taglist); - -G_END_DECLS -#endif /* __GST_METADATA_XMP_H__ */ |