/* 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
 * @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
