/* GStreamer
 * Copyright (C) 2010 Stefan Kost <stefan.kost@nokia.com>
 * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
 *
 * gstxmptag.c: library for reading / modifying xmp tags
 *
 * 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gsttagxmp
 * @title: GstXmptag
 * @short_description: tag mappings and support functions for plugins
 *                     dealing with xmp packets
 * @see_also: #GstTagList
 *
 * Contains various utility functions for plugins to parse or create
 * xmp packets and map them to and from #GstTagList<!-- -->s.
 *
 * Please note that the xmp parser is very lightweight and not strict at all.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "tag.h"
#include <gst/gsttagsetter.h>
#include "gsttageditingprivate.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>

#define GST_CAT_DEFAULT gst_tag_ensure_debug_category()

static GstDebugCategory *
gst_tag_ensure_debug_category (void)
{
  static gsize cat_gonce = 0;

  if (g_once_init_enter (&cat_gonce)) {
    GstDebugCategory *cat = NULL;

    GST_DEBUG_CATEGORY_INIT (cat, "xmp-tags", 0, "XMP GstTag helper functions");

    g_once_init_leave (&cat_gonce, (gsize) cat);
  }

  return (GstDebugCategory *) cat_gonce;
}

static const gchar *schema_list[] = {
  "dc",
  "xap",
  "tiff",
  "exif",
  "photoshop",
  "Iptc4xmpCore",
  "Iptc4xmpExt",
  NULL
};

/**
 * gst_tag_xmp_list_schemas:
 *
 * Gets the list of supported schemas in the xmp lib
 *
 * Returns: (transfer none): a %NULL terminated array of strings with the
 *     schema names
 */
const gchar **
gst_tag_xmp_list_schemas (void)
{
  return schema_list;
}

typedef struct _XmpSerializationData XmpSerializationData;
typedef struct _XmpTag XmpTag;

/*
 * Serializes a GValue into a string.
 */
typedef gchar *(*XmpSerializationFunc) (const GValue * value);

/*
 * Deserializes @str that is the gstreamer tag @gst_tag represented in
 * XMP as the @xmp_tag_value and adds the result to the @taglist.
 *
 * @pending_tags is passed so that compound xmp tags can search for its
 * complements on the list and use them. Note that used complements should
 * be freed and removed from the list.
 * The list is of PendingXmpTag
 */
typedef void (*XmpDeserializationFunc) (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag_value,
    const gchar * str, GSList ** pending_tags);

struct _XmpSerializationData
{
  GString *data;
  const gchar **schemas;
};

static gboolean
xmp_serialization_data_use_schema (XmpSerializationData * serdata,
    const gchar * schemaname)
{
  gint i = 0;
  if (serdata->schemas == NULL)
    return TRUE;

  while (serdata->schemas[i] != NULL) {
    if (strcmp (serdata->schemas[i], schemaname) == 0)
      return TRUE;
    i++;
  }
  return FALSE;
}

typedef enum
{
  GstXmpTagTypeNone = 0,
  GstXmpTagTypeSimple,
  GstXmpTagTypeBag,
  GstXmpTagTypeSeq,
  GstXmpTagTypeStruct,

  /* Not really a xmp type, this is a tag that in gst is represented with
   * a single value and on xmp it needs 2 (or more) simple values
   *
   * e.g. GST_TAG_GEO_LOCATION_ELEVATION needs to be mapped into 2 complementary
   * tags in the exif's schema. One of them stores the absolute elevation,
   * and the other one stores if it is above of below sea level.
   */
  GstXmpTagTypeCompound
} GstXmpTagType;

struct _XmpTag
{
  const gchar *gst_tag;
  const gchar *tag_name;
  GstXmpTagType type;

  /* some tags must be inside a Bag even
   * if they are a single entry. Set it here so we know */
  GstXmpTagType supertype;

  /* For tags that need a rdf:parseType attribute */
  const gchar *parse_type;

  /* Used for struct and compound types */
  GSList *children;

  XmpSerializationFunc serialize;
  XmpDeserializationFunc deserialize;
};

static GstTagMergeMode
xmp_tag_get_merge_mode (XmpTag * xmptag)
{
  switch (xmptag->type) {
    case GstXmpTagTypeBag:
    case GstXmpTagTypeSeq:
      return GST_TAG_MERGE_APPEND;
    case GstXmpTagTypeSimple:
    default:
      return GST_TAG_MERGE_KEEP;
  }
}

static const gchar *
xmp_tag_type_get_name (GstXmpTagType tagtype)
{
  switch (tagtype) {
    case GstXmpTagTypeSeq:
      return "rdf:Seq";
    case GstXmpTagTypeBag:
      return "rdf:Bag";
    default:
      break;
  }

  /* Make compiler happy */
  g_return_val_if_reached ("");
}

struct _PendingXmpTag
{
  XmpTag *xmp_tag;
  gchar *str;
};
typedef struct _PendingXmpTag PendingXmpTag;

/*
 * A schema is a mapping of strings (the tag name in gstreamer) to a list of
 * tags in xmp (XmpTag).
 */
typedef GHashTable GstXmpSchema;
#define gst_xmp_schema_lookup g_hash_table_lookup
#define gst_xmp_schema_insert g_hash_table_insert
static GstXmpSchema *
gst_xmp_schema_new ()
{
  return g_hash_table_new (g_direct_hash, g_direct_equal);
}

/*
 * Mappings from schema names into the schema group of tags (GstXmpSchema)
 */
static GHashTable *__xmp_schemas;

static GstXmpSchema *
_gst_xmp_get_schema (const gchar * name)
{
  GQuark key;
  GstXmpSchema *schema;

  key = g_quark_from_string (name);

  schema = g_hash_table_lookup (__xmp_schemas, GUINT_TO_POINTER (key));
  if (!schema) {
    GST_WARNING ("Schema %s doesn't exist", name);
  }
  return schema;
}

static void
_gst_xmp_add_schema (const gchar * name, GstXmpSchema * schema)
{
  GQuark key;

  key = g_quark_from_string (name);

  if (g_hash_table_lookup (__xmp_schemas, GUINT_TO_POINTER (key))) {
    GST_WARNING ("Schema %s already exists, ignoring", name);
    g_assert_not_reached ();
    return;
  }

  g_hash_table_insert (__xmp_schemas, GUINT_TO_POINTER (key), schema);
}

static void
_gst_xmp_schema_add_mapping (GstXmpSchema * schema, XmpTag * tag)
{
  GQuark key;

  key = g_quark_from_string (tag->gst_tag);

  if (gst_xmp_schema_lookup (schema, GUINT_TO_POINTER (key))) {
    GST_WARNING ("Tag %s already present for the schema", tag->gst_tag);
    g_assert_not_reached ();
    return;
  }
  gst_xmp_schema_insert (schema, GUINT_TO_POINTER (key), tag);
}

static XmpTag *
gst_xmp_tag_create (const gchar * gst_tag, const gchar * xmp_tag,
    gint xmp_type, XmpSerializationFunc serialization_func,
    XmpDeserializationFunc deserialization_func)
{
  XmpTag *xmpinfo;

  xmpinfo = g_slice_new (XmpTag);
  xmpinfo->gst_tag = gst_tag;
  xmpinfo->tag_name = xmp_tag;
  xmpinfo->type = xmp_type;
  xmpinfo->supertype = GstXmpTagTypeNone;
  xmpinfo->parse_type = NULL;
  xmpinfo->serialize = serialization_func;
  xmpinfo->deserialize = deserialization_func;
  xmpinfo->children = NULL;

  return xmpinfo;
}

static XmpTag *
gst_xmp_tag_create_compound (const gchar * gst_tag, const gchar * xmp_tag_a,
    const gchar * xmp_tag_b, XmpSerializationFunc serialization_func_a,
    XmpSerializationFunc serialization_func_b,
    XmpDeserializationFunc deserialization_func)
{
  XmpTag *xmptag;
  XmpTag *xmptag_a =
      gst_xmp_tag_create (gst_tag, xmp_tag_a, GstXmpTagTypeSimple,
      serialization_func_a, deserialization_func);
  XmpTag *xmptag_b =
      gst_xmp_tag_create (gst_tag, xmp_tag_b, GstXmpTagTypeSimple,
      serialization_func_b, deserialization_func);

  xmptag =
      gst_xmp_tag_create (gst_tag, NULL, GstXmpTagTypeCompound, NULL, NULL);

  xmptag->children = g_slist_prepend (xmptag->children, xmptag_b);
  xmptag->children = g_slist_prepend (xmptag->children, xmptag_a);

  return xmptag;
}

static void
_gst_xmp_schema_add_simple_mapping (GstXmpSchema * schema,
    const gchar * gst_tag, const gchar * xmp_tag, gint xmp_type,
    XmpSerializationFunc serialization_func,
    XmpDeserializationFunc deserialization_func)
{
  _gst_xmp_schema_add_mapping (schema,
      gst_xmp_tag_create (gst_tag, xmp_tag, xmp_type, serialization_func,
          deserialization_func));
}

/*
 * We do not return a copy here because elements are
 * appended, and the API is not public, so we shouldn't
 * have our lists modified during usage
 */
#if 0
static GPtrArray *
_xmp_tag_get_mapping (const gchar * gst_tag, XmpSerializationData * serdata)
{
  GPtrArray *ret = NULL;
  GHashTableIter iter;
  GQuark key = g_quark_from_string (gst_tag);
  gpointer iterkey, value;
  const gchar *schemaname;

  g_hash_table_iter_init (&iter, __xmp_schemas);
  while (!ret && g_hash_table_iter_next (&iter, &iterkey, &value)) {
    GstXmpSchema *schema = (GstXmpSchema *) value;

    schemaname = g_quark_to_string (GPOINTER_TO_UINT (iterkey));
    if (xmp_serialization_data_use_schema (serdata, schemaname))
      ret =
          (GPtrArray *) gst_xmp_schema_lookup (schema, GUINT_TO_POINTER (key));
  }
  return ret;
}
#endif

/* finds the gst tag that maps to this xmp tag in this schema */
static const gchar *
_gst_xmp_schema_get_mapping_reverse (GstXmpSchema * schema,
    const gchar * xmp_tag, XmpTag ** _xmp_tag)
{
  GHashTableIter iter;
  gpointer key, value;
  const gchar *ret = NULL;

  /* Iterate over the hashtable */
  g_hash_table_iter_init (&iter, schema);
  while (!ret && g_hash_table_iter_next (&iter, &key, &value)) {
    XmpTag *xmpinfo = (XmpTag *) value;

    if (xmpinfo->tag_name) {
      if (strcmp (xmpinfo->tag_name, xmp_tag) == 0) {
        *_xmp_tag = xmpinfo;
        ret = g_quark_to_string (GPOINTER_TO_UINT (key));
        goto out;
      }
    } else if (xmpinfo->children) {
      GSList *iter;
      for (iter = xmpinfo->children; iter; iter = g_slist_next (iter)) {
        XmpTag *child = iter->data;
        if (strcmp (child->tag_name, xmp_tag) == 0) {
          *_xmp_tag = child;
          ret = g_quark_to_string (GPOINTER_TO_UINT (key));
          goto out;
        }
      }
    } else {
      g_assert_not_reached ();
    }
  }

out:
  return ret;
}

/* finds the gst tag that maps to this xmp tag (searches on all schemas) */
static const gchar *
_gst_xmp_tag_get_mapping_reverse (const gchar * xmp_tag, XmpTag ** _xmp_tag)
{
  GHashTableIter iter;
  gpointer key, value;
  const gchar *ret = NULL;

  /* Iterate over the hashtable */
  g_hash_table_iter_init (&iter, __xmp_schemas);
  while (!ret && g_hash_table_iter_next (&iter, &key, &value)) {
    ret = _gst_xmp_schema_get_mapping_reverse ((GstXmpSchema *) value, xmp_tag,
        _xmp_tag);
  }
  return ret;
}

/* utility functions/macros */

#define METERS_PER_SECOND_TO_KILOMETERS_PER_HOUR (3.6)
#define KILOMETERS_PER_HOUR_TO_METERS_PER_SECOND (1/3.6)
#define MILES_PER_HOUR_TO_METERS_PER_SECOND (0.44704)
#define KNOTS_TO_METERS_PER_SECOND (0.514444)

static gchar *
double_to_fraction_string (gdouble num)
{
  gint frac_n;
  gint frac_d;

  gst_util_double_to_fraction (num, &frac_n, &frac_d);
  return g_strdup_printf ("%d/%d", frac_n, frac_d);
}

/* (de)serialize functions */
static gchar *
serialize_exif_gps_coordinate (const GValue * value, gchar pos, gchar neg)
{
  gdouble num;
  gchar c;
  gint integer;
  gchar fraction[G_ASCII_DTOSTR_BUF_SIZE];

  g_return_val_if_fail (G_VALUE_TYPE (value) == G_TYPE_DOUBLE, NULL);

  num = g_value_get_double (value);
  if (num < 0) {
    c = neg;
    num *= -1;
  } else {
    c = pos;
  }
  integer = (gint) num;

  g_ascii_dtostr (fraction, sizeof (fraction), (num - integer) * 60);

  /* FIXME review GPSCoordinate serialization spec for the .mm or ,ss
   * decision. Couldn't understand it clearly */
  return g_strdup_printf ("%d,%s%c", integer, fraction, c);
}

static gchar *
serialize_exif_latitude (const GValue * value)
{
  return serialize_exif_gps_coordinate (value, 'N', 'S');
}

static gchar *
serialize_exif_longitude (const GValue * value)
{
  return serialize_exif_gps_coordinate (value, 'E', 'W');
}

static void
deserialize_exif_gps_coordinate (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * str, gchar pos, gchar neg)
{
  gdouble value = 0;
  gint d = 0, m = 0, s = 0;
  gdouble m2 = 0;
  gchar c = 0;
  const gchar *current;

  /* get the degrees */
  if (sscanf (str, "%d", &d) != 1)
    goto error;

  /* find the beginning of the minutes */
  current = strchr (str, ',');
  if (current == NULL)
    goto end;
  current += 1;

  /* check if it uses ,SS or .mm */
  if (strchr (current, ',') != NULL) {
    if (!sscanf (current, "%d,%d%c", &m, &s, &c))
      goto error;
  } else {
    gchar *copy = g_strdup (current);
    gint len = strlen (copy);
    gint i;

    /* check the last letter */
    for (i = len - 1; len >= 0; len--) {
      if (g_ascii_isspace (copy[i]))
        continue;

      if (g_ascii_isalpha (copy[i])) {
        /* found it */
        c = copy[i];
        copy[i] = '\0';
        break;

      } else {
        /* something is wrong */
        g_free (copy);
        goto error;
      }
    }

    /* use a copy so we can change the last letter as E can cause
     * problems here */
    m2 = g_ascii_strtod (copy, NULL);
    g_free (copy);
  }

end:
  /* we can add them all as those that aren't parsed are 0 */
  value = d + (m / 60.0) + (s / (60.0 * 60.0)) + (m2 / 60.0);

  if (c == pos) {
    //NOP
  } else if (c == neg) {
    value *= -1;
  } else {
    goto error;
  }

  gst_tag_list_add (taglist, xmp_tag_get_merge_mode (xmptag), gst_tag, value,
      NULL);
  return;

error:
  GST_WARNING ("Failed to deserialize gps coordinate: %s", str);
}

static void
deserialize_exif_latitude (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag, const gchar * str,
    GSList ** pending_tags)
{
  deserialize_exif_gps_coordinate (xmptag, taglist, gst_tag, str, 'N', 'S');
}

static void
deserialize_exif_longitude (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag, const gchar * str,
    GSList ** pending_tags)
{
  deserialize_exif_gps_coordinate (xmptag, taglist, gst_tag, str, 'E', 'W');
}

static gchar *
serialize_exif_altitude (const GValue * value)
{
  gdouble num;

  num = g_value_get_double (value);

  if (num < 0)
    num *= -1;

  return double_to_fraction_string (num);
}

static gchar *
serialize_exif_altituderef (const GValue * value)
{
  gdouble num;

  num = g_value_get_double (value);

  /* 0 means above sea level, 1 means below */
  if (num >= 0)
    return g_strdup ("0");
  return g_strdup ("1");
}

static void
deserialize_exif_altitude (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag, const gchar * str,
    GSList ** pending_tags)
{
  const gchar *altitude_str = NULL;
  const gchar *altituderef_str = NULL;
  gint frac_n;
  gint frac_d;
  gdouble value;

  GSList *entry;
  PendingXmpTag *ptag = NULL;

  /* find the other missing part */
  if (strcmp (xmp_tag, "exif:GPSAltitude") == 0) {
    altitude_str = str;

    for (entry = *pending_tags; entry; entry = g_slist_next (entry)) {
      ptag = (PendingXmpTag *) entry->data;

      if (strcmp (ptag->xmp_tag->tag_name, "exif:GPSAltitudeRef") == 0) {
        altituderef_str = ptag->str;
        break;
      }
    }

  } else if (strcmp (xmp_tag, "exif:GPSAltitudeRef") == 0) {
    altituderef_str = str;

    for (entry = *pending_tags; entry; entry = g_slist_next (entry)) {
      ptag = (PendingXmpTag *) entry->data;

      if (strcmp (ptag->xmp_tag->tag_name, "exif:GPSAltitude") == 0) {
        altitude_str = ptag->str;
        break;
      }
    }

  } else {
    GST_WARNING ("Unexpected xmp tag %s", xmp_tag);
    return;
  }

  if (!altitude_str) {
    GST_WARNING ("Missing exif:GPSAltitude tag");
    return;
  }
  if (!altituderef_str) {
    GST_WARNING ("Missing exif:GPSAltitudeRef tag");
    return;
  }

  if (sscanf (altitude_str, "%d/%d", &frac_n, &frac_d) != 2) {
    GST_WARNING ("Failed to parse fraction: %s", altitude_str);
    return;
  }

  gst_util_fraction_to_double (frac_n, frac_d, &value);

  if (altituderef_str[0] == '0') {
    /* nop */
  } else if (altituderef_str[0] == '1') {
    value *= -1;
  } else {
    GST_WARNING ("Unexpected exif:AltitudeRef value: %s", altituderef_str);
    return;
  }

  /* add to the taglist */
  gst_tag_list_add (taglist, xmp_tag_get_merge_mode (xmptag),
      GST_TAG_GEO_LOCATION_ELEVATION, value, NULL);

  /* clean up entry */
  g_free (ptag->str);
  g_slice_free (PendingXmpTag, ptag);
  *pending_tags = g_slist_delete_link (*pending_tags, entry);
}

static gchar *
serialize_exif_gps_speed (const GValue * value)
{
  return double_to_fraction_string (g_value_get_double (value) *
      METERS_PER_SECOND_TO_KILOMETERS_PER_HOUR);
}

static gchar *
serialize_exif_gps_speedref (const GValue * value)
{
  /* we always use km/h */
  return g_strdup ("K");
}

static void
deserialize_exif_gps_speed (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag, const gchar * str,
    GSList ** pending_tags)
{
  const gchar *speed_str = NULL;
  const gchar *speedref_str = NULL;
  gint frac_n;
  gint frac_d;
  gdouble value;

  GSList *entry;
  PendingXmpTag *ptag = NULL;

  /* find the other missing part */
  if (strcmp (xmp_tag, "exif:GPSSpeed") == 0) {
    speed_str = str;

    for (entry = *pending_tags; entry; entry = g_slist_next (entry)) {
      ptag = (PendingXmpTag *) entry->data;

      if (strcmp (ptag->xmp_tag->tag_name, "exif:GPSSpeedRef") == 0) {
        speedref_str = ptag->str;
        break;
      }
    }

  } else if (strcmp (xmp_tag, "exif:GPSSpeedRef") == 0) {
    speedref_str = str;

    for (entry = *pending_tags; entry; entry = g_slist_next (entry)) {
      ptag = (PendingXmpTag *) entry->data;

      if (strcmp (ptag->xmp_tag->tag_name, "exif:GPSSpeed") == 0) {
        speed_str = ptag->str;
        break;
      }
    }

  } else {
    GST_WARNING ("Unexpected xmp tag %s", xmp_tag);
    return;
  }

  if (!speed_str) {
    GST_WARNING ("Missing exif:GPSSpeed tag");
    return;
  }
  if (!speedref_str) {
    GST_WARNING ("Missing exif:GPSSpeedRef tag");
    return;
  }

  if (sscanf (speed_str, "%d/%d", &frac_n, &frac_d) != 2) {
    GST_WARNING ("Failed to parse fraction: %s", speed_str);
    return;
  }

  gst_util_fraction_to_double (frac_n, frac_d, &value);

  if (speedref_str[0] == 'K') {
    value *= KILOMETERS_PER_HOUR_TO_METERS_PER_SECOND;
  } else if (speedref_str[0] == 'M') {
    value *= MILES_PER_HOUR_TO_METERS_PER_SECOND;
  } else if (speedref_str[0] == 'N') {
    value *= KNOTS_TO_METERS_PER_SECOND;
  } else {
    GST_WARNING ("Unexpected exif:SpeedRef value: %s", speedref_str);
    return;
  }

  /* add to the taglist */
  gst_tag_list_add (taglist, xmp_tag_get_merge_mode (xmptag),
      GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, value, NULL);

  /* clean up entry */
  g_free (ptag->str);
  g_slice_free (PendingXmpTag, ptag);
  *pending_tags = g_slist_delete_link (*pending_tags, entry);
}

static gchar *
serialize_exif_gps_direction (const GValue * value)
{
  return double_to_fraction_string (g_value_get_double (value));
}

static gchar *
serialize_exif_gps_directionref (const GValue * value)
{
  /* T for true geographic direction (M would mean magnetic) */
  return g_strdup ("T");
}

static void
deserialize_exif_gps_direction (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag, const gchar * str,
    GSList ** pending_tags, const gchar * direction_tag,
    const gchar * directionref_tag)
{
  const gchar *dir_str = NULL;
  const gchar *dirref_str = NULL;
  gint frac_n;
  gint frac_d;
  gdouble value;

  GSList *entry;
  PendingXmpTag *ptag = NULL;

  /* find the other missing part */
  if (strcmp (xmp_tag, direction_tag) == 0) {
    dir_str = str;

    for (entry = *pending_tags; entry; entry = g_slist_next (entry)) {
      ptag = (PendingXmpTag *) entry->data;

      if (strcmp (ptag->xmp_tag->tag_name, directionref_tag) == 0) {
        dirref_str = ptag->str;
        break;
      }
    }

  } else if (strcmp (xmp_tag, directionref_tag) == 0) {
    dirref_str = str;

    for (entry = *pending_tags; entry; entry = g_slist_next (entry)) {
      ptag = (PendingXmpTag *) entry->data;

      if (strcmp (ptag->xmp_tag->tag_name, direction_tag) == 0) {
        dir_str = ptag->str;
        break;
      }
    }

  } else {
    GST_WARNING ("Unexpected xmp tag %s", xmp_tag);
    return;
  }

  if (!dir_str) {
    GST_WARNING ("Missing %s tag", dir_str);
    return;
  }
  if (!dirref_str) {
    GST_WARNING ("Missing %s tag", dirref_str);
    return;
  }

  if (sscanf (dir_str, "%d/%d", &frac_n, &frac_d) != 2) {
    GST_WARNING ("Failed to parse fraction: %s", dir_str);
    return;
  }

  gst_util_fraction_to_double (frac_n, frac_d, &value);

  if (dirref_str[0] == 'T') {
    /* nop */
  } else if (dirref_str[0] == 'M') {
    GST_WARNING ("Magnetic direction tags aren't supported yet");
    return;
  } else {
    GST_WARNING ("Unexpected %s value: %s", directionref_tag, dirref_str);
    return;
  }

  /* add to the taglist */
  gst_tag_list_add (taglist, xmp_tag_get_merge_mode (xmptag), gst_tag, value,
      NULL);

  /* clean up entry */
  g_free (ptag->str);
  g_slice_free (PendingXmpTag, ptag);
  *pending_tags = g_slist_delete_link (*pending_tags, entry);
}

static void
deserialize_exif_gps_track (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag, const gchar * str,
    GSList ** pending_tags)
{
  deserialize_exif_gps_direction (xmptag, taglist, gst_tag, xmp_tag, str,
      pending_tags, "exif:GPSTrack", "exif:GPSTrackRef");
}

static void
deserialize_exif_gps_img_direction (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag, const gchar * str,
    GSList ** pending_tags)
{
  deserialize_exif_gps_direction (xmptag, taglist, gst_tag, xmp_tag, str,
      pending_tags, "exif:GPSImgDirection", "exif:GPSImgDirectionRef");
}

static void
deserialize_xmp_rating (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag, const gchar * str,
    GSList ** pending_tags)
{
  guint value;

  if (sscanf (str, "%u", &value) != 1) {
    GST_WARNING ("Failed to parse xmp:Rating %s", str);
    return;
  }

  if (value > 100) {
    GST_WARNING ("Unsupported Rating tag %u (should be from 0 to 100), "
        "ignoring", value);
    return;
  }

  gst_tag_list_add (taglist, xmp_tag_get_merge_mode (xmptag), gst_tag, value,
      NULL);
}

static gchar *
serialize_tiff_orientation (const GValue * value)
{
  const gchar *str;
  gint num;

  str = g_value_get_string (value);
  if (str == NULL) {
    GST_WARNING ("Failed to get image orientation tag value");
    return NULL;
  }

  num = __exif_tag_image_orientation_to_exif_value (str);
  if (num == -1)
    return NULL;

  return g_strdup_printf ("%d", num);
}

static void
deserialize_tiff_orientation (XmpTag * xmptag, GstTagList * taglist,
    const gchar * gst_tag, const gchar * xmp_tag, const gchar * str,
    GSList ** pending_tags)
{
  guint value;
  const gchar *orientation = NULL;

  if (sscanf (str, "%u", &value) != 1) {
    GST_WARNING ("Failed to parse tiff:Orientation %s", str);
    return;
  }

  if (value < 1 || value > 8) {
    GST_WARNING ("Invalid tiff:Orientation tag %u (should be from 1 to 8), "
        "ignoring", value);
    return;
  }

  orientation = __exif_tag_image_orientation_from_exif_value (value);
  if (orientation == NULL)
    return;
  gst_tag_list_add (taglist, xmp_tag_get_merge_mode (xmptag), gst_tag,
      orientation, NULL);
}


/* look at this page for addtional schemas
 * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/XMP.html
 */
static gpointer
_init_xmp_tag_map (gpointer user_data)
{
  XmpTag *xmpinfo;
  GstXmpSchema *schema;

  __xmp_schemas = g_hash_table_new (g_direct_hash, g_direct_equal);

  /* add the maps */
  /* dublic code metadata
   * http://dublincore.org/documents/dces/
   */
  schema = gst_xmp_schema_new ();
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_ARTIST,
      "dc:creator", GstXmpTagTypeSeq, NULL, NULL);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_COPYRIGHT,
      "dc:rights", GstXmpTagTypeSimple, NULL, NULL);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DATE_TIME, "dc:date",
      GstXmpTagTypeSeq, NULL, NULL);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DESCRIPTION,
      "dc:description", GstXmpTagTypeSimple, NULL, NULL);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_KEYWORDS,
      "dc:subject", GstXmpTagTypeBag, NULL, NULL);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_TITLE, "dc:title",
      GstXmpTagTypeSimple, NULL, NULL);
  /* FIXME: we probably want GST_TAG_{,AUDIO_,VIDEO_}MIME_TYPE */
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_VIDEO_CODEC,
      "dc:format", GstXmpTagTypeSimple, NULL, NULL);
  _gst_xmp_add_schema ("dc", schema);

  /* xap (xmp) schema */
  schema = gst_xmp_schema_new ();
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_USER_RATING,
      "xmp:Rating", GstXmpTagTypeSimple, NULL, deserialize_xmp_rating);
  _gst_xmp_add_schema ("xap", schema);

  /* tiff */
  schema = gst_xmp_schema_new ();
  _gst_xmp_schema_add_simple_mapping (schema,
      GST_TAG_DEVICE_MANUFACTURER, "tiff:Make", GstXmpTagTypeSimple, NULL,
      NULL);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DEVICE_MODEL,
      "tiff:Model", GstXmpTagTypeSimple, NULL, NULL);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_APPLICATION_NAME,
      "tiff:Software", GstXmpTagTypeSimple, NULL, NULL);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_IMAGE_ORIENTATION,
      "tiff:Orientation", GstXmpTagTypeSimple, serialize_tiff_orientation,
      deserialize_tiff_orientation);
  _gst_xmp_add_schema ("tiff", schema);

  /* exif schema */
  schema = gst_xmp_schema_new ();
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_DATE_TIME,
      "exif:DateTimeOriginal", GstXmpTagTypeSimple, NULL, NULL);
  _gst_xmp_schema_add_simple_mapping (schema,
      GST_TAG_GEO_LOCATION_LATITUDE, "exif:GPSLatitude",
      GstXmpTagTypeSimple, serialize_exif_latitude, deserialize_exif_latitude);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_GEO_LOCATION_LONGITUDE,
      "exif:GPSLongitude", GstXmpTagTypeSimple, serialize_exif_longitude,
      deserialize_exif_longitude);
  _gst_xmp_schema_add_simple_mapping (schema,
      GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, "exif:ExposureBiasValue",
      GstXmpTagTypeSimple, NULL, NULL);

  /* compound exif tags */
  xmpinfo = gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_ELEVATION,
      "exif:GPSAltitude", "exif:GPSAltitudeRef", serialize_exif_altitude,
      serialize_exif_altituderef, deserialize_exif_altitude);
  _gst_xmp_schema_add_mapping (schema, xmpinfo);

  xmpinfo = gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED,
      "exif:GPSSpeed", "exif:GPSSpeedRef", serialize_exif_gps_speed,
      serialize_exif_gps_speedref, deserialize_exif_gps_speed);
  _gst_xmp_schema_add_mapping (schema, xmpinfo);

  xmpinfo =
      gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION,
      "exif:GPSTrack", "exif:GPSTrackRef", serialize_exif_gps_direction,
      serialize_exif_gps_directionref, deserialize_exif_gps_track);
  _gst_xmp_schema_add_mapping (schema, xmpinfo);

  xmpinfo = gst_xmp_tag_create_compound (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION,
      "exif:GPSImgDirection", "exif:GPSImgDirectionRef",
      serialize_exif_gps_direction, serialize_exif_gps_directionref,
      deserialize_exif_gps_img_direction);
  _gst_xmp_schema_add_mapping (schema, xmpinfo);

  _gst_xmp_add_schema ("exif", schema);

  /* photoshop schema */
  schema = gst_xmp_schema_new ();
  _gst_xmp_schema_add_simple_mapping (schema,
      GST_TAG_GEO_LOCATION_COUNTRY, "photoshop:Country",
      GstXmpTagTypeSimple, NULL, NULL);
  _gst_xmp_schema_add_simple_mapping (schema, GST_TAG_GEO_LOCATION_CITY,
      "photoshop:City", GstXmpTagTypeSimple, NULL, NULL);
  _gst_xmp_add_schema ("photoshop", schema);

  /* iptc4xmpcore schema */
  schema = gst_xmp_schema_new ();
  _gst_xmp_schema_add_simple_mapping (schema,
      GST_TAG_GEO_LOCATION_SUBLOCATION, "Iptc4xmpCore:Location",
      GstXmpTagTypeSimple, NULL, NULL);
  _gst_xmp_add_schema ("Iptc4xmpCore", schema);

  /* iptc4xmpext schema */
  schema = gst_xmp_schema_new ();
  xmpinfo = gst_xmp_tag_create (NULL, "Iptc4xmpExt:LocationShown",
      GstXmpTagTypeStruct, NULL, NULL);
  xmpinfo->supertype = GstXmpTagTypeBag;
  xmpinfo->parse_type = "Resource";
  xmpinfo->children = g_slist_prepend (xmpinfo->children,
      gst_xmp_tag_create (GST_TAG_GEO_LOCATION_SUBLOCATION,
          "LocationDetails:Sublocation", GstXmpTagTypeSimple, NULL, NULL));
  xmpinfo->children =
      g_slist_prepend (xmpinfo->children,
      gst_xmp_tag_create (GST_TAG_GEO_LOCATION_CITY,
          "LocationDetails:City", GstXmpTagTypeSimple, NULL, NULL));
  xmpinfo->children =
      g_slist_prepend (xmpinfo->children,
      gst_xmp_tag_create (GST_TAG_GEO_LOCATION_COUNTRY,
          "LocationDetails:Country", GstXmpTagTypeSimple, NULL, NULL));
  _gst_xmp_schema_add_mapping (schema, xmpinfo);
  _gst_xmp_add_schema ("Iptc4xmpExt", schema);

  return NULL;
}

static void
xmp_tags_initialize ()
{
  static GOnce my_once = G_ONCE_INIT;
  g_once (&my_once, (GThreadFunc) _init_xmp_tag_map, NULL);
}

typedef struct _GstXmpNamespaceMatch GstXmpNamespaceMatch;
struct _GstXmpNamespaceMatch
{
  const gchar *ns_prefix;
  const gchar *ns_uri;

  /*
   * Stores extra namespaces for array tags
   * The namespaces should be writen in the form:
   *
   * xmlns:XpTo="http://some.org/your/ns/name/ (next ones)"
   */
  const gchar *extra_ns;
};

static const GstXmpNamespaceMatch ns_match[] = {
  {"dc", "http://purl.org/dc/elements/1.1/", NULL},
  {"exif", "http://ns.adobe.com/exif/1.0/", NULL},
  {"tiff", "http://ns.adobe.com/tiff/1.0/", NULL},
  {"xap", "http://ns.adobe.com/xap/1.0/", NULL},
  {"photoshop", "http://ns.adobe.com/photoshop/1.0/", NULL},
  {"Iptc4xmpCore", "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/", NULL},
  {"Iptc4xmpExt", "http://iptc.org/std/Iptc4xmpExt/2008-02-29/",
      "xmlns:LocationDetails=\"http://iptc.org/std/Iptc4xmpExt/2008-02-29/LocationDetails/\""},
  {NULL, NULL, NULL}
};

typedef struct _GstXmpNamespaceMap GstXmpNamespaceMap;
struct _GstXmpNamespaceMap
{
  const gchar *original_ns;
  gchar *gstreamer_ns;
};

/* parsing */

static void
read_one_tag (GstTagList * list, XmpTag * xmptag,
    const gchar * v, GSList ** pending_tags)
{
  GType tag_type;
  GstTagMergeMode merge_mode;
  const gchar *tag = xmptag->gst_tag;

  g_return_if_fail (tag != NULL);

  if (xmptag->deserialize) {
    xmptag->deserialize (xmptag, list, tag, xmptag->tag_name, v, pending_tags);
    return;
  }

  merge_mode = xmp_tag_get_merge_mode (xmptag);
  tag_type = gst_tag_get_type (tag);

  /* add gstreamer tag depending on type */
  switch (tag_type) {
    case G_TYPE_STRING:{
      gst_tag_list_add (list, merge_mode, tag, v, NULL);
      break;
    }
    case G_TYPE_DOUBLE:{
      gdouble value = 0;
      gint frac_n, frac_d;

      if (sscanf (v, "%d/%d", &frac_n, &frac_d) == 2) {
        gst_util_fraction_to_double (frac_n, frac_d, &value);
        gst_tag_list_add (list, merge_mode, tag, value, NULL);
      } else {
        GST_WARNING ("Failed to parse fraction: %s", v);
      }
      break;
    }
    default:
      if (tag_type == GST_TYPE_DATE_TIME) {
        GstDateTime *datetime;

        if (v == NULL || *v == '\0') {
          GST_WARNING ("Empty string for datetime parsing");
          return;
        }

        GST_DEBUG ("Parsing %s into a datetime", v);
        datetime = gst_date_time_new_from_iso8601_string (v);
        if (datetime) {
          gst_tag_list_add (list, merge_mode, tag, datetime, NULL);
          gst_date_time_unref (datetime);
        }

      } else if (tag_type == G_TYPE_DATE) {
        GST_ERROR ("Use GST_TYPE_DATE_TIME in tags instead of G_TYPE_DATE");
      } else {
        GST_WARNING ("unhandled type for %s from xmp", tag);
      }
      break;
  }
}

/**
 * gst_tag_list_from_xmp_buffer:
 * @buffer: buffer
 *
 * Parse a xmp packet into a taglist.
 *
 * Returns: new taglist or %NULL, free the list when done
 */
GstTagList *
gst_tag_list_from_xmp_buffer (GstBuffer * buffer)
{
  GstTagList *list = NULL;
  GstMapInfo info;
  gchar *xps, *xp1, *xp2, *xpe, *ns, *ne;
  gsize len, max_ft_len;
  gboolean in_tag;
  gchar *part = NULL, *pp;
  guint i;
  XmpTag *last_xmp_tag = NULL;
  GSList *pending_tags = NULL;

  /* Used for strucuture xmp tags */
  XmpTag *context_tag = NULL;

  GstXmpNamespaceMap ns_map[] = {
    {"dc", NULL}
    ,
    {"exif", NULL}
    ,
    {"tiff", NULL}
    ,
    {"xap", NULL}
    ,
    {"photoshop", NULL}
    ,
    {"Iptc4xmpCore", NULL}
    ,
    {"Iptc4xmpExt", NULL}
    ,
    {NULL, NULL}
  };

  xmp_tags_initialize ();

  g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);

  GST_LOG ("Starting xmp parsing");

  gst_buffer_map (buffer, &info, GST_MAP_READ);
  xps = (gchar *) info.data;
  len = info.size;
  g_return_val_if_fail (len > 0, NULL);

  xpe = &xps[len + 1];

  /* check header and footer */
  xp1 = g_strstr_len (xps, len, "<?xpacket begin");
  if (!xp1)
    goto missing_header;
  xp1 = &xp1[strlen ("<?xpacket begin")];
  while (*xp1 != '>' && *xp1 != '<' && xp1 < xpe)
    xp1++;
  if (*xp1 != '>')
    goto missing_header;

  /* Use 2 here to count for an extra trailing \n that was added
   * in old versions, this makes it able to parse xmp packets with
   * and without this trailing char */
  max_ft_len = 2 + strlen ("<?xpacket end=\".\"?>");
  if (len < max_ft_len)
    goto missing_footer;

  xp2 = g_strstr_len (&xps[len - max_ft_len], max_ft_len, "<?xpacket ");
  if (!xp2)
    goto missing_footer;

  GST_INFO ("xmp header okay");

  /* skip > and text until first xml-node */
  xp1++;
  while (*xp1 != '<' && xp1 < xpe)
    xp1++;

  /* no tag can be longer than the whole buffer */
  part = g_malloc (xp2 - xp1);
  list = gst_tag_list_new_empty ();

  /* parse data into a list of nodes */
  /* data is between xp1..xp2 */
  in_tag = TRUE;
  ns = ne = xp1;
  pp = part;
  while (ne < xp2) {
    if (in_tag) {
      ne++;
      while (ne < xp2 && *ne != '>' && *ne != '<') {
        if (*ne == '\n' || *ne == '\t' || *ne == ' ') {
          while (ne < xp2 && (*ne == '\n' || *ne == '\t' || *ne == ' '))
            ne++;
          *pp++ = ' ';
        } else {
          *pp++ = *ne++;
        }
      }
      *pp = '\0';
      if (*ne != '>')
        goto broken_xml;
      /* create node */
      /* {XML, ns, ne-ns} */
      if (ns[0] != '/') {
        gchar *as = strchr (part, ' ');
        /* only log start nodes */
        GST_INFO ("xml: %s", part);

        if (as) {
          gchar *ae, *d;

          /* skip ' ' and scan the attributes */
          as++;
          d = ae = as;

          /* split attr=value pairs */
          while (*ae != '\0') {
            if (*ae == '=') {
              /* attr/value delimmiter */
              d = ae;
            } else if (*ae == '"') {
              /* scan values */
              gchar *v;

              ae++;
              while (*ae != '\0' && *ae != '"')
                ae++;

              *d = *ae = '\0';
              v = &d[2];
              GST_INFO ("   : [%s][%s]", as, v);
              if (!strncmp (as, "xmlns:", 6)) {
                i = 0;
                /* we need to rewrite known namespaces to what we use in
                 * tag_matches */
                while (ns_match[i].ns_prefix) {
                  if (!strcmp (ns_match[i].ns_uri, v))
                    break;
                  i++;
                }
                if (ns_match[i].ns_prefix) {
                  if (strcmp (ns_map[i].original_ns, &as[6])) {
                    g_free (ns_map[i].gstreamer_ns);
                    ns_map[i].gstreamer_ns = g_strdup (&as[6]);
                  }
                }
              } else {
                XmpTag *xmp_tag = NULL;
                /* FIXME: eventually rewrite ns
                 * find ':'
                 * check if ns before ':' is in ns_map and ns_map[i].gstreamer_ns!=NULL
                 * do 2 stage filter in tag_matches
                 */
                if (context_tag) {
                  GSList *iter;

                  for (iter = context_tag->children; iter;
                      iter = g_slist_next (iter)) {
                    XmpTag *child = iter->data;

                    GST_DEBUG ("Looking at child tag %s : %s", child->tag_name,
                        as);
                    if (strcmp (child->tag_name, as) == 0) {
                      xmp_tag = child;
                      break;
                    }
                  }

                } else {
                  GST_LOG ("Looking for tag: %s", as);
                  _gst_xmp_tag_get_mapping_reverse (as, &xmp_tag);
                }
                if (xmp_tag) {
                  PendingXmpTag *ptag;

                  GST_DEBUG ("Found xmp tag: %s -> %s", xmp_tag->tag_name,
                      xmp_tag->gst_tag);

                  /* we shouldn't find a xmp structure here */
                  g_assert (xmp_tag->gst_tag != NULL);

                  ptag = g_slice_new (PendingXmpTag);
                  ptag->xmp_tag = xmp_tag;
                  ptag->str = g_strdup (v);

                  pending_tags = g_slist_prepend (pending_tags, ptag);
                }
              }
              /* restore chars overwritten by '\0' */
              *d = '=';
              *ae = '"';
            } else if (*ae == '\0' || *ae == ' ') {
              /* end of attr/value pair */
              as = &ae[1];
            }
            /* to next char if not eos */
            if (*ae != '\0')
              ae++;
          }
        } else {
          /*
             <dc:type><rdf:Bag><rdf:li>Image</rdf:li></rdf:Bag></dc:type>
             <dc:creator><rdf:Seq><rdf:li/></rdf:Seq></dc:creator>
           */
          /* FIXME: eventually rewrite ns */

          /* skip rdf tags for now */
          if (strncmp (part, "rdf:", 4)) {
            /* if we're inside some struct, we look only on its children */
            if (context_tag) {
              GSList *iter;

              /* check if this is the closing of the context */
              if (part[0] == '/'
                  && strcmp (part + 1, context_tag->tag_name) == 0) {
                GST_DEBUG ("Closing context tag %s", part);
                context_tag = NULL;
              } else {

                for (iter = context_tag->children; iter;
                    iter = g_slist_next (iter)) {
                  XmpTag *child = iter->data;

                  GST_DEBUG ("Looking at child tag %s : %s", child->tag_name,
                      part);
                  if (strcmp (child->tag_name, part) == 0) {
                    last_xmp_tag = child;
                    break;
                  }
                }
              }

            } else {
              GST_LOG ("Looking for tag: %s", part);
              _gst_xmp_tag_get_mapping_reverse (part, &last_xmp_tag);
              if (last_xmp_tag && last_xmp_tag->type == GstXmpTagTypeStruct) {
                context_tag = last_xmp_tag;
                last_xmp_tag = NULL;
              }
            }
          }
        }
      }
      GST_LOG ("Next cycle");
      /* next cycle */
      ne++;
      if (ne < xp2) {
        if (*ne != '<')
          in_tag = FALSE;
        ns = ne;
        pp = part;
      }
    } else {
      while (ne < xp2 && *ne != '<') {
        *pp++ = *ne;
        ne++;
      }
      *pp = '\0';
      /* create node */
      /* {TXT, ns, (ne-ns)-1} */
      if (ns[0] != '\n' && &ns[1] <= ne) {
        /* only log non-newline nodes, we still have to parse them */
        GST_INFO ("txt: %s", part);
        if (last_xmp_tag) {
          PendingXmpTag *ptag;

          GST_DEBUG ("Found tag %s -> %s", last_xmp_tag->tag_name,
              last_xmp_tag->gst_tag);

          if (last_xmp_tag->type == GstXmpTagTypeStruct) {
            g_assert (context_tag == NULL);     /* we can't handle struct nesting currently */

            context_tag = last_xmp_tag;
          } else {
            ptag = g_slice_new (PendingXmpTag);
            ptag->xmp_tag = last_xmp_tag;
            ptag->str = g_strdup (part);

            pending_tags = g_slist_prepend (pending_tags, ptag);
          }
        }
      }
      /* next cycle */
      in_tag = TRUE;
      ns = ne;
      pp = part;
    }
  }

  pending_tags = g_slist_reverse (pending_tags);

  GST_DEBUG ("Done accumulating tags, now handling them");

  while (pending_tags) {
    PendingXmpTag *ptag = (PendingXmpTag *) pending_tags->data;

    pending_tags = g_slist_delete_link (pending_tags, pending_tags);

    read_one_tag (list, ptag->xmp_tag, ptag->str, &pending_tags);

    g_free (ptag->str);
    g_slice_free (PendingXmpTag, ptag);
  }

  GST_INFO ("xmp packet parsed, %d entries", gst_tag_list_n_tags (list));

out:

  /* free resources */
  i = 0;
  while (ns_map[i].original_ns) {
    g_free (ns_map[i].gstreamer_ns);
    i++;
  }

  g_free (part);

  gst_buffer_unmap (buffer, &info);

  return list;

  /* Errors */
missing_header:
  GST_WARNING ("malformed xmp packet header");
  goto out;
missing_footer:
  GST_WARNING ("malformed xmp packet footer");
  goto out;
broken_xml:
  GST_WARNING ("malformed xml tag: %s", part);
  gst_tag_list_unref (list);
  list = NULL;
  goto out;
}


/* formatting */

static void
string_open_tag (GString * string, const char *tag)
{
  g_string_append_c (string, '<');
  g_string_append (string, tag);
  g_string_append_c (string, '>');
}

static void
string_close_tag (GString * string, const char *tag)
{
  g_string_append (string, "</");
  g_string_append (string, tag);
  g_string_append (string, ">\n");
}

static char *
gst_value_serialize_xmp (const GValue * value)
{
  switch (G_VALUE_TYPE (value)) {
    case G_TYPE_STRING:
      return g_markup_escape_text (g_value_get_string (value), -1);
    case G_TYPE_INT:
      return g_strdup_printf ("%d", g_value_get_int (value));
    case G_TYPE_UINT:
      return g_strdup_printf ("%u", g_value_get_uint (value));
    case G_TYPE_DOUBLE:
      return double_to_fraction_string (g_value_get_double (value));
    default:
      break;
  }
  /* put non-switchable types here */
  if (G_VALUE_TYPE (value) == G_TYPE_DATE) {
    const GDate *date = g_value_get_boxed (value);

    return g_strdup_printf ("%04d-%02d-%02d",
        (gint) g_date_get_year (date), (gint) g_date_get_month (date),
        (gint) g_date_get_day (date));
  } else if (G_VALUE_TYPE (value) == GST_TYPE_DATE_TIME) {
    gint year, month, day, hour, min, sec, microsec;
    gfloat gmt_offset = 0;
    gint gmt_offset_hour, gmt_offset_min;
    GstDateTime *datetime = (GstDateTime *) g_value_get_boxed (value);

    if (!gst_date_time_has_time (datetime))
      return gst_date_time_to_iso8601_string (datetime);

    /* can't just use gst_date_time_to_iso8601_string() here because we need
     * the timezone info with a colon, i.e. as +03:00 instead of +0300 */
    year = gst_date_time_get_year (datetime);
    month = gst_date_time_get_month (datetime);
    day = gst_date_time_get_day (datetime);
    hour = gst_date_time_get_hour (datetime);
    min = gst_date_time_get_minute (datetime);
    sec = gst_date_time_get_second (datetime);
    microsec = gst_date_time_get_microsecond (datetime);
    gmt_offset = gst_date_time_get_time_zone_offset (datetime);
    if (gmt_offset == 0) {
      /* UTC */
      return g_strdup_printf ("%04d-%02d-%02dT%02d:%02d:%02d.%06dZ",
          year, month, day, hour, min, sec, microsec);
    } else {
      gmt_offset_hour = ABS (gmt_offset);
      gmt_offset_min = (ABS (gmt_offset) - gmt_offset_hour) * 60;

      return g_strdup_printf ("%04d-%02d-%02dT%02d:%02d:%02d.%06d%c%02d:%02d",
          year, month, day, hour, min, sec, microsec,
          gmt_offset >= 0 ? '+' : '-', gmt_offset_hour, gmt_offset_min);
    }
  } else {
    return NULL;
  }
}

static void
write_one_tag (const GstTagList * list, XmpTag * xmp_tag, gpointer user_data)
{
  guint i = 0, ct;
  XmpSerializationData *serialization_data = user_data;
  GString *data = serialization_data->data;
  char *s;

  /* struct type handled differently */
  if (xmp_tag->type == GstXmpTagTypeStruct ||
      xmp_tag->type == GstXmpTagTypeCompound) {
    GSList *iter;
    gboolean use_it = FALSE;

    /* check if any of the inner tags are present on the taglist */
    for (iter = xmp_tag->children; iter && !use_it; iter = g_slist_next (iter)) {
      XmpTag *child_tag = iter->data;

      if (gst_tag_list_get_value_index (list, child_tag->gst_tag, 0) != NULL) {
        use_it = TRUE;
        break;
      }
    }

    if (use_it) {
      if (xmp_tag->tag_name)
        string_open_tag (data, xmp_tag->tag_name);

      if (xmp_tag->supertype) {
        string_open_tag (data, xmp_tag_type_get_name (xmp_tag->supertype));
        if (xmp_tag->parse_type) {
          g_string_append (data, "<rdf:li rdf:parseType=\"");
          g_string_append (data, xmp_tag->parse_type);
          g_string_append_c (data, '"');
          g_string_append_c (data, '>');
        } else {
          string_open_tag (data, "rdf:li");
        }
      }

      /* now write it */
      for (iter = xmp_tag->children; iter; iter = g_slist_next (iter)) {
        write_one_tag (list, iter->data, user_data);
      }

      if (xmp_tag->supertype) {
        string_close_tag (data, "rdf:li");
        string_close_tag (data, xmp_tag_type_get_name (xmp_tag->supertype));
      }

      if (xmp_tag->tag_name)
        string_close_tag (data, xmp_tag->tag_name);
    }
    return;
  }

  /* at this point we must have a gst_tag */
  g_assert (xmp_tag->gst_tag);
  if (gst_tag_list_get_value_index (list, xmp_tag->gst_tag, 0) == NULL)
    return;

  ct = gst_tag_list_get_tag_size (list, xmp_tag->gst_tag);
  string_open_tag (data, xmp_tag->tag_name);

  /* fast path for single valued tag */
  if (ct == 1 || xmp_tag->type == GstXmpTagTypeSimple) {
    if (xmp_tag->serialize) {
      s = xmp_tag->serialize (gst_tag_list_get_value_index (list,
              xmp_tag->gst_tag, 0));
    } else {
      s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list,
              xmp_tag->gst_tag, 0));
    }
    if (s) {
      g_string_append (data, s);
      g_free (s);
    } else {
      GST_WARNING ("unhandled type for %s to xmp", xmp_tag->gst_tag);
    }
  } else {
    const gchar *typename;

    typename = xmp_tag_type_get_name (xmp_tag->type);

    string_open_tag (data, typename);
    for (i = 0; i < ct; i++) {
      GST_DEBUG ("mapping %s[%u/%u] to xmp", xmp_tag->gst_tag, i, ct);
      if (xmp_tag->serialize) {
        s = xmp_tag->serialize (gst_tag_list_get_value_index (list,
                xmp_tag->gst_tag, i));
      } else {
        s = gst_value_serialize_xmp (gst_tag_list_get_value_index (list,
                xmp_tag->gst_tag, i));
      }
      if (s) {
        string_open_tag (data, "rdf:li");
        g_string_append (data, s);
        string_close_tag (data, "rdf:li");
        g_free (s);
      } else {
        GST_WARNING ("unhandled type for %s to xmp", xmp_tag->gst_tag);
      }
    }
    string_close_tag (data, typename);
  }

  string_close_tag (data, xmp_tag->tag_name);
}

/**
 * gst_tag_list_to_xmp_buffer:
 * @list: tags
 * @read_only: does the container forbid inplace editing
 * @schemas: (array zero-terminated):
 *     %NULL terminated array of schemas to be used on serialization
 *
 * Formats a taglist as a xmp packet using only the selected
 * schemas. An empty list (%NULL) means that all schemas should
 * be used
 *
 * Returns: new buffer or %NULL, unref the buffer when done
 */
GstBuffer *
gst_tag_list_to_xmp_buffer (const GstTagList * list, gboolean read_only,
    const gchar ** schemas)
{
  GstBuffer *buffer = NULL;
  XmpSerializationData serialization_data;
  GString *data;
  guint i;
  gsize bsize;
  gpointer bdata;

  serialization_data.data = g_string_sized_new (4096);
  serialization_data.schemas = schemas;
  data = serialization_data.data;

  xmp_tags_initialize ();

  g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);

  /* xmp header */
  g_string_append (data,
      "<?xpacket begin=\"\xEF\xBB\xBF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>\n");
  g_string_append (data,
      "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"GStreamer\">\n");
  g_string_append (data,
      "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"");
  i = 0;
  while (ns_match[i].ns_prefix) {
    if (xmp_serialization_data_use_schema (&serialization_data,
            ns_match[i].ns_prefix)) {
      g_string_append_printf (data, " xmlns:%s=\"%s\"",
          ns_match[i].ns_prefix, ns_match[i].ns_uri);
      if (ns_match[i].extra_ns) {
        g_string_append_printf (data, " %s", ns_match[i].extra_ns);
      }
    }
    i++;
  }
  g_string_append (data, ">\n");
  g_string_append (data, "<rdf:Description rdf:about=\"\">\n");

  /* iterate the schemas */
  if (schemas == NULL) {
    /* use all schemas */
    schemas = gst_tag_xmp_list_schemas ();
  }
  for (i = 0; schemas[i] != NULL; i++) {
    GstXmpSchema *schema = _gst_xmp_get_schema (schemas[i]);
    GHashTableIter iter;
    gpointer key, value;

    if (schema == NULL)
      continue;

    /* Iterate over the hashtable */
    g_hash_table_iter_init (&iter, schema);
    while (g_hash_table_iter_next (&iter, &key, &value)) {
      write_one_tag (list, value, (gpointer) & serialization_data);
    }
  }

  /* xmp footer */
  g_string_append (data, "</rdf:Description>\n");
  g_string_append (data, "</rdf:RDF>\n");
  g_string_append (data, "</x:xmpmeta>\n");

  if (!read_only) {
    /* the xmp spec recommends to add 2-4KB padding for in-place editable xmp */
    guint i;

    for (i = 0; i < 32; i++) {
      g_string_append (data, "                " "                "
          "                " "                " "\n");
    }
  }
  g_string_append_printf (data, "<?xpacket end=\"%c\"?>",
      (read_only ? 'r' : 'w'));

  bsize = data->len;
  bdata = g_string_free (data, FALSE);

  buffer = gst_buffer_new_wrapped (bdata, bsize);

  return buffer;
}

#undef gst_xmp_schema_lookup
#undef gst_xmp_schema_insert
