/* GStreamer
 * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
 *
 * gstexiftag.c: library for reading / modifying exif 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:gsttagexif
 * @title: GstExiftag
 * @short_description: tag mappings and support functions for plugins
 *                     dealing with exif tags
 * @see_also: #GstTagList
 *
 * Contains utility function to parse #GstTagList<!-- -->s from exif
 * buffers and to create exif buffers from #GstTagList<!-- -->s
 *
 * Note that next IFD fields on the created exif buffers are set to 0.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gst/gsttagsetter.h>
#include <gst/base/gstbytewriter.h>
#include "gsttageditingprivate.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gst/math-compat.h>

/* Some useful constants */
#define TIFF_LITTLE_ENDIAN  0x4949
#define TIFF_BIG_ENDIAN     0x4D4D
#define TIFF_HEADER_SIZE    8
#define EXIF_TAG_ENTRY_SIZE (2 + 2 + 4 + 4)

/* Exif tag types */
#define EXIF_TYPE_BYTE       1
#define EXIF_TYPE_ASCII      2
#define EXIF_TYPE_SHORT      3
#define EXIF_TYPE_LONG       4
#define EXIF_TYPE_RATIONAL   5
#define EXIF_TYPE_UNDEFINED  7
#define EXIF_TYPE_SLONG      9
#define EXIF_TYPE_SRATIONAL 10

typedef struct _GstExifTagMatch GstExifTagMatch;
typedef struct _GstExifWriter GstExifWriter;
typedef struct _GstExifReader GstExifReader;
typedef struct _GstExifTagData GstExifTagData;

typedef void (*GstExifSerializationFunc) (GstExifWriter * writer,
    const GstTagList * taglist, const GstExifTagMatch * exiftag);

/*
 * Function used to deserialize tags that don't follow the usual
 * deserialization conversions. Usually those that have 'Ref' complementary
 * tags.
 *
 * Those functions receive a exif tag data in the parameters, plus the taglist
 * and the reader and buffer if they need to get more information to build
 * its tags. There are lots of parameters, but this is needed to make it
 * versatile. Explanation of them follows:
 *
 * exif_reader: The #GstExifReader with the reading parameter and taglist for
 * results.
 * reader: The #GstByteReader pointing to the start of the next tag entry in
 * the ifd, useful for tags that use other complementary tags.
 * the buffer start
 * exiftag: The #GstExifTagMatch that contains this tag info
 * tagdata: values from the already parsed tag
 */
typedef gint (*GstExifDeserializationFunc) (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata);

#define EXIF_SERIALIZATION_FUNC(name) \
static void serialize_ ## name (GstExifWriter * writer, \
    const GstTagList * taglist, const GstExifTagMatch * exiftag)

#define EXIF_DESERIALIZATION_FUNC(name) \
static gint deserialize_ ## name (GstExifReader * exif_reader, \
    GstByteReader * reader, const GstExifTagMatch * exiftag, \
    GstExifTagData * tagdata)

#define EXIF_SERIALIZATION_DESERIALIZATION_FUNC(name) \
  EXIF_SERIALIZATION_FUNC (name); \
  EXIF_DESERIALIZATION_FUNC (name)

/*
 * A common case among serialization/deserialization routines is that
 * the gstreamer tag is a string (with a predefined set of allowed values)
 * and exif is an int. These macros cover these cases
 */
#define EXIF_SERIALIZATION_MAP_STRING_TO_INT_FUNC(name,funcname) \
static void \
serialize_ ## name (GstExifWriter * writer, const GstTagList * taglist, \
    const GstExifTagMatch * exiftag) \
{ \
  gchar *str = NULL; \
  gint exif_value; \
\
  if (!gst_tag_list_get_string_index (taglist, exiftag->gst_tag, 0, &str)) { \
    GST_WARNING ("No %s tag present in taglist", exiftag->gst_tag); \
    return; \
  } \
\
  exif_value = __exif_tag_ ## funcname ## _to_exif_value (str); \
  if (exif_value == -1) { \
    g_free (str); \
    return; \
  } \
  g_free (str); \
\
  switch (exiftag->exif_type) { \
    case EXIF_TYPE_SHORT: \
      gst_exif_writer_write_short_tag (writer, exiftag->exif_tag, exif_value); \
      break; \
    case EXIF_TYPE_LONG: \
      gst_exif_writer_write_long_tag (writer, exiftag->exif_tag, exif_value); \
      break; \
    case EXIF_TYPE_UNDEFINED: \
    { \
        guint8 data = (guint8) exif_value; \
        write_exif_undefined_tag (writer, exiftag->exif_tag, &data, 1); \
    } \
      break; \
    default: \
      g_assert_not_reached (); \
      GST_WARNING ("Unmapped serialization for type %d", exiftag->exif_type); \
      break; \
   } \
}

#define EXIF_DESERIALIZATION_MAP_STRING_TO_INT_FUNC(name,funcname) \
static gint \
deserialize_ ## name (GstExifReader * exif_reader, \
    GstByteReader * reader, const GstExifTagMatch * exiftag, \
    GstExifTagData * tagdata) \
{ \
  const gchar *str = NULL; \
  gint value; \
\
  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag, \
      exiftag->exif_tag); \
\
  /* validate tag */ \
  if (tagdata->count != 1) { \
    GST_WARNING ("0x%X has unexpected count", tagdata->count); \
    return 0; \
  } \
\
  if (tagdata->tag_type == EXIF_TYPE_SHORT) { \
    if (exif_reader->byte_order == G_LITTLE_ENDIAN) { \
      value = GST_READ_UINT16_LE (tagdata->offset_as_data); \
    } else { \
      value = GST_READ_UINT16_BE (tagdata->offset_as_data); \
    } \
  } else if (tagdata->tag_type == EXIF_TYPE_UNDEFINED) { \
    value = GST_READ_UINT8 (tagdata->offset_as_data); \
  } else { \
    GST_WARNING ("0x%X has unexpected type %d", exiftag->exif_tag, \
        tagdata->tag_type); \
    return 0; \
  } \
\
  str = __exif_tag_## funcname ## _from_exif_value (value); \
  if (str == NULL) { \
    GST_WARNING ("Invalid value for tag 0x%X: %d", tagdata->tag, value); \
    return 0; \
  } \
  gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_REPLACE, \
      exiftag->gst_tag, str, NULL); \
\
  return 0; \
}

#define EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC(name,funcname) \
  EXIF_SERIALIZATION_MAP_STRING_TO_INT_FUNC(name,funcname); \
  EXIF_DESERIALIZATION_MAP_STRING_TO_INT_FUNC(name,funcname);

struct _GstExifTagMatch
{
  const gchar *gst_tag;
  guint16 exif_tag;
  guint16 exif_type;

  /* for tags that need special handling */
  guint16 complementary_tag;
  GstExifSerializationFunc serialize;
  GstExifDeserializationFunc deserialize;
};

struct _GstExifTagData
{
  guint16 tag;
  guint16 tag_type;
  guint32 count;
  guint32 offset;
  const guint8 *offset_as_data;
};

/*
 * Holds the info and variables necessary to write
 * the exif tags properly
 */
struct _GstExifWriter
{
  GstByteWriter tagwriter;
  GstByteWriter datawriter;

  gint byte_order;
  guint tags_total;
};

struct _GstExifReader
{
  GstTagList *taglist;
  GstBuffer *buffer;
  guint32 base_offset;
  gint byte_order;

  /* tags waiting for their complementary tags */
  GSList *pending_tags;
};

EXIF_SERIALIZATION_DESERIALIZATION_FUNC (aperture_value);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (contrast);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (exposure_program);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (exposure_mode);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (flash);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (gain_control);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (geo_coordinate);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (geo_direction);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (geo_elevation);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (metering_mode);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (orientation);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (saturation);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (scene_capture_type);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (scene_type);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (sensitivity_type);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (sharpness);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (shutter_speed);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (source);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (speed);
EXIF_SERIALIZATION_DESERIALIZATION_FUNC (white_balance);

EXIF_DESERIALIZATION_FUNC (resolution);
EXIF_DESERIALIZATION_FUNC (add_to_pending_tags);

/* FIXME copyright tag has a weird "artist\0editor\0" format that is
 * not yet handled */

/* exif tag numbers */
#define EXIF_TAG_GPS_LATITUDE_REF 0x1
#define EXIF_TAG_GPS_LATITUDE 0x2
#define EXIF_TAG_GPS_LONGITUDE_REF 0x3
#define EXIF_TAG_GPS_LONGITUDE 0x4
#define EXIF_TAG_GPS_ALTITUDE_REF 0x5
#define EXIF_TAG_GPS_ALTITUDE 0x6
#define EXIF_TAG_GPS_SPEED_REF 0xC
#define EXIF_TAG_GPS_SPEED 0xD
#define EXIF_TAG_GPS_TRACK_REF 0xE
#define EXIF_TAG_GPS_TRACK 0xF
#define EXIF_TAG_GPS_IMAGE_DIRECTION_REF 0x10
#define EXIF_TAG_GPS_IMAGE_DIRECTION 0x11
#define EXIF_TAG_GPS_HORIZONTAL_POSITIONING_ERROR 0x1F
#define EXIF_TAG_IMAGE_DESCRIPTION 0x10E
#define EXIF_TAG_MAKE 0x10F
#define EXIF_TAG_MODEL 0x110
#define EXIF_TAG_ORIENTATION 0x112
#define EXIF_TAG_XRESOLUTION 0x11A
#define EXIF_TAG_YRESOLUTION 0x11B
#define EXIF_TAG_RESOLUTION_UNIT 0x128
#define EXIF_TAG_SOFTWARE 0x131
#define EXIF_TAG_DATE_TIME 0x132
#define EXIF_TAG_ARTIST 0x13B
#define EXIF_TAG_COPYRIGHT 0x8298
#define EXIF_TAG_EXPOSURE_TIME 0x829A
#define EXIF_TAG_F_NUMBER 0x829D
#define EXIF_TAG_EXPOSURE_PROGRAM 0x8822
#define EXIF_TAG_PHOTOGRAPHIC_SENSITIVITY 0x8827
#define EXIF_TAG_SENSITIVITY_TYPE 0x8830
#define EXIF_TAG_ISO_SPEED 0x8833
#define EXIF_TAG_DATE_TIME_ORIGINAL 0x9003
#define EXIF_TAG_DATE_TIME_DIGITIZED 0x9004
#define EXIF_TAG_SHUTTER_SPEED_VALUE 0x9201
#define EXIF_TAG_APERTURE_VALUE 0x9202
#define EXIF_TAG_EXPOSURE_BIAS 0x9204
#define EXIF_TAG_METERING_MODE 0x9207
#define EXIF_TAG_FLASH 0x9209
#define EXIF_TAG_FOCAL_LENGTH 0x920A
#define EXIF_TAG_MAKER_NOTE 0x927C
#define EXIF_TAG_FILE_SOURCE 0xA300
#define EXIF_TAG_SCENE_TYPE 0xA301
#define EXIF_TAG_EXPOSURE_MODE 0xA402
#define EXIF_TAG_WHITE_BALANCE 0xA403
#define EXIF_TAG_DIGITAL_ZOOM_RATIO 0xA404
#define EXIF_TAG_FOCAL_LENGTH_IN_35_MM_FILM 0xa405
#define EXIF_TAG_SCENE_CAPTURE_TYPE 0xA406
#define EXIF_TAG_GAIN_CONTROL 0xA407
#define EXIF_TAG_CONTRAST 0xA408
#define EXIF_TAG_SATURATION 0xA409
#define EXIF_TAG_SHARPNESS 0xA40A

/* IFD pointer tags */
#define EXIF_IFD_TAG 0x8769
#define EXIF_GPS_IFD_TAG 0x8825

/* version tags */
#define EXIF_VERSION_TAG 0x9000
#define EXIF_FLASHPIX_VERSION_TAG 0xA000

/* useful macros for speed tag */
#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)

/*
 * Should be kept in ascending id order
 *
 * {gst-tag, exif-tag, exig-type, complementary-exif-tag, serialization-func,
 *     deserialization-func}
 */
static const GstExifTagMatch tag_map_ifd0[] = {
  {GST_TAG_IMAGE_HORIZONTAL_PPI, EXIF_TAG_XRESOLUTION, EXIF_TYPE_RATIONAL,
      0, NULL, deserialize_add_to_pending_tags},
  {GST_TAG_IMAGE_VERTICAL_PPI, EXIF_TAG_YRESOLUTION, EXIF_TYPE_RATIONAL,
      0, NULL, deserialize_add_to_pending_tags},
  {NULL, EXIF_TAG_RESOLUTION_UNIT, EXIF_TYPE_SHORT, 0, NULL,
      deserialize_resolution},
  {GST_TAG_DESCRIPTION, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TYPE_ASCII, 0, NULL,
      NULL},
  {GST_TAG_DEVICE_MANUFACTURER, EXIF_TAG_MAKE, EXIF_TYPE_ASCII, 0, NULL, NULL},
  {GST_TAG_DEVICE_MODEL, EXIF_TAG_MODEL, EXIF_TYPE_ASCII, 0, NULL, NULL},
  {GST_TAG_IMAGE_ORIENTATION, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT, 0,
        serialize_orientation,
      deserialize_orientation},
  {GST_TAG_APPLICATION_NAME, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII, 0, NULL, NULL},
  {GST_TAG_DATE_TIME, EXIF_TAG_DATE_TIME, EXIF_TYPE_ASCII, 0, NULL, NULL},
  {GST_TAG_ARTIST, EXIF_TAG_ARTIST, EXIF_TYPE_ASCII, 0, NULL, NULL},
  {GST_TAG_COPYRIGHT, EXIF_TAG_COPYRIGHT, EXIF_TYPE_ASCII, 0, NULL, NULL},
  {NULL, EXIF_IFD_TAG, EXIF_TYPE_LONG, 0, NULL, NULL},
  {NULL, EXIF_GPS_IFD_TAG, EXIF_TYPE_LONG, 0, NULL, NULL},
  {NULL, 0, 0, 0, NULL, NULL}
};

static const GstExifTagMatch tag_map_exif[] = {
  {GST_TAG_CAPTURING_SHUTTER_SPEED, EXIF_TAG_EXPOSURE_TIME, EXIF_TYPE_RATIONAL,
        0,
      NULL, NULL},
  {GST_TAG_CAPTURING_FOCAL_RATIO, EXIF_TAG_F_NUMBER, EXIF_TYPE_RATIONAL, 0,
        NULL,
      NULL},
  {GST_TAG_CAPTURING_EXPOSURE_PROGRAM, EXIF_TAG_EXPOSURE_PROGRAM,
        EXIF_TYPE_SHORT, 0, serialize_exposure_program,
      deserialize_exposure_program},

  /* don't need the serializer as we always write the iso speed alone */
  {GST_TAG_CAPTURING_ISO_SPEED, EXIF_TAG_PHOTOGRAPHIC_SENSITIVITY,
        EXIF_TYPE_SHORT, 0, NULL,
      deserialize_add_to_pending_tags},

  {GST_TAG_CAPTURING_ISO_SPEED, EXIF_TAG_SENSITIVITY_TYPE, EXIF_TYPE_SHORT, 0,
      serialize_sensitivity_type, deserialize_sensitivity_type},
  {GST_TAG_CAPTURING_ISO_SPEED, EXIF_TAG_ISO_SPEED, EXIF_TYPE_LONG, 0, NULL,
      NULL},
  {NULL, EXIF_VERSION_TAG, EXIF_TYPE_UNDEFINED, 0, NULL, NULL},
  {GST_TAG_DATE_TIME, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_TYPE_ASCII, 0, NULL,
      NULL},
  {GST_TAG_CAPTURING_SHUTTER_SPEED, EXIF_TAG_SHUTTER_SPEED_VALUE,
        EXIF_TYPE_SRATIONAL, 0,
      serialize_shutter_speed, deserialize_shutter_speed},
  {GST_TAG_CAPTURING_FOCAL_RATIO, EXIF_TAG_APERTURE_VALUE, EXIF_TYPE_RATIONAL,
        0,
      serialize_aperture_value, deserialize_aperture_value},
  {GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, EXIF_TAG_EXPOSURE_BIAS,
      EXIF_TYPE_SRATIONAL, 0, NULL, NULL},
  {GST_TAG_CAPTURING_METERING_MODE, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT, 0,
      serialize_metering_mode, deserialize_metering_mode},
  {GST_TAG_CAPTURING_FLASH_FIRED, EXIF_TAG_FLASH, EXIF_TYPE_SHORT, 0,
      serialize_flash, deserialize_flash},
  {GST_TAG_CAPTURING_FOCAL_LENGTH, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL, 0,
      NULL, NULL},
  {GST_TAG_APPLICATION_DATA, EXIF_TAG_MAKER_NOTE, EXIF_TYPE_UNDEFINED, 0, NULL,
      NULL},
  {NULL, EXIF_FLASHPIX_VERSION_TAG, EXIF_TYPE_UNDEFINED, 0, NULL, NULL},
  {GST_TAG_CAPTURING_SOURCE, EXIF_TAG_FILE_SOURCE, EXIF_TYPE_UNDEFINED,
      0, serialize_source, deserialize_source},
  {GST_TAG_CAPTURING_SOURCE, EXIF_TAG_SCENE_TYPE, EXIF_TYPE_UNDEFINED,
      0, serialize_scene_type, deserialize_scene_type},
  {GST_TAG_CAPTURING_EXPOSURE_MODE, EXIF_TAG_EXPOSURE_MODE, EXIF_TYPE_SHORT,
      0, serialize_exposure_mode, deserialize_exposure_mode},
  {GST_TAG_CAPTURING_WHITE_BALANCE, EXIF_TAG_WHITE_BALANCE, EXIF_TYPE_SHORT,
      0, serialize_white_balance, deserialize_white_balance},
  {GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO, EXIF_TAG_DIGITAL_ZOOM_RATIO,
        EXIF_TYPE_RATIONAL, 0, NULL,
      NULL},
  {GST_TAG_CAPTURING_FOCAL_LENGTH_35_MM, EXIF_TAG_FOCAL_LENGTH_IN_35_MM_FILM,
      EXIF_TYPE_SHORT, 0, NULL, NULL},
  {GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, EXIF_TAG_SCENE_CAPTURE_TYPE,
        EXIF_TYPE_SHORT, 0, serialize_scene_capture_type,
      deserialize_scene_capture_type},
  {GST_TAG_CAPTURING_GAIN_ADJUSTMENT, EXIF_TAG_GAIN_CONTROL,
        EXIF_TYPE_SHORT, 0, serialize_gain_control,
      deserialize_gain_control},
  {GST_TAG_CAPTURING_CONTRAST, EXIF_TAG_CONTRAST, EXIF_TYPE_SHORT, 0,
      serialize_contrast, deserialize_contrast},
  {GST_TAG_CAPTURING_SATURATION, EXIF_TAG_SATURATION, EXIF_TYPE_SHORT, 0,
      serialize_saturation, deserialize_saturation},
  {GST_TAG_CAPTURING_SHARPNESS, EXIF_TAG_SHARPNESS, EXIF_TYPE_SHORT, 0,
      serialize_sharpness, deserialize_sharpness},
  {NULL, 0, 0, 0, NULL, NULL}
};

static const GstExifTagMatch tag_map_gps[] = {
  {GST_TAG_GEO_LOCATION_LATITUDE, EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL,
        EXIF_TAG_GPS_LATITUDE_REF,
      serialize_geo_coordinate, deserialize_geo_coordinate},
  {GST_TAG_GEO_LOCATION_LONGITUDE, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL,
        EXIF_TAG_GPS_LONGITUDE_REF,
      serialize_geo_coordinate, deserialize_geo_coordinate},
  {GST_TAG_GEO_LOCATION_ELEVATION, EXIF_TAG_GPS_ALTITUDE, EXIF_TYPE_RATIONAL,
        EXIF_TAG_GPS_ALTITUDE_REF,
      serialize_geo_elevation, deserialize_geo_elevation},
  {GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, EXIF_TAG_GPS_SPEED, EXIF_TYPE_RATIONAL,
        EXIF_TAG_GPS_SPEED_REF,
      serialize_speed, deserialize_speed},
  {GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, EXIF_TAG_GPS_TRACK,
        EXIF_TYPE_RATIONAL, EXIF_TAG_GPS_TRACK_REF,
      serialize_geo_direction, deserialize_geo_direction},
  {GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, EXIF_TAG_GPS_IMAGE_DIRECTION,
        EXIF_TYPE_RATIONAL, EXIF_TAG_GPS_IMAGE_DIRECTION_REF,
      serialize_geo_direction, deserialize_geo_direction},
  {GST_TAG_GEO_LOCATION_HORIZONTAL_ERROR,
        EXIF_TAG_GPS_HORIZONTAL_POSITIONING_ERROR,
      EXIF_TYPE_RATIONAL, 0, NULL, NULL},
  {NULL, 0, 0, 0, NULL, NULL}
};

/* GstExifReader functions */
static void
gst_exif_reader_init (GstExifReader * reader, gint byte_order,
    GstBuffer * buf, guint32 base_offset)
{
  ensure_exif_tags ();

  reader->taglist = gst_tag_list_new_empty ();
  reader->buffer = buf;
  reader->base_offset = base_offset;
  reader->byte_order = byte_order;
  reader->pending_tags = NULL;
  if (reader->byte_order != G_LITTLE_ENDIAN &&
      reader->byte_order != G_BIG_ENDIAN) {
    GST_WARNING ("Unexpected byte order %d, using system default: %d",
        reader->byte_order, G_BYTE_ORDER);
    reader->byte_order = G_BYTE_ORDER;
  }
}

static void
gst_exif_reader_add_pending_tag (GstExifReader * reader, GstExifTagData * data)
{
  GstExifTagData *copy;

  copy = g_slice_new (GstExifTagData);
  memcpy (copy, data, sizeof (GstExifTagData));

  reader->pending_tags = g_slist_prepend (reader->pending_tags, copy);
}

static GstExifTagData *
gst_exif_reader_get_pending_tag (GstExifReader * reader, gint tagid)
{
  GSList *walker;

  for (walker = reader->pending_tags; walker; walker = g_slist_next (walker)) {
    GstExifTagData *data = (GstExifTagData *) walker->data;
    if (data->tag == tagid)
      return data;
  }

  return NULL;
}

static GstTagList *
gst_exif_reader_reset (GstExifReader * reader, gboolean return_taglist)
{
  GstTagList *ret = NULL;
  GSList *walker;

  for (walker = reader->pending_tags; walker; walker = g_slist_next (walker)) {
    GstExifTagData *data = (GstExifTagData *) walker->data;

    g_slice_free (GstExifTagData, data);
  }
  g_slist_free (reader->pending_tags);

  if (return_taglist) {
    ret = reader->taglist;
    reader->taglist = NULL;
  }

  if (reader->taglist) {
    gst_tag_list_unref (reader->taglist);
  }

  return ret;
}

/* GstExifWriter functions */

static void
gst_exif_writer_init (GstExifWriter * writer, gint byte_order)
{
  ensure_exif_tags ();

  gst_byte_writer_init (&writer->tagwriter);
  gst_byte_writer_init (&writer->datawriter);

  writer->byte_order = byte_order;
  writer->tags_total = 0;
  if (writer->byte_order != G_LITTLE_ENDIAN &&
      writer->byte_order != G_BIG_ENDIAN) {
    GST_WARNING ("Unexpected byte order %d, using system default: %d",
        writer->byte_order, G_BYTE_ORDER);
    writer->byte_order = G_BYTE_ORDER;
  }
}

static GstBuffer *
gst_exif_writer_reset_and_get_buffer (GstExifWriter * writer)
{
  GstBuffer *header;
  GstBuffer *data;

  header = gst_byte_writer_reset_and_get_buffer (&writer->tagwriter);
  data = gst_byte_writer_reset_and_get_buffer (&writer->datawriter);

  return gst_buffer_append (header, data);
}

/*
 * Given the exif tag with the passed id, returns the map index of the tag
 * corresponding to it. If use_complementary is true, then the complementary
 * are also used in the search.
 *
 * Returns -1 if not found
 */
static gint
exif_tag_map_find_reverse (guint16 exif_tag, const GstExifTagMatch * tag_map,
    gboolean use_complementary)
{
  gint i;

  for (i = 0; tag_map[i].exif_tag != 0; i++) {
    if (exif_tag == tag_map[i].exif_tag || (use_complementary &&
            exif_tag == tag_map[i].complementary_tag)) {
      return i;
    }
  }
  return -1;
}

static gboolean
gst_tag_list_has_ifd_tags (const GstTagList * taglist,
    const GstExifTagMatch * tag_map)
{
  gint i;

  for (i = 0; tag_map[i].exif_tag != 0; i++) {
    if (tag_map[i].gst_tag == NULL) {
      if (tag_map[i].exif_tag == EXIF_GPS_IFD_TAG &&
          gst_tag_list_has_ifd_tags (taglist, tag_map_gps))
        return TRUE;
      if (tag_map[i].exif_tag == EXIF_IFD_TAG &&
          gst_tag_list_has_ifd_tags (taglist, tag_map_exif))
        return TRUE;
      continue;
    }

    if (gst_tag_list_get_value_index (taglist, tag_map[i].gst_tag, 0)) {
      return TRUE;
    }
  }
  return FALSE;
}

/*
 * Writes the tag entry.
 *
 * The tag entry is the tag id, the tag type,
 * the count and the offset.
 *
 * The offset is the on the amount of data writen so far, as one
 * can't predict the total bytes that the tag entries will take.
 * This means those fields requires being updated later.
 */
static void
gst_exif_writer_write_tag_header (GstExifWriter * writer,
    guint16 exif_tag, guint16 exif_type, guint32 count, guint32 offset,
    const guint32 * offset_data)
{
  gboolean handled = TRUE;

  GST_DEBUG ("Writing tag entry: id %x, type %u, count %u, offset %u",
      exif_tag, exif_type, count, offset);

  if (writer->byte_order == G_LITTLE_ENDIAN) {
    handled &= gst_byte_writer_put_uint16_le (&writer->tagwriter, exif_tag);
    handled &= gst_byte_writer_put_uint16_le (&writer->tagwriter, exif_type);
    handled &= gst_byte_writer_put_uint32_le (&writer->tagwriter, count);
    if (offset_data != NULL) {
      handled &=
          gst_byte_writer_put_data (&writer->tagwriter, (guint8 *) offset_data,
          4);
    } else {
      handled &= gst_byte_writer_put_uint32_le (&writer->tagwriter, offset);
    }
  } else if (writer->byte_order == G_BIG_ENDIAN) {
    handled &= gst_byte_writer_put_uint16_be (&writer->tagwriter, exif_tag);
    handled &= gst_byte_writer_put_uint16_be (&writer->tagwriter, exif_type);
    handled &= gst_byte_writer_put_uint32_be (&writer->tagwriter, count);
    if (offset_data != NULL) {
      handled &=
          gst_byte_writer_put_data (&writer->tagwriter, (guint8 *) offset_data,
          4);
    } else {
      handled &= gst_byte_writer_put_uint32_be (&writer->tagwriter, offset);
    }
  } else {
    g_assert_not_reached ();
  }

  if (G_UNLIKELY (!handled))
    GST_WARNING ("Error writing tag header");

  writer->tags_total++;
}

static void
gst_exif_writer_write_rational_data (GstExifWriter * writer, guint32 frac_n,
    guint32 frac_d)
{
  gboolean handled = TRUE;

  if (writer->byte_order == G_LITTLE_ENDIAN) {
    handled &= gst_byte_writer_put_uint32_le (&writer->datawriter, frac_n);
    handled &= gst_byte_writer_put_uint32_le (&writer->datawriter, frac_d);
  } else {
    handled &= gst_byte_writer_put_uint32_be (&writer->datawriter, frac_n);
    handled &= gst_byte_writer_put_uint32_be (&writer->datawriter, frac_d);
  }

  if (G_UNLIKELY (!handled))
    GST_WARNING ("Error writing rational data");
}

static void
gst_exif_writer_write_signed_rational_data (GstExifWriter * writer,
    gint32 frac_n, gint32 frac_d)
{
  gboolean handled = TRUE;

  if (writer->byte_order == G_LITTLE_ENDIAN) {
    handled &= gst_byte_writer_put_int32_le (&writer->datawriter, frac_n);
    handled &= gst_byte_writer_put_int32_le (&writer->datawriter, frac_d);
  } else {
    handled &= gst_byte_writer_put_int32_be (&writer->datawriter, frac_n);
    handled &= gst_byte_writer_put_int32_be (&writer->datawriter, frac_d);
  }

  if (G_UNLIKELY (!handled))
    GST_WARNING ("Error writing signed rational data");
}

static void
gst_exif_writer_write_rational_tag (GstExifWriter * writer,
    guint16 tag, guint32 frac_n, guint32 frac_d)
{
  guint32 offset = gst_byte_writer_get_size (&writer->datawriter);

  gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_RATIONAL,
      1, offset, NULL);

  gst_exif_writer_write_rational_data (writer, frac_n, frac_d);
}

static void
gst_exif_writer_write_signed_rational_tag (GstExifWriter * writer,
    guint16 tag, gint32 frac_n, gint32 frac_d)
{
  guint32 offset = gst_byte_writer_get_size (&writer->datawriter);

  gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_SRATIONAL,
      1, offset, NULL);

  gst_exif_writer_write_signed_rational_data (writer, frac_n, frac_d);
}

static void
gst_exif_writer_write_rational_tag_from_double (GstExifWriter * writer,
    guint16 tag, gdouble value)
{
  gint frac_n;
  gint frac_d;

  gst_util_double_to_fraction (value, &frac_n, &frac_d);

  gst_exif_writer_write_rational_tag (writer, tag, frac_n, frac_d);
}

static void
gst_exif_writer_write_signed_rational_tag_from_double (GstExifWriter * writer,
    guint16 tag, gdouble value)
{
  gint frac_n;
  gint frac_d;

  gst_util_double_to_fraction (value, &frac_n, &frac_d);

  gst_exif_writer_write_signed_rational_tag (writer, tag, frac_n, frac_d);
}

static void
gst_exif_writer_write_byte_tag (GstExifWriter * writer, guint16 tag,
    guint8 value)
{
  guint32 offset = 0;

  GST_WRITE_UINT8 ((guint8 *) & offset, value);
  gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_BYTE,
      1, offset, &offset);
}

static void
gst_exif_writer_write_short_tag (GstExifWriter * writer, guint16 tag,
    guint16 value)
{
  guint32 offset = 0;

  if (writer->byte_order == G_LITTLE_ENDIAN) {
    GST_WRITE_UINT16_LE ((guint8 *) & offset, value);
  } else {
    GST_WRITE_UINT16_BE ((guint8 *) & offset, value);
  }

  gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_SHORT,
      1, offset, &offset);
}

static void
gst_exif_writer_write_long_tag (GstExifWriter * writer, guint16 tag,
    guint32 value)
{
  guint32 offset = 0;
  if (writer->byte_order == G_LITTLE_ENDIAN) {
    GST_WRITE_UINT32_LE ((guint8 *) & offset, value);
  } else {
    GST_WRITE_UINT32_BE ((guint8 *) & offset, value);
  }

  gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_LONG,
      1, offset, &offset);
}


static void
write_exif_undefined_tag (GstExifWriter * writer, guint16 tag,
    const guint8 * data, gint size)
{
  guint32 offset = 0;

  if (size > 4) {
    /* we only use the data offset here, later we add up the
     * resulting tag headers offset and the base offset */
    offset = gst_byte_writer_get_size (&writer->datawriter);
    gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_UNDEFINED,
        size, offset, NULL);
    if (!gst_byte_writer_put_data (&writer->datawriter, data, size)) {
      GST_WARNING ("Error writing undefined tag");
    }
  } else {
    /* small enough to go in the offset */
    memcpy ((guint8 *) & offset, data, size);
    gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_UNDEFINED,
        size, offset, &offset);
  }
}

static inline gboolean
gst_exif_tag_str_is_ascii (const gchar * str, gsize * length)
{
  gsize len = 0;

  while (*str) {
    if (*str++ & 0x80)
      return FALSE;
    ++len;
  }
  *length = len;
  return TRUE;
}

static void
write_exif_ascii_tag (GstExifWriter * writer, guint16 tag, const gchar * str)
{
  guint32 offset = 0;
  gchar *ascii_str;
  gsize ascii_size;
  GError *error = NULL;

  if (gst_exif_tag_str_is_ascii (str, &ascii_size))
    ascii_str = g_strndup (str, ascii_size);
  else
    ascii_str =
        g_convert (str, -1, "latin1", "utf8", NULL, &ascii_size, &error);

  if (error) {
    GST_WARNING ("Failed to convert exif tag to ascii: 0x%x - %s. Error: %s",
        tag, str, error->message);
    g_error_free (error);
    g_free (ascii_str);
    return;
  }

  /* add the \0 at the end */
  ascii_size++;

  if (ascii_size > 4) {
    /* we only use the data offset here, later we add up the
     * resulting tag headers offset and the base offset */
    offset = gst_byte_writer_get_size (&writer->datawriter);
    gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_ASCII,
        ascii_size, offset, NULL);
    gst_byte_writer_put_string (&writer->datawriter, ascii_str);
  } else {
    /* small enough to go in the offset */
    memcpy ((guint8 *) & offset, ascii_str, ascii_size);
    gst_exif_writer_write_tag_header (writer, tag, EXIF_TYPE_ASCII,
        ascii_size, offset, &offset);
  }

  g_free (ascii_str);
}

static void
write_exif_ascii_tag_from_taglist (GstExifWriter * writer,
    const GstTagList * taglist, const GstExifTagMatch * exiftag)
{
  gchar *str = NULL;
  gboolean cleanup = FALSE;
  const GValue *value;
  gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag);

  if (tag_size != 1) {
    /* FIXME support this by serializing them with a ','? */
    GST_WARNING ("Multiple string tags not supported yet");
    return;
  }

  value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0);

  /* do some conversion if needed */
  switch (G_VALUE_TYPE (value)) {
    case G_TYPE_STRING:
      str = (gchar *) g_value_get_string (value);
      break;
    default:
      if (G_VALUE_TYPE (value) == GST_TYPE_DATE_TIME) {
        GstDateTime *dt = (GstDateTime *) g_value_get_boxed (value);

        if (dt == NULL) {
          GST_WARNING ("NULL datetime received");
          break;
        }

        str = g_strdup_printf ("%04d:%02d:%02d %02d:%02d:%02d",
            gst_date_time_get_year (dt), gst_date_time_get_month (dt),
            gst_date_time_get_day (dt), gst_date_time_get_hour (dt),
            gst_date_time_get_minute (dt), gst_date_time_get_second (dt));

        cleanup = TRUE;
      } else {
        GST_WARNING ("Conversion from %s to ascii string not supported",
            G_VALUE_TYPE_NAME (value));
      }
      break;
  }

  if (str == NULL)
    return;

  write_exif_ascii_tag (writer, exiftag->exif_tag, str);
  if (cleanup)
    g_free (str);
}

static void
write_exif_undefined_tag_from_taglist (GstExifWriter * writer,
    const GstTagList * taglist, const GstExifTagMatch * exiftag)
{
  const GValue *value;
  GstMapInfo info;
  guint8 *data = NULL;
  gsize size = 0;
  gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag);
  GstSample *sample = NULL;
  GstBuffer *buf = NULL;

  if (tag_size != 1) {
    GST_WARNING ("Only the first item in the taglist will be serialized");
    return;
  }

  value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0);

  /* do some conversion if needed */
  switch (G_VALUE_TYPE (value)) {
    case G_TYPE_STRING:
      data = (guint8 *) g_value_get_string (value);
      size = strlen ((gchar *) data);   /* no need to +1, undefined doesn't require it */
      break;
    default:
      if (G_VALUE_TYPE (value) == GST_TYPE_SAMPLE) {
        sample = gst_value_get_sample (value);
        buf = gst_sample_get_buffer (sample);
        if (gst_buffer_map (buf, &info, GST_MAP_READ)) {
          data = info.data;
          size = info.size;
        } else {
          GST_WARNING ("Failed to map buffer for reading");
        }
      } else {
        GST_WARNING ("Conversion from %s to raw data not supported",
            G_VALUE_TYPE_NAME (value));
      }
      break;
  }

  if (size > 0)
    write_exif_undefined_tag (writer, exiftag->exif_tag, data, size);

  if (buf)
    gst_buffer_unmap (buf, &info);
}

static void
write_exif_rational_tag_from_taglist (GstExifWriter * writer,
    const GstTagList * taglist, const GstExifTagMatch * exiftag)
{
  const GValue *value;
  gdouble num = 0;
  gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag);

  if (tag_size != 1) {
    GST_WARNING ("Only the first item in the taglist will be serialized");
    return;
  }

  value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0);

  /* do some conversion if needed */
  switch (G_VALUE_TYPE (value)) {
    case G_TYPE_DOUBLE:
      num = g_value_get_double (value);
      gst_exif_writer_write_rational_tag_from_double (writer, exiftag->exif_tag,
          num);
      break;
    default:
      if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION) {
        gst_exif_writer_write_rational_tag (writer, exiftag->exif_tag,
            gst_value_get_fraction_numerator (value),
            gst_value_get_fraction_denominator (value));
      } else {
        GST_WARNING ("Conversion from %s to rational not supported",
            G_VALUE_TYPE_NAME (value));
      }
      break;
  }
}

static void
write_exif_signed_rational_tag_from_taglist (GstExifWriter * writer,
    const GstTagList * taglist, const GstExifTagMatch * exiftag)
{
  const GValue *value;
  gdouble num = 0;
  gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag);

  if (tag_size != 1) {
    GST_WARNING ("Only the first item in the taglist will be serialized");
    return;
  }

  value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0);

  /* do some conversion if needed */
  switch (G_VALUE_TYPE (value)) {
    case G_TYPE_DOUBLE:
      num = g_value_get_double (value);
      gst_exif_writer_write_signed_rational_tag_from_double (writer,
          exiftag->exif_tag, num);
      break;
    default:
      if (G_VALUE_TYPE (value) == GST_TYPE_FRACTION) {
        gst_exif_writer_write_signed_rational_tag (writer, exiftag->exif_tag,
            gst_value_get_fraction_numerator (value),
            gst_value_get_fraction_denominator (value));
      } else {
        GST_WARNING ("Conversion from %s to signed rational not supported",
            G_VALUE_TYPE_NAME (value));
      }
      break;
  }
}

static void
write_exif_integer_tag_from_taglist (GstExifWriter * writer,
    const GstTagList * taglist, const GstExifTagMatch * exiftag)
{
  const GValue *value;
  guint32 num = 0;
  gint tag_size = gst_tag_list_get_tag_size (taglist, exiftag->gst_tag);

  if (tag_size != 1) {
    GST_WARNING ("Only the first item in the taglist will be serialized");
    return;
  }

  value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0);

  /* do some conversion if needed */
  switch (G_VALUE_TYPE (value)) {
    case G_TYPE_INT:
      num = g_value_get_int (value);
      break;
    case G_TYPE_DOUBLE:
      num = (gint) g_value_get_double (value);
      break;
    default:
      GST_WARNING ("Conversion from %s to int not supported",
          G_VALUE_TYPE_NAME (value));
      break;
  }

  switch (exiftag->exif_type) {
    case EXIF_TYPE_LONG:
      gst_exif_writer_write_long_tag (writer, exiftag->exif_tag, num);
      break;
    case EXIF_TYPE_SHORT:
      gst_exif_writer_write_short_tag (writer, exiftag->exif_tag, num);
      break;
    default:
      break;
  }
}

static void
write_exif_tag_from_taglist (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  GST_DEBUG ("Writing tag %s", exiftag->gst_tag);

  /* check for special handling */
  if (exiftag->serialize) {
    exiftag->serialize (writer, taglist, exiftag);
    return;
  }

  switch (exiftag->exif_type) {
    case EXIF_TYPE_ASCII:
      write_exif_ascii_tag_from_taglist (writer, taglist, exiftag);
      break;
    case EXIF_TYPE_UNDEFINED:
      write_exif_undefined_tag_from_taglist (writer, taglist, exiftag);
      break;
    case EXIF_TYPE_RATIONAL:
      write_exif_rational_tag_from_taglist (writer, taglist, exiftag);
      break;
    case EXIF_TYPE_SRATIONAL:
      write_exif_signed_rational_tag_from_taglist (writer, taglist, exiftag);
      break;
    case EXIF_TYPE_LONG:
    case EXIF_TYPE_SHORT:
      write_exif_integer_tag_from_taglist (writer, taglist, exiftag);
      break;
    default:
      GST_WARNING ("Unhandled tag type %d", exiftag->exif_type);
  }
}

static void
tagdata_copy (GstExifTagData * to, const GstExifTagData * from)
{
  to->tag = from->tag;
  to->tag_type = from->tag_type;
  to->count = from->count;
  to->offset = from->offset;
  to->offset_as_data = from->offset_as_data;
}

static void
gst_exif_tag_rewrite_offsets (GstByteWriter * writer, gint byte_order,
    guint32 offset, gint num_tags, GstByteWriter * inner_ifds_data)
{
  GstByteReader *reader;
  gint i;
  guint16 aux = G_MAXUINT16;
  gboolean handled = TRUE;

  GST_LOG ("Rewriting tag entries offsets");

  reader = (GstByteReader *) writer;

  if (num_tags == -1) {
    if (byte_order == G_LITTLE_ENDIAN) {
      handled &= gst_byte_reader_get_uint16_le (reader, &aux);
    } else {
      handled &= gst_byte_reader_get_uint16_be (reader, &aux);
    }
    if (aux == G_MAXUINT16) {
      GST_WARNING ("Failed to read number of tags, won't rewrite offsets");
      return;
    }
    num_tags = (gint) aux;
  }

  g_return_if_fail (num_tags != -1);

  GST_DEBUG ("number of tags %d", num_tags);

  for (i = 0; i < num_tags; i++) {
    guint16 type = 0;
    guint32 cur_offset = 0;
    gint byte_size = 0;
    guint32 count = 0;
    guint16 tag_id = 0;

    g_assert (gst_byte_writer_get_pos (writer) <
        gst_byte_writer_get_size (writer));

    /* read the type */
    if (byte_order == G_LITTLE_ENDIAN) {
      if (!gst_byte_reader_get_uint16_le (reader, &tag_id))
        break;
      if (!gst_byte_reader_get_uint16_le (reader, &type))
        break;
      if (!gst_byte_reader_get_uint32_le (reader, &count))
        break;
    } else {
      if (!gst_byte_reader_get_uint16_be (reader, &tag_id))
        break;
      if (!gst_byte_reader_get_uint16_be (reader, &type))
        break;
      if (!gst_byte_reader_get_uint32_be (reader, &count))
        break;
    }

    GST_LOG ("Parsed tag %x of type %u and count %u", tag_id, type, count);

    switch (type) {
      case EXIF_TYPE_BYTE:
      case EXIF_TYPE_ASCII:
      case EXIF_TYPE_UNDEFINED:
        byte_size = count;
        break;
      case EXIF_TYPE_SHORT:
        byte_size = count * 2;  /* 2 bytes */
        break;
      case EXIF_TYPE_LONG:
      case EXIF_TYPE_SLONG:
        byte_size = count * 4;  /* 4 bytes */
        break;
      case EXIF_TYPE_RATIONAL:
      case EXIF_TYPE_SRATIONAL:
        byte_size = count * 8;  /* 8 bytes */
        break;
      default:
        g_assert_not_reached ();
        break;
    }

    /* adjust the offset if needed */
    if (byte_size > 4 || tag_id == EXIF_GPS_IFD_TAG || tag_id == EXIF_IFD_TAG) {
      if (byte_order == G_LITTLE_ENDIAN) {
        if (gst_byte_reader_peek_uint32_le (reader, &cur_offset)) {
          handled &=
              gst_byte_writer_put_uint32_le (writer, cur_offset + offset);
        }
      } else {
        if (gst_byte_reader_peek_uint32_be (reader, &cur_offset)) {
          handled &=
              gst_byte_writer_put_uint32_be (writer, cur_offset + offset);
        }
      }
      GST_DEBUG ("Rewriting tag offset from %u to (%u + %u) %u",
          cur_offset, cur_offset, offset, cur_offset + offset);

      if ((tag_id == EXIF_GPS_IFD_TAG || tag_id == EXIF_IFD_TAG) &&
          inner_ifds_data != NULL) {
        /* needs special handling */
        if (!gst_byte_writer_set_pos (inner_ifds_data, cur_offset)) {
          GST_WARNING ("Failed to position writer to rewrite inner ifd "
              "offsets");
          continue;
        }

        gst_exif_tag_rewrite_offsets (inner_ifds_data, byte_order, offset, -1,
            NULL);
      }
    } else {
      handled &= gst_byte_reader_skip (reader, 4);
      GST_DEBUG ("No need to rewrite tag offset");
    }
  }
  if (G_UNLIKELY (!handled))
    GST_WARNING ("Error rewriting offsets");

  GST_LOG ("Done rewriting offsets");
}

static void
parse_exif_ascii_tag (GstExifReader * reader, const GstExifTagMatch * tag,
    guint32 count, guint32 offset, const guint8 * offset_as_data)
{
  GType tagtype;
  gchar *str;
  gchar *utfstr;
  guint32 real_offset;
  GError *error = NULL;

  if (count > 4) {
    GstMapInfo info;

    if (offset < reader->base_offset) {
      GST_WARNING ("Offset is smaller (%u) than base offset (%u)", offset,
          reader->base_offset);
      return;
    }

    real_offset = offset - reader->base_offset;

    if (!gst_buffer_map (reader->buffer, &info, GST_MAP_READ)) {
      GST_WARNING ("Failed to map buffer for reading");
      return;
    }
    if (real_offset >= info.size) {
      GST_WARNING ("Invalid offset %u for buffer of size %" G_GSIZE_FORMAT
          ", not adding tag %s", real_offset, info.size, tag->gst_tag);
      gst_buffer_unmap (reader->buffer, &info);
      return;
    }

    str = g_strndup ((gchar *) (info.data + real_offset), count);
    gst_buffer_unmap (reader->buffer, &info);
  } else {
    str = g_strndup ((gchar *) offset_as_data, count);
  }

  /* convert from ascii to utf8 */
  if (g_utf8_validate (str, -1, NULL)) {
    GST_DEBUG ("Exif string is already on utf8: %s", str);
    utfstr = str;
  } else {
    GST_DEBUG ("Exif string isn't utf8, trying to convert from latin1: %s",
        str);
    utfstr = g_convert (str, count, "utf8", "latin1", NULL, NULL, &error);
    if (error) {
      GST_WARNING ("Skipping tag %d:%s. Failed to convert ascii string "
          "to utf8 : %s - %s", tag->exif_tag, tag->gst_tag, str,
          error->message);
      g_error_free (error);
      g_free (str);
      return;
    }
    g_free (str);
  }

  tagtype = gst_tag_get_type (tag->gst_tag);
  if (tagtype == GST_TYPE_DATE_TIME) {
    gint year = 0, month = 1, day = 1, hour = 0, minute = 0, second = 0;

    if (sscanf (utfstr, "%04d:%02d:%02d %02d:%02d:%02d", &year, &month, &day,
            &hour, &minute, &second) > 0) {
      GstDateTime *d;

      d = gst_date_time_new_local_time (year, month, day, hour, minute, second);
      gst_tag_list_add (reader->taglist, GST_TAG_MERGE_REPLACE,
          tag->gst_tag, d, NULL);
      gst_date_time_unref (d);
    } else {
      GST_WARNING ("Failed to parse %s into a datetime tag", utfstr);
    }
  } else if (tagtype == G_TYPE_STRING) {
    if (utfstr[0] != '\0')
      gst_tag_list_add (reader->taglist, GST_TAG_MERGE_REPLACE, tag->gst_tag,
          utfstr, NULL);
  } else {
    GST_WARNING ("No parsing function associated to %x(%s)", tag->exif_tag,
        tag->gst_tag);
  }
  g_free (utfstr);
}

static void
parse_exif_short_tag (GstExifReader * reader, const GstExifTagMatch * tag,
    guint32 count, guint32 offset, const guint8 * offset_as_data)
{
  GType tagtype;
  guint16 value;

  if (count > 1) {
    GST_WARNING ("Short tags with more than one value are not supported");
    return;
  }

  /* value is encoded into offset */
  if (reader->byte_order == G_LITTLE_ENDIAN)
    value = GST_READ_UINT16_LE (offset_as_data);
  else
    value = GST_READ_UINT16_BE (offset_as_data);

  tagtype = gst_tag_get_type (tag->gst_tag);
  if (tagtype == G_TYPE_INT) {
    gst_tag_list_add (reader->taglist, GST_TAG_MERGE_REPLACE, tag->gst_tag,
        value, NULL);
  } else if (tagtype == G_TYPE_DOUBLE) {
    gst_tag_list_add (reader->taglist, GST_TAG_MERGE_REPLACE, tag->gst_tag,
        (gdouble) value, NULL);
  } else {
    GST_WARNING ("No parsing function associated to %x(%s)", tag->exif_tag,
        tag->gst_tag);
  }
}

static void
parse_exif_long_tag (GstExifReader * reader, const GstExifTagMatch * tag,
    guint32 count, guint32 offset, const guint8 * offset_as_data)
{
  GType tagtype;

  if (count > 1) {
    GST_WARNING ("Long tags with more than one value are not supported");
    return;
  }

  tagtype = gst_tag_get_type (tag->gst_tag);
  if (tagtype == G_TYPE_INT) {
    gst_tag_list_add (reader->taglist, GST_TAG_MERGE_REPLACE, tag->gst_tag,
        offset, NULL);
  } else {
    GST_WARNING ("No parsing function associated to %x(%s)", tag->exif_tag,
        tag->gst_tag);
  }
}


static void
parse_exif_undefined_tag (GstExifReader * reader, const GstExifTagMatch * tag,
    guint32 count, guint32 offset, const guint8 * offset_as_data)
{
  GType tagtype;
  guint8 *data;
  guint32 real_offset;

  if (count > 4) {
    GstMapInfo info;

    if (offset < reader->base_offset) {
      GST_WARNING ("Offset is smaller (%u) than base offset (%u)", offset,
          reader->base_offset);
      return;
    }

    real_offset = offset - reader->base_offset;

    if (!gst_buffer_map (reader->buffer, &info, GST_MAP_READ)) {
      GST_WARNING ("Failed to map buffer for reading");
      return;
    }

    if (real_offset >= info.size) {
      GST_WARNING ("Invalid offset %u for buffer of size %" G_GSIZE_FORMAT
          ", not adding tag %s", real_offset, info.size, tag->gst_tag);
      gst_buffer_unmap (reader->buffer, &info);
      return;
    }

    /* +1 because it could be a string without the \0 */
    data = malloc (sizeof (guint8) * count + 1);
    memcpy (data, info.data + real_offset, count);
    data[count] = 0;

    gst_buffer_unmap (reader->buffer, &info);
  } else {
    data = malloc (sizeof (guint8) * count + 1);
    memcpy (data, (guint8 *) offset_as_data, count);
    data[count] = 0;
  }

  tagtype = gst_tag_get_type (tag->gst_tag);
  if (tagtype == GST_TYPE_SAMPLE) {
    GstSample *sample;
    GstBuffer *buf;

    buf = gst_buffer_new_wrapped (data, count);
    data = NULL;

    sample = gst_sample_new (buf, NULL, NULL, NULL);
    gst_tag_list_add (reader->taglist, GST_TAG_MERGE_APPEND, tag->gst_tag,
        sample, NULL);
    gst_sample_unref (sample);
    gst_buffer_unref (buf);
  } else if (tagtype == G_TYPE_STRING) {
    if (data[0] != '\0')
      gst_tag_list_add (reader->taglist, GST_TAG_MERGE_REPLACE, tag->gst_tag,
          data, NULL);
  } else {
    GST_WARNING ("No parsing function associated to %x(%s)", tag->exif_tag,
        tag->gst_tag);
  }
  g_free (data);
}

static gboolean
exif_reader_read_rational_tag (GstExifReader * exif_reader,
    guint32 count, guint32 offset, gboolean is_signed,
    gint32 * _frac_n, gint32 * _frac_d)
{
  GstByteReader data_reader;
  guint32 real_offset;
  gint32 frac_n = 0;
  gint32 frac_d = 0;
  GstMapInfo info;

  if (count > 1) {
    GST_WARNING ("Rationals with multiple entries are not supported");
  }
  if (offset < exif_reader->base_offset) {
    GST_WARNING ("Offset is smaller (%u) than base offset (%u)", offset,
        exif_reader->base_offset);
    return FALSE;
  }

  real_offset = offset - exif_reader->base_offset;

  if (!gst_buffer_map (exif_reader->buffer, &info, GST_MAP_READ)) {
    GST_WARNING ("Failed to map buffer for reading");
    return FALSE;
  }

  if (real_offset >= info.size) {
    GST_WARNING ("Invalid offset %u for buffer of size %" G_GSIZE_FORMAT,
        real_offset, info.size);
    goto reader_fail;
  }

  gst_byte_reader_init (&data_reader, info.data, info.size);
  if (!gst_byte_reader_set_pos (&data_reader, real_offset))
    goto reader_fail;

  if (!is_signed) {
    guint32 aux_n = 0, aux_d = 0;
    if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
      if (!gst_byte_reader_get_uint32_le (&data_reader, &aux_n) ||
          !gst_byte_reader_get_uint32_le (&data_reader, &aux_d))
        goto reader_fail;
    } else {
      if (!gst_byte_reader_get_uint32_be (&data_reader, &aux_n) ||
          !gst_byte_reader_get_uint32_be (&data_reader, &aux_d))
        goto reader_fail;
    }
    frac_n = (gint32) aux_n;
    frac_d = (gint32) aux_d;
  } else {
    if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
      if (!gst_byte_reader_get_int32_le (&data_reader, &frac_n) ||
          !gst_byte_reader_get_int32_le (&data_reader, &frac_d))
        goto reader_fail;
    } else {
      if (!gst_byte_reader_get_int32_be (&data_reader, &frac_n) ||
          !gst_byte_reader_get_int32_be (&data_reader, &frac_d))
        goto reader_fail;
    }
  }

  if (_frac_n)
    *_frac_n = frac_n;
  if (_frac_d)
    *_frac_d = frac_d;

  gst_buffer_unmap (exif_reader->buffer, &info);

  return TRUE;

reader_fail:
  GST_WARNING ("Failed to read from byte reader. (Buffer too short?)");
  gst_buffer_unmap (exif_reader->buffer, &info);
  return FALSE;
}

static void
parse_exif_rational_tag (GstExifReader * exif_reader,
    const gchar * gst_tag, guint32 count, guint32 offset, gdouble multiplier,
    gboolean is_signed)
{
  GType type;
  gint32 frac_n = 0;
  gint32 frac_d = 1;
  gdouble value;

  GST_DEBUG ("Reading fraction for tag %s...", gst_tag);
  if (!exif_reader_read_rational_tag (exif_reader, count, offset, is_signed,
          &frac_n, &frac_d))
    return;
  GST_DEBUG ("Read fraction for tag %s: %d/%d", gst_tag, frac_n, frac_d);

  type = gst_tag_get_type (gst_tag);
  switch (type) {
    case G_TYPE_DOUBLE:
      gst_util_fraction_to_double (frac_n, frac_d, &value);
      value *= multiplier;
      GST_DEBUG ("Adding %s tag: %lf", gst_tag, value);
      gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_REPLACE, gst_tag,
          value, NULL);
      break;
    default:
      if (type == GST_TYPE_FRACTION) {
        GValue fraction = { 0 };

        g_value_init (&fraction, GST_TYPE_FRACTION);
        gst_value_set_fraction (&fraction, frac_n * multiplier, frac_d);
        gst_tag_list_add_value (exif_reader->taglist, GST_TAG_MERGE_REPLACE,
            gst_tag, &fraction);
        g_value_unset (&fraction);
      } else {
        GST_WARNING ("Can't convert from fraction into %s", g_type_name (type));
      }
  }

}

static GstBuffer *
write_exif_ifd (const GstTagList * taglist, guint byte_order,
    guint32 base_offset, const GstExifTagMatch * tag_map)
{
  GstExifWriter writer;
  gint i;
  gboolean handled = TRUE;

  GST_DEBUG ("Formatting taglist %p as exif buffer. Byte order: %d, "
      "base_offset: %u", taglist, byte_order, base_offset);

  g_assert (byte_order == G_LITTLE_ENDIAN || byte_order == G_BIG_ENDIAN);

  if (!gst_tag_list_has_ifd_tags (taglist, tag_map)) {
    GST_DEBUG ("No tags for this ifd");
    return NULL;
  }

  gst_exif_writer_init (&writer, byte_order);

  /* write tag number as 0 */
  handled &= gst_byte_writer_put_uint16_le (&writer.tagwriter, 0);

  /* write both tag headers and data
   * in ascending id order */

  for (i = 0; tag_map[i].exif_tag != 0; i++) {

    /* special cases have NULL gst tag */
    if (tag_map[i].gst_tag == NULL) {
      GstBuffer *inner_ifd = NULL;
      const GstExifTagMatch *inner_tag_map = NULL;

      GST_LOG ("Inner ifd tag: %x", tag_map[i].exif_tag);

      if (tag_map[i].exif_tag == EXIF_GPS_IFD_TAG) {
        inner_tag_map = tag_map_gps;
      } else if (tag_map[i].exif_tag == EXIF_IFD_TAG) {
        inner_tag_map = tag_map_exif;
      } else if (tag_map[i].exif_tag == EXIF_VERSION_TAG) {
        /* special case where we write the exif version */
        write_exif_undefined_tag (&writer, EXIF_VERSION_TAG, (guint8 *) "0230",
            4);
      } else if (tag_map[i].exif_tag == EXIF_FLASHPIX_VERSION_TAG) {
        /* special case where we write the flashpix version */
        write_exif_undefined_tag (&writer, EXIF_FLASHPIX_VERSION_TAG,
            (guint8 *) "0100", 4);
      }

      if (inner_tag_map) {
        /* base offset and tagheader size are added when rewriting offset */
        inner_ifd = write_exif_ifd (taglist, byte_order,
            gst_byte_writer_get_size (&writer.datawriter), inner_tag_map);
      }

      if (inner_ifd) {
        GstMapInfo info;

        GST_DEBUG ("Adding inner ifd: %x", tag_map[i].exif_tag);
        gst_exif_writer_write_tag_header (&writer, tag_map[i].exif_tag,
            EXIF_TYPE_LONG, 1,
            gst_byte_writer_get_size (&writer.datawriter), NULL);

        if (gst_buffer_map (inner_ifd, &info, GST_MAP_READ)) {
          handled &=
              gst_byte_writer_put_data (&writer.datawriter, info.data,
              info.size);
          gst_buffer_unmap (inner_ifd, &info);
        } else {
          GST_WARNING ("Failed to map buffer for reading");
          handled = FALSE;
        }
        gst_buffer_unref (inner_ifd);
      }
      continue;
    }

    GST_LOG ("Checking tag %s", tag_map[i].gst_tag);
    if (gst_tag_list_get_value_index (taglist, tag_map[i].gst_tag, 0) == NULL)
      continue;

    write_exif_tag_from_taglist (&writer, taglist, &tag_map[i]);
  }

  /* Add the next IFD offset, we just set it to 0 because
   * there is no easy way to predict what it is going to be.
   * The user might rewrite the value if needed */
  handled &= gst_byte_writer_put_uint32_le (&writer.tagwriter, 0);

  /* write the number of tags */
  gst_byte_writer_set_pos (&writer.tagwriter, 0);
  if (writer.byte_order == G_LITTLE_ENDIAN)
    handled &=
        gst_byte_writer_put_uint16_le (&writer.tagwriter, writer.tags_total);
  else
    handled &=
        gst_byte_writer_put_uint16_be (&writer.tagwriter, writer.tags_total);

  GST_DEBUG ("Number of tags rewritten to %d", writer.tags_total);

  /* now that we know the tag headers size, we can add the offsets */
  gst_exif_tag_rewrite_offsets (&writer.tagwriter, writer.byte_order,
      base_offset + gst_byte_writer_get_size (&writer.tagwriter),
      writer.tags_total, &writer.datawriter);

  if (G_UNLIKELY (!handled)) {
    GST_WARNING ("Error rewriting tags");
    gst_buffer_unref (gst_exif_writer_reset_and_get_buffer (&writer));
    return NULL;
  }

  return gst_exif_writer_reset_and_get_buffer (&writer);
}

static gboolean
parse_exif_tag_header (GstByteReader * reader, gint byte_order,
    GstExifTagData * _tagdata)
{
  g_assert (_tagdata);

  /* read the fields */
  if (byte_order == G_LITTLE_ENDIAN) {
    if (!gst_byte_reader_get_uint16_le (reader, &_tagdata->tag) ||
        !gst_byte_reader_get_uint16_le (reader, &_tagdata->tag_type) ||
        !gst_byte_reader_get_uint32_le (reader, &_tagdata->count) ||
        !gst_byte_reader_get_data (reader, 4, &_tagdata->offset_as_data)) {
      return FALSE;
    }
    _tagdata->offset = GST_READ_UINT32_LE (_tagdata->offset_as_data);
  } else {
    if (!gst_byte_reader_get_uint16_be (reader, &_tagdata->tag) ||
        !gst_byte_reader_get_uint16_be (reader, &_tagdata->tag_type) ||
        !gst_byte_reader_get_uint32_be (reader, &_tagdata->count) ||
        !gst_byte_reader_get_data (reader, 4, &_tagdata->offset_as_data)) {
      return FALSE;
    }
    _tagdata->offset = GST_READ_UINT32_BE (_tagdata->offset_as_data);
  }

  return TRUE;
}

static gboolean
parse_exif_ifd (GstExifReader * exif_reader, gint buf_offset,
    const GstExifTagMatch * tag_map)
{
  GstByteReader reader;
  guint16 entries = 0;
  guint16 i;
  GstMapInfo info;

  g_return_val_if_fail (exif_reader->byte_order == G_LITTLE_ENDIAN
      || exif_reader->byte_order == G_BIG_ENDIAN, FALSE);

  if (!gst_buffer_map (exif_reader->buffer, &info, GST_MAP_READ)) {
    GST_WARNING ("Failed to map buffer for reading");
    return FALSE;
  }

  gst_byte_reader_init (&reader, info.data, info.size);
  if (!gst_byte_reader_set_pos (&reader, buf_offset))
    goto invalid_offset;

  /* read the IFD entries number */
  if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
    if (!gst_byte_reader_get_uint16_le (&reader, &entries))
      goto read_error;
  } else {
    if (!gst_byte_reader_get_uint16_be (&reader, &entries))
      goto read_error;
  }
  GST_DEBUG ("Read number of entries: %u", entries);

  /* iterate over the buffer and find the tags and stuff */
  for (i = 0; i < entries; i++) {
    GstExifTagData tagdata;
    gint map_index;

    GST_LOG ("Reading entry: %u", i);

    if (!parse_exif_tag_header (&reader, exif_reader->byte_order, &tagdata))
      goto read_error;

    GST_DEBUG ("Parsed tag: id 0x%x, type %u, count %u, offset %u (0x%x)"
        ", buf size: %u", tagdata.tag, tagdata.tag_type, tagdata.count,
        tagdata.offset, tagdata.offset, gst_byte_reader_get_size (&reader));

    map_index = exif_tag_map_find_reverse (tagdata.tag, tag_map, TRUE);
    if (map_index == -1) {
      GST_WARNING ("Unmapped exif tag: 0x%x", tagdata.tag);
      continue;
    }

    /*
     * inner ifd tags handling, errors processing those are being ignored
     * and we try to continue the parsing
     */
    if (tagdata.tag == EXIF_GPS_IFD_TAG) {
      parse_exif_ifd (exif_reader,
          tagdata.offset - exif_reader->base_offset, tag_map_gps);

      continue;
    }
    if (tagdata.tag == EXIF_IFD_TAG) {
      parse_exif_ifd (exif_reader,
          tagdata.offset - exif_reader->base_offset, tag_map_exif);

      continue;
    }
    if (tagdata.tag == EXIF_VERSION_TAG ||
        tagdata.tag == EXIF_FLASHPIX_VERSION_TAG) {
      /* skip */
      continue;
    }

    /* tags that need specialized deserialization */
    if (tag_map[map_index].deserialize) {
      i += tag_map[map_index].deserialize (exif_reader, &reader,
          &tag_map[map_index], &tagdata);
      continue;
    }

    switch (tagdata.tag_type) {
      case EXIF_TYPE_ASCII:
        parse_exif_ascii_tag (exif_reader, &tag_map[map_index],
            tagdata.count, tagdata.offset, tagdata.offset_as_data);
        break;
      case EXIF_TYPE_RATIONAL:
        parse_exif_rational_tag (exif_reader, tag_map[map_index].gst_tag,
            tagdata.count, tagdata.offset, 1, FALSE);
        break;
      case EXIF_TYPE_SRATIONAL:
        parse_exif_rational_tag (exif_reader, tag_map[map_index].gst_tag,
            tagdata.count, tagdata.offset, 1, TRUE);
        break;
      case EXIF_TYPE_UNDEFINED:
        parse_exif_undefined_tag (exif_reader, &tag_map[map_index],
            tagdata.count, tagdata.offset, tagdata.offset_as_data);
        break;
      case EXIF_TYPE_LONG:
        parse_exif_long_tag (exif_reader, &tag_map[map_index],
            tagdata.count, tagdata.offset, tagdata.offset_as_data);
        break;
      case EXIF_TYPE_SHORT:
        parse_exif_short_tag (exif_reader, &tag_map[map_index],
            tagdata.count, tagdata.offset, tagdata.offset_as_data);
        break;
      default:
        GST_WARNING ("Unhandled tag type: %u", tagdata.tag_type);
        break;
    }
  }

  /* check if the pending tags have something that can still be added */
  {
    GSList *walker;
    GstExifTagData *data;

    for (walker = exif_reader->pending_tags; walker;
        walker = g_slist_next (walker)) {
      data = (GstExifTagData *) walker->data;
      switch (data->tag) {
        case EXIF_TAG_XRESOLUTION:
          parse_exif_rational_tag (exif_reader, GST_TAG_IMAGE_HORIZONTAL_PPI,
              data->count, data->offset, 1, FALSE);
          break;
        case EXIF_TAG_YRESOLUTION:
          parse_exif_rational_tag (exif_reader, GST_TAG_IMAGE_VERTICAL_PPI,
              data->count, data->offset, 1, FALSE);
          break;
        default:
          /* NOP */
          break;
      }
    }
  }
  gst_buffer_unmap (exif_reader->buffer, &info);

  return TRUE;

invalid_offset:
  {
    GST_WARNING ("Buffer offset invalid when parsing exif ifd");
    gst_buffer_unmap (exif_reader->buffer, &info);
    return FALSE;
  }
read_error:
  {
    GST_WARNING ("Failed to parse the exif ifd");
    gst_buffer_unmap (exif_reader->buffer, &info);
    return FALSE;
  }
}

/**
 * gst_tag_list_to_exif_buffer:
 * @taglist: The taglist
 * @byte_order: byte order used in writing (G_LITTLE_ENDIAN or G_BIG_ENDIAN)
 * @base_offset: Offset from the tiff header first byte
 *
 * Formats the tags in taglist on exif format. The resulting buffer contains
 * the tags IFD and is followed by the data pointed by the tag entries.
 *
 * Returns: A GstBuffer containing the tag entries followed by the tag data
 */
GstBuffer *
gst_tag_list_to_exif_buffer (const GstTagList * taglist, gint byte_order,
    guint32 base_offset)
{
  return write_exif_ifd (taglist, byte_order, base_offset, tag_map_ifd0);
}

/**
 * gst_tag_list_to_exif_buffer_with_tiff_header:
 * @taglist: The taglist
 *
 * Formats the tags in taglist into exif structure, a tiff header
 * is put in the beginning of the buffer.
 *
 * Returns: A GstBuffer containing the data
 */
GstBuffer *
gst_tag_list_to_exif_buffer_with_tiff_header (const GstTagList * taglist)
{
  GstBuffer *ifd, *res;
  GstByteWriter writer;
  GstMapInfo info;
  gboolean handled = TRUE;

  ifd = gst_tag_list_to_exif_buffer (taglist, G_BYTE_ORDER, 8);
  if (ifd == NULL) {
    GST_WARNING ("Failed to create exif buffer");
    return NULL;
  }

  if (!gst_buffer_map (ifd, &info, GST_MAP_READ)) {
    GST_WARNING ("Failed to map buffer for reading");
    gst_buffer_unref (ifd);
    return NULL;
  }

  /* TODO what is the correct endianness here? */
  gst_byte_writer_init_with_size (&writer, info.size + TIFF_HEADER_SIZE, FALSE);
  /* TIFF header */
  if (G_BYTE_ORDER == G_LITTLE_ENDIAN) {
    handled &= gst_byte_writer_put_uint16_le (&writer, TIFF_LITTLE_ENDIAN);
    handled &= gst_byte_writer_put_uint16_le (&writer, 42);
    handled &= gst_byte_writer_put_uint32_le (&writer, 8);
  } else {
    handled &= gst_byte_writer_put_uint16_be (&writer, TIFF_BIG_ENDIAN);
    handled &= gst_byte_writer_put_uint16_be (&writer, 42);
    handled &= gst_byte_writer_put_uint32_be (&writer, 8);
  }
  if (!gst_byte_writer_put_data (&writer, info.data, info.size)) {
    GST_WARNING ("Byte writer size mismatch");
    /* reaching here is a programming error because we should have a buffer
     * large enough */
    g_assert_not_reached ();
    gst_buffer_unmap (ifd, &info);
    gst_buffer_unref (ifd);
    gst_byte_writer_reset (&writer);
    return NULL;
  }
  gst_buffer_unmap (ifd, &info);
  gst_buffer_unref (ifd);

  res = gst_byte_writer_reset_and_get_buffer (&writer);

  if (G_UNLIKELY (!handled)) {
    GST_WARNING ("Error creating buffer");
    gst_buffer_unref (res);
    res = NULL;
  }

  return res;
}

/**
 * gst_tag_list_from_exif_buffer:
 * @buffer: The exif buffer
 * @byte_order: byte order of the data
 * @base_offset: Offset from the tiff header to this buffer
 *
 * Parses the IFD and IFD tags data contained in the buffer and puts it
 * on a taglist. The base_offset is used to subtract from the offset in
 * the tag entries and be able to get the offset relative to the buffer
 * start
 *
 * Returns: The parsed taglist
 */
GstTagList *
gst_tag_list_from_exif_buffer (GstBuffer * buffer, gint byte_order,
    guint32 base_offset)
{
  GstExifReader reader;
  g_return_val_if_fail (byte_order == G_LITTLE_ENDIAN
      || byte_order == G_BIG_ENDIAN, NULL);

  gst_exif_reader_init (&reader, byte_order, buffer, base_offset);

  if (!parse_exif_ifd (&reader, 0, tag_map_ifd0))
    goto read_error;

  return gst_exif_reader_reset (&reader, TRUE);

read_error:
  {
    gst_exif_reader_reset (&reader, FALSE);
    GST_WARNING ("Failed to parse the exif buffer");
    return NULL;
  }
}

/**
 * gst_tag_list_from_exif_buffer_with_tiff_header:
 * @buffer: The exif buffer
 *
 * Parses the exif tags starting with a tiff header structure.
 *
 * Returns: The taglist
 */
GstTagList *
gst_tag_list_from_exif_buffer_with_tiff_header (GstBuffer * buffer)
{
  GstByteReader reader;
  guint16 fortytwo = 42;
  guint16 endianness = 0;
  guint32 offset;
  GstTagList *taglist = NULL;
  GstBuffer *subbuffer;
  GstMapInfo info, sinfo;

  if (!gst_buffer_map (buffer, &info, GST_MAP_READ)) {
    GST_WARNING ("Failed to map buffer for reading");
    return NULL;
  }

  GST_LOG ("Parsing exif tags with tiff header of size %" G_GSIZE_FORMAT,
      info.size);

  gst_byte_reader_init (&reader, info.data, info.size);

  GST_LOG ("Parsing the tiff header");
  if (!gst_byte_reader_get_uint16_be (&reader, &endianness)) {
    goto byte_reader_fail;
  }

  if (endianness == TIFF_LITTLE_ENDIAN) {
    if (!gst_byte_reader_get_uint16_le (&reader, &fortytwo) ||
        !gst_byte_reader_get_uint32_le (&reader, &offset))
      goto byte_reader_fail;
  } else if (endianness == TIFF_BIG_ENDIAN) {
    if (!gst_byte_reader_get_uint16_be (&reader, &fortytwo) ||
        !gst_byte_reader_get_uint32_be (&reader, &offset))
      goto byte_reader_fail;
  } else
    goto invalid_endianness;

  if (fortytwo != 42)
    goto invalid_magic;

  subbuffer = gst_buffer_new_and_alloc (info.size - (TIFF_HEADER_SIZE - 2));

  if (!gst_buffer_map (subbuffer, &sinfo, GST_MAP_WRITE))
    goto map_failed;

  memcpy (sinfo.data, info.data + TIFF_HEADER_SIZE,
      info.size - TIFF_HEADER_SIZE);
  gst_buffer_unmap (subbuffer, &sinfo);

  taglist = gst_tag_list_from_exif_buffer (subbuffer,
      endianness == TIFF_LITTLE_ENDIAN ? G_LITTLE_ENDIAN : G_BIG_ENDIAN, 8);

  gst_buffer_unref (subbuffer);

done:
  gst_buffer_unmap (buffer, &info);

  return taglist;

map_failed:
  {
    GST_WARNING ("Failed to map buffer for writing");
    gst_buffer_unref (subbuffer);
    goto done;
  }
byte_reader_fail:
  {
    GST_WARNING ("Failed to read values from buffer");
    goto done;
  }
invalid_endianness:
  {
    GST_WARNING ("Invalid endianness number %u", endianness);
    goto done;
  }
invalid_magic:
  {
    GST_WARNING ("Invalid magic number %u, should be 42", fortytwo);
    goto done;
  }
}

/* special serialization functions */
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (contrast,
    capturing_contrast);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (exposure_mode,
    capturing_exposure_mode);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (exposure_program,
    capturing_exposure_program);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (gain_control,
    capturing_gain_adjustment);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (metering_mode,
    capturing_metering_mode);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (orientation,
    image_orientation);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (saturation,
    capturing_saturation);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (scene_capture_type,
    capturing_scene_capture_type);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (sharpness,
    capturing_sharpness);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (source,
    capturing_source);
EXIF_SERIALIZATION_DESERIALIZATION_MAP_STRING_TO_INT_FUNC (white_balance,
    capturing_white_balance);

static void
serialize_geo_coordinate (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  gboolean latitude;
  gdouble value;
  guint32 degrees;
  guint32 minutes;
  guint32 seconds_numerator, seconds_denominator;
  guint32 offset;

  latitude = exiftag->exif_tag == EXIF_TAG_GPS_LATITUDE;        /* exif tag for latitude */
  if (!gst_tag_list_get_double (taglist, exiftag->gst_tag, &value)) {
    GST_WARNING ("Failed to get double from tag list for tag: %s",
        exiftag->gst_tag);
    return;
  }

  /* first write the Latitude or Longitude Ref */
  if (latitude) {
    if (value >= 0) {
      write_exif_ascii_tag (writer, exiftag->complementary_tag, "N");
    } else {
      value *= -1;
      write_exif_ascii_tag (writer, exiftag->complementary_tag, "S");
    }
  } else {
    if (value >= 0) {
      write_exif_ascii_tag (writer, exiftag->complementary_tag, "E");
    } else {
      value *= -1;
      write_exif_ascii_tag (writer, exiftag->complementary_tag, "W");
    }
  }

  /* now write the degrees stuff */
  GST_DEBUG ("Converting %lf degrees geo location to HMS", value);
  degrees = (guint32) value;
  value -= degrees;
  minutes = (guint32) (value * 60);
  value = (value * 60) - minutes;
  seconds_denominator = 10000000UL;
  seconds_numerator = (guint32) (value * 60 * seconds_denominator);

  GST_DEBUG ("Converted rational geo location to %u/%u %u/%u %u/%u degrees ",
      degrees, 1U, minutes, 1U, seconds_numerator, seconds_denominator);

  offset = gst_byte_writer_get_size (&writer->datawriter);
  gst_exif_writer_write_tag_header (writer, exiftag->exif_tag,
      EXIF_TYPE_RATIONAL, 3, offset, NULL);
  gst_exif_writer_write_rational_data (writer, degrees, 1);
  gst_exif_writer_write_rational_data (writer, minutes, 1);
  gst_exif_writer_write_rational_data (writer, seconds_numerator,
      seconds_denominator);
}

static gint
deserialize_geo_coordinate (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  GstByteReader fractions_reader;
  gint multiplier;
  GstExifTagData next_tagdata;
  gint ret = 0;
  /* for the conversion */
  guint32 degrees_n = 0;
  guint32 degrees_d = 1;
  guint32 minutes_n = 0;
  guint32 minutes_d = 1;
  guint32 seconds_n = 0;
  guint32 seconds_d = 1;
  gdouble degrees;
  gdouble minutes;
  gdouble seconds;
  GstMapInfo info = { NULL };

  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
      exiftag->exif_tag);

  if (exiftag->complementary_tag != tagdata->tag) {
    /* First should come the 'Ref' tags */
    GST_WARNING ("Tag %d is not the 'Ref' tag for latitude nor longitude",
        tagdata->tag);
    return ret;
  }

  if (tagdata->offset_as_data[0] == 'N' || tagdata->offset_as_data[0] == 'E') {
    multiplier = 1;
  } else if (tagdata->offset_as_data[0] == 'S'
      || tagdata->offset_as_data[0] == 'W') {
    multiplier = -1;
  } else {
    GST_WARNING ("Invalid LatitudeRef or LongitudeRef %c",
        tagdata->offset_as_data[0]);
    return ret;
  }

  /* now read the following tag that must be the latitude or longitude */
  if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
    if (!gst_byte_reader_peek_uint16_le (reader, &next_tagdata.tag))
      goto reader_fail;
  } else {
    if (!gst_byte_reader_peek_uint16_be (reader, &next_tagdata.tag))
      goto reader_fail;
  }

  if (exiftag->exif_tag != next_tagdata.tag) {
    GST_WARNING ("This is not a geo coordinate tag");
    return ret;
  }

  /* read the remaining tag entry data */
  if (!parse_exif_tag_header (reader, exif_reader->byte_order, &next_tagdata)) {
    ret = -1;
    goto reader_fail;
  }

  ret = 1;

  /* some checking */
  if (next_tagdata.tag_type != EXIF_TYPE_RATIONAL) {
    GST_WARNING ("Invalid type %d for geo coordinate (latitude/longitude)",
        next_tagdata.tag_type);
    return ret;
  }
  if (next_tagdata.count != 3) {
    GST_WARNING ("Geo coordinate should use 3 fractions, we have %u",
        next_tagdata.count);
    return ret;
  }

  if (!gst_buffer_map (exif_reader->buffer, &info, GST_MAP_READ)) {
    GST_WARNING ("Failed to map buffer for reading");
    return ret;
  }

  /* now parse the fractions */
  gst_byte_reader_init (&fractions_reader, info.data, info.size);

  if (!gst_byte_reader_set_pos (&fractions_reader,
          next_tagdata.offset - exif_reader->base_offset))
    goto reader_fail;

  if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
    if (!gst_byte_reader_get_uint32_le (&fractions_reader, &degrees_n) ||
        !gst_byte_reader_get_uint32_le (&fractions_reader, &degrees_d) ||
        !gst_byte_reader_get_uint32_le (&fractions_reader, &minutes_n) ||
        !gst_byte_reader_get_uint32_le (&fractions_reader, &minutes_d) ||
        !gst_byte_reader_get_uint32_le (&fractions_reader, &seconds_n) ||
        !gst_byte_reader_get_uint32_le (&fractions_reader, &seconds_d))
      goto reader_fail;
  } else {
    if (!gst_byte_reader_get_uint32_be (&fractions_reader, &degrees_n) ||
        !gst_byte_reader_get_uint32_be (&fractions_reader, &degrees_d) ||
        !gst_byte_reader_get_uint32_be (&fractions_reader, &minutes_n) ||
        !gst_byte_reader_get_uint32_be (&fractions_reader, &minutes_d) ||
        !gst_byte_reader_get_uint32_be (&fractions_reader, &seconds_n) ||
        !gst_byte_reader_get_uint32_be (&fractions_reader, &seconds_d))
      goto reader_fail;
  }
  gst_buffer_unmap (exif_reader->buffer, &info);

  GST_DEBUG ("Read degrees fraction for tag %s: %u/%u %u/%u %u/%u",
      exiftag->gst_tag, degrees_n, degrees_d, minutes_n, minutes_d,
      seconds_n, seconds_d);

  gst_util_fraction_to_double (degrees_n, degrees_d, &degrees);
  gst_util_fraction_to_double (minutes_n, minutes_d, &minutes);
  gst_util_fraction_to_double (seconds_n, seconds_d, &seconds);
  minutes += seconds / 60;
  degrees += minutes / 60;
  degrees *= multiplier;

  GST_DEBUG ("Adding %s tag: %lf degrees", exiftag->gst_tag, degrees);
  gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_REPLACE,
      exiftag->gst_tag, degrees, NULL);

  return ret;

reader_fail:
  GST_WARNING ("Failed to read fields from buffer (too short?)");
  if (info.data)
    gst_buffer_unmap (exif_reader->buffer, &info);
  return ret;
}


static void
serialize_geo_direction (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  gdouble value;

  if (!gst_tag_list_get_double (taglist, exiftag->gst_tag, &value)) {
    GST_WARNING ("Failed to get double from tag list for tag: %s",
        exiftag->gst_tag);
    return;
  }

  /* first write the direction ref */
  write_exif_ascii_tag (writer, exiftag->complementary_tag, "T");
  gst_exif_writer_write_rational_tag_from_double (writer,
      exiftag->exif_tag, value);
}

static gint
deserialize_geo_direction (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  GstExifTagData next_tagdata = { 0, };
  gint ret = 0;

  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
      exiftag->exif_tag);

  if (exiftag->complementary_tag == tagdata->tag) {
    /* First should come the 'Ref' tags */
    if (tagdata->offset_as_data[0] == 'M') {
      GST_WARNING ("Magnetic direction is not supported");
      return ret;
    } else if (tagdata->offset_as_data[0] == 'T') {
      /* nop */
    } else {
      GST_WARNING ("Invalid Ref for direction or track %c",
          tagdata->offset_as_data[0]);
      return ret;
    }
  } else {
    GST_DEBUG ("No Direction Ref, using default=T");
    if (tagdata->tag == exiftag->exif_tag) {
      /* this is the main tag */
      tagdata_copy (&next_tagdata, tagdata);
    }
  }

  if (next_tagdata.tag == 0) {
    /* now read the following tag that must be the exif_tag */
    if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
      if (!gst_byte_reader_peek_uint16_le (reader, &next_tagdata.tag))
        goto reader_fail;
    } else {
      if (!gst_byte_reader_peek_uint16_be (reader, &next_tagdata.tag))
        goto reader_fail;
    }

    if (exiftag->exif_tag != next_tagdata.tag) {
      GST_WARNING ("Unexpected tag");
      return ret;
    }

    /* read the remaining tag entry data */
    if (!parse_exif_tag_header (reader, exif_reader->byte_order, &next_tagdata)) {
      ret = -1;
      goto reader_fail;
    }
    ret = 1;
  }

  /* some checking */
  if (next_tagdata.tag_type != EXIF_TYPE_RATIONAL) {
    GST_WARNING ("Invalid type %d for 0x%x", next_tagdata.tag_type,
        next_tagdata.tag);
    return ret;
  }
  if (next_tagdata.count != 1) {
    GST_WARNING ("0x%x tag must have a single fraction, we have %u",
        next_tagdata.tag_type, next_tagdata.count);
    return ret;
  }

  parse_exif_rational_tag (exif_reader,
      exiftag->gst_tag, next_tagdata.count, next_tagdata.offset, 1, FALSE);

  return ret;

reader_fail:
  GST_WARNING ("Failed to read fields from buffer (too short?)");
  return ret;
}


static void
serialize_geo_elevation (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  gdouble value;

  if (!gst_tag_list_get_double (taglist, exiftag->gst_tag, &value)) {
    GST_WARNING ("Failed to get double from tag list for tag: %s",
        exiftag->gst_tag);
    return;
  }

  /* first write the Ref */
  gst_exif_writer_write_byte_tag (writer,
      exiftag->complementary_tag, value >= 0 ? 0 : 1);

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

  /* now the value */
  gst_exif_writer_write_rational_tag_from_double (writer,
      exiftag->exif_tag, value);
}

static gint
deserialize_geo_elevation (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  GstExifTagData next_tagdata = { 0, };
  gint multiplier = 1;
  gint ret = 0;

  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
      exiftag->exif_tag);

  if (exiftag->complementary_tag == tagdata->tag) {
    if (tagdata->offset_as_data[0] == 0) {
      /* NOP */
    } else if (tagdata->offset_as_data[0] == 1) {
      multiplier = -1;
    } else {
      GST_WARNING ("Invalid GPSAltitudeRef %u", tagdata->offset_as_data[0]);
      return ret;
    }
  } else {
    GST_DEBUG ("No GPSAltitudeRef, using default=0");
    if (tagdata->tag == exiftag->exif_tag) {
      tagdata_copy (&next_tagdata, tagdata);
    }
  }

  /* now read the following tag that must be the exif_tag */
  if (next_tagdata.tag == 0) {
    if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
      if (!gst_byte_reader_peek_uint16_le (reader, &next_tagdata.tag))
        goto reader_fail;
    } else {
      if (!gst_byte_reader_peek_uint16_be (reader, &next_tagdata.tag))
        goto reader_fail;
    }

    if (exiftag->exif_tag != next_tagdata.tag) {
      GST_WARNING ("Unexpected tag");
      return ret;
    }

    /* read the remaining tag entry data */
    if (!parse_exif_tag_header (reader, exif_reader->byte_order, &next_tagdata)) {
      ret = -1;
      goto reader_fail;
    }
    ret = 1;
  }

  /* some checking */
  if (next_tagdata.tag_type != EXIF_TYPE_RATIONAL) {
    GST_WARNING ("Invalid type %d for 0x%x", next_tagdata.tag_type,
        next_tagdata.tag);
    return ret;
  }
  if (next_tagdata.count != 1) {
    GST_WARNING ("0x%x tag must have a single fraction, we have %u",
        next_tagdata.tag_type, next_tagdata.count);
    return ret;
  }

  parse_exif_rational_tag (exif_reader,
      exiftag->gst_tag, next_tagdata.count, next_tagdata.offset, multiplier,
      FALSE);

  return ret;

reader_fail:
  GST_WARNING ("Failed to read fields from buffer (too short?)");
  return ret;
}


static void
serialize_speed (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  gdouble value;

  if (!gst_tag_list_get_double (taglist, exiftag->gst_tag, &value)) {
    GST_WARNING ("Failed to get double from tag list for tag: %s",
        exiftag->gst_tag);
    return;
  }

  /* first write the Ref */
  write_exif_ascii_tag (writer, exiftag->complementary_tag, "K");

  /* now the value */
  gst_exif_writer_write_rational_tag_from_double (writer,
      exiftag->exif_tag, value * METERS_PER_SECOND_TO_KILOMETERS_PER_HOUR);
}

static gint
deserialize_speed (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  GstExifTagData next_tagdata = { 0, };
  gdouble multiplier = 1;
  gint ret = 0;

  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
      exiftag->exif_tag);

  if (exiftag->complementary_tag == tagdata->tag) {
    if (tagdata->offset_as_data[0] == 'K') {
      multiplier = KILOMETERS_PER_HOUR_TO_METERS_PER_SECOND;
    } else if (tagdata->offset_as_data[0] == 'M') {
      multiplier = MILES_PER_HOUR_TO_METERS_PER_SECOND;
    } else if (tagdata->offset_as_data[0] == 'N') {
      multiplier = KNOTS_TO_METERS_PER_SECOND;
    } else {
      GST_WARNING ("Invalid GPSSpeedRed %c", tagdata->offset_as_data[0]);
      return ret;
    }
  } else {
    GST_DEBUG ("No GPSSpeedRef, using default=K");
    multiplier = KILOMETERS_PER_HOUR_TO_METERS_PER_SECOND;

    if (tagdata->tag == exiftag->exif_tag) {
      tagdata_copy (&next_tagdata, tagdata);
    }
  }

  /* now read the following tag that must be the exif_tag */
  if (next_tagdata.tag == 0) {
    if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
      if (!gst_byte_reader_peek_uint16_le (reader, &next_tagdata.tag))
        goto reader_fail;
    } else {
      if (!gst_byte_reader_peek_uint16_be (reader, &next_tagdata.tag))
        goto reader_fail;
    }

    if (exiftag->exif_tag != next_tagdata.tag) {
      GST_WARNING ("Unexpected tag");
      return ret;
    }

    /* read the remaining tag entry data */
    if (!parse_exif_tag_header (reader, exif_reader->byte_order, &next_tagdata)) {
      ret = -1;
      goto reader_fail;
    }
    ret = 1;
  }


  /* some checking */
  if (next_tagdata.tag_type != EXIF_TYPE_RATIONAL) {
    GST_WARNING ("Invalid type %d for 0x%x", next_tagdata.tag_type,
        next_tagdata.tag);
    return ret;
  }
  if (next_tagdata.count != 1) {
    GST_WARNING ("0x%x tag must have a single fraction, we have %u",
        next_tagdata.tag_type, next_tagdata.count);
    return ret;
  }

  parse_exif_rational_tag (exif_reader,
      exiftag->gst_tag, next_tagdata.count, next_tagdata.offset, multiplier,
      FALSE);

  return ret;

reader_fail:
  GST_WARNING ("Failed to read fields from buffer (too short?)");
  return ret;
}

static void
serialize_shutter_speed (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  const GValue *value = NULL;
  gdouble num;

  value = gst_tag_list_get_value_index (taglist, exiftag->gst_tag, 0);
  if (!value) {
    GST_WARNING ("Failed to get shutter speed from from tag list");
    return;
  }
  gst_util_fraction_to_double (gst_value_get_fraction_numerator (value),
      gst_value_get_fraction_denominator (value), &num);

#ifdef HAVE_LOG2
  num = -log2 (num);
#else
  num = -log (num) / M_LN2;
#endif

  /* now the value */
  gst_exif_writer_write_signed_rational_tag_from_double (writer,
      exiftag->exif_tag, num);
}

static gint
deserialize_shutter_speed (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  gint32 frac_n, frac_d;
  gdouble d;
  GValue value = { 0 };

  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
      exiftag->exif_tag);

  if (!exif_reader_read_rational_tag (exif_reader, tagdata->count,
          tagdata->offset, TRUE, &frac_n, &frac_d))
    return 0;

  gst_util_fraction_to_double (frac_n, frac_d, &d);
  d = pow (2, -d);
  gst_util_double_to_fraction (d, &frac_n, &frac_d);

  g_value_init (&value, GST_TYPE_FRACTION);
  gst_value_set_fraction (&value, frac_n, frac_d);
  gst_tag_list_add_value (exif_reader->taglist, GST_TAG_MERGE_KEEP,
      exiftag->gst_tag, &value);
  g_value_unset (&value);

  return 0;
}

static void
serialize_aperture_value (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  gdouble num;

  if (!gst_tag_list_get_double_index (taglist, exiftag->gst_tag, 0, &num)) {
    GST_WARNING ("Failed to get focal ratio from from tag list");
    return;
  }
#ifdef HAVE_LOG2
  num = 2 * log2 (num);
#else
  num = 2 * (log (num) / M_LN2);
#endif

  /* now the value */
  gst_exif_writer_write_rational_tag_from_double (writer,
      exiftag->exif_tag, num);
}

static gint
deserialize_aperture_value (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  gint32 frac_n, frac_d;
  gdouble d;

  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
      exiftag->exif_tag);

  if (!exif_reader_read_rational_tag (exif_reader, tagdata->count,
          tagdata->offset, FALSE, &frac_n, &frac_d))
    return 0;

  gst_util_fraction_to_double (frac_n, frac_d, &d);
  d = pow (2, d / 2);

  gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_KEEP,
      exiftag->gst_tag, d, NULL);

  return 0;
}

static void
serialize_sensitivity_type (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  /* we only support ISOSpeed as the sensitivity type (3) */
  gst_exif_writer_write_short_tag (writer, exiftag->exif_tag, 3);
}

static gint
deserialize_sensitivity_type (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  GstExifTagData *sensitivity = NULL;
  guint16 type_data;

  if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
    type_data = GST_READ_UINT16_LE (tagdata->offset_as_data);
  } else {
    type_data = GST_READ_UINT16_BE (tagdata->offset_as_data);
  }

  if (type_data != 3) {
    GST_WARNING ("We only support SensitivityType=3");
    return 0;
  }

  /* check the pending tags for the PhotographicSensitivity tag */
  sensitivity =
      gst_exif_reader_get_pending_tag (exif_reader,
      EXIF_TAG_PHOTOGRAPHIC_SENSITIVITY);
  if (sensitivity == NULL) {
    GST_WARNING ("PhotographicSensitivity tag not found");
    return 0;
  }

  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
      exiftag->exif_tag);

  gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_KEEP,
      GST_TAG_CAPTURING_ISO_SPEED, sensitivity->offset_as_data, NULL);

  return 0;
}

static void
serialize_flash (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  gboolean flash_fired;
  const gchar *flash_mode;
  guint16 tagvalue = 0;

  if (!gst_tag_list_get_boolean_index (taglist, exiftag->gst_tag, 0,
          &flash_fired)) {
    GST_WARNING ("Failed to get flash fired from from tag list");
    return;
  }

  if (flash_fired)
    tagvalue = 1;

  if (gst_tag_list_peek_string_index (taglist, GST_TAG_CAPTURING_FLASH_MODE, 0,
          &flash_mode)) {
    guint16 mode = 0;
    if (strcmp (flash_mode, "auto") == 0) {
      mode = 3;
    } else if (strcmp (flash_mode, "always") == 0) {
      mode = 1;
    } else if (strcmp (flash_mode, "never") == 0) {
      mode = 2;
    }

    tagvalue = tagvalue | (mode << 3);
  } else {
    GST_DEBUG ("flash-mode not available");
  }

  gst_exif_writer_write_short_tag (writer, exiftag->exif_tag, tagvalue);
}

static gint
deserialize_flash (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  guint16 value = 0;
  guint mode = 0;
  const gchar *mode_str = NULL;

  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
      exiftag->exif_tag);

  if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
    value = GST_READ_UINT16_LE (tagdata->offset_as_data);
  } else {
    value = GST_READ_UINT16_BE (tagdata->offset_as_data);
  }

  /* check flash fired */
  if (value & 0x1) {
    gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_REPLACE,
        GST_TAG_CAPTURING_FLASH_FIRED, TRUE, NULL);
  } else {
    gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_REPLACE,
        GST_TAG_CAPTURING_FLASH_FIRED, FALSE, NULL);
  }

  mode = (value >> 3) & 0x3;
  if (mode == 1) {
    mode_str = "always";
  } else if (mode == 2) {
    mode_str = "never";
  } else if (mode == 3) {
    mode_str = "auto";
  }

  if (mode_str)
    gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_REPLACE,
        GST_TAG_CAPTURING_FLASH_MODE, mode_str, NULL);

  return 0;
}

static gint
deserialize_resolution (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  GstExifTagData *xres = NULL;
  GstExifTagData *yres = NULL;
  guint16 unit;
  gdouble multiplier;

  if (exif_reader->byte_order == G_LITTLE_ENDIAN) {
    unit = GST_READ_UINT16_LE (tagdata->offset_as_data);
  } else {
    unit = GST_READ_UINT16_BE (tagdata->offset_as_data);
  }

  switch (unit) {
    case 2:                    /* inch */
      multiplier = 1;
      break;
    case 3:                    /* cm */
      multiplier = 1 / 2.54;
      break;
    default:
      GST_WARNING ("Invalid resolution unit, ignoring PPI tags");
      return 0;
  }

  xres = gst_exif_reader_get_pending_tag (exif_reader, EXIF_TAG_XRESOLUTION);
  if (xres) {
    parse_exif_rational_tag (exif_reader, GST_TAG_IMAGE_HORIZONTAL_PPI,
        xres->count, xres->offset, multiplier, FALSE);
  }
  yres = gst_exif_reader_get_pending_tag (exif_reader, EXIF_TAG_YRESOLUTION);
  if (yres) {
    parse_exif_rational_tag (exif_reader, GST_TAG_IMAGE_VERTICAL_PPI,
        yres->count, yres->offset, multiplier, FALSE);
  }

  return 0;
}

static void
serialize_scene_type (GstExifWriter * writer, const GstTagList * taglist,
    const GstExifTagMatch * exiftag)
{
  const gchar *str;
  guint8 value = 0;

  if (gst_tag_list_peek_string_index (taglist, GST_TAG_CAPTURING_SOURCE, 0,
          &str)) {
    if (strcmp (str, "dsc") == 0) {
      value = 1;
    }
  }

  if (value != 0)
    write_exif_undefined_tag (writer, exiftag->exif_tag, &value, 1);
}

static gint
deserialize_scene_type (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  guint8 value = 0;

  GST_LOG ("Starting to parse %s tag in exif 0x%x", exiftag->gst_tag,
      exiftag->exif_tag);

  value = GST_READ_UINT8 (tagdata->offset_as_data);

  if (value == 1) {
    gst_tag_list_add (exif_reader->taglist, GST_TAG_MERGE_KEEP,
        GST_TAG_CAPTURING_SOURCE, "dsc", NULL);
  }

  return 0;
}

static gint
deserialize_add_to_pending_tags (GstExifReader * exif_reader,
    GstByteReader * reader, const GstExifTagMatch * exiftag,
    GstExifTagData * tagdata)
{
  GST_LOG ("Adding %s tag in exif 0x%x to pending tags", exiftag->gst_tag,
      exiftag->exif_tag);

  /* add it to the pending tags, as we can only parse it when we find the
   * SensitivityType tag */
  gst_exif_reader_add_pending_tag (exif_reader, tagdata);
  return 0;
}

#undef EXIF_SERIALIZATION_FUNC
#undef EXIF_DESERIALIZATION_FUNC
#undef EXIF_SERIALIZATION_DESERIALIZATION_FUNC
