示例#1
0
void
exif_content_add_entry (ExifContent * content, ExifEntry * entry)
{
    if (entry->parent)
	return;

    entry->parent = content;
    content->entries = realloc (content->entries,
				sizeof (ExifEntry) * (content->count + 1));
    content->entries[content->count] = entry;
    exif_entry_ref (entry);
    content->count++;
}
示例#2
0
void
exif_content_add_entry (ExifContent *c, ExifEntry *entry)
{
	ExifEntry **entries;
	if (!c || !c->priv || !entry || entry->parent) return;

	
	if (exif_content_get_entry (c, entry->tag)) {
		exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "ExifContent",
			"An attempt has been made to add "
			"the tag '%s' twice to an IFD. This is against "
			"specification.", exif_tag_get_name (entry->tag));
		return;
	}

	entries = exif_mem_realloc (c->priv->mem,
		c->entries, sizeof (ExifEntry*) * (c->count + 1));
	if (!entries) return;
	entry->parent = c;
	entries[c->count++] = entry;
	c->entries = entries;
	exif_entry_ref (entry);
}
示例#3
0
static void
metadatamux_exif_for_each_tag_in_list (const GstTagList * list,
    const gchar * tag, gpointer user_data)
{
  ExifData *ed = (ExifData *) user_data;
  ExifTag exif_tag;
  GType type = G_TYPE_INVALID;
  ExifEntry *entry = NULL;
  ExifIfd ifd = EXIF_IFD_COUNT;
  const ExifByteOrder byte_order = exif_data_get_byte_order (ed);

  exif_tag = metadatamux_exif_get_exif_from_tag (tag, &type, &ifd);

  if (!exif_tag)
    goto done;

  entry = exif_data_get_entry (ed, exif_tag);

  if (entry)
    exif_entry_ref (entry);
  else {
    entry = exif_entry_new ();
    exif_content_add_entry (ed->ifd[ifd], entry);
    exif_entry_initialize (entry, exif_tag);
  }

  if (entry->data == NULL) {
    if (entry->tag == EXIF_TAG_GPS_ALTITUDE) {
      entry->format = EXIF_FORMAT_RATIONAL;
      entry->components = 1;
      entry->size = exif_format_get_size (entry->format) * entry->components;
      entry->data = g_malloc (entry->size);
    } else if (entry->tag == EXIF_TAG_GPS_LATITUDE
        || entry->tag == EXIF_TAG_GPS_LONGITUDE) {
      entry->format = EXIF_FORMAT_RATIONAL;
      entry->components = 3;
      entry->size = exif_format_get_size (entry->format) * entry->components;
      entry->data = g_malloc (entry->size);
    }
  }

  if (type == GST_TYPE_FRACTION) {
    const GValue *gvalue = gst_tag_list_get_value_index (list, tag, 0);
    gint numerator = gst_value_get_fraction_numerator (gvalue);
    gint denominator = gst_value_get_fraction_denominator (gvalue);

    switch (entry->format) {
      case EXIF_FORMAT_SRATIONAL:
      {
        ExifSRational sr = { numerator, denominator };

        exif_set_srational (entry->data, byte_order, sr);
      }
        break;
      case EXIF_FORMAT_RATIONAL:
      {
        ExifRational r;

        if (entry->tag == EXIF_TAG_X_RESOLUTION ||
            entry->tag == EXIF_TAG_Y_RESOLUTION) {
          ExifEntry *unit_entry = NULL;

          unit_entry = exif_data_get_entry (ed, EXIF_TAG_RESOLUTION_UNIT);

          if (unit_entry) {
            ExifShort vsh = exif_get_short (unit_entry->data, byte_order);

            if (vsh != 2)       /* inches */
              exif_set_short (unit_entry->data, byte_order, 2);
          }
        }
        r.numerator = numerator;
        r.denominator = denominator;
        if (numerator < 0)
          r.numerator = -numerator;
        if (denominator < 0)
          r.denominator = -denominator;
        exif_set_rational (entry->data, byte_order, r);
      }
        break;
      default:
        break;
    }
  } else if (type == GST_TYPE_BUFFER) {
    const GValue *val = NULL;
    GstBuffer *buf;

    val = gst_tag_list_get_value_index (list, tag, 0);
    buf = gst_value_get_buffer (val);
    entry->components = GST_BUFFER_SIZE (buf);
    entry->size = GST_BUFFER_SIZE (buf);
    entry->data = g_malloc (entry->size);
    memcpy (entry->data, GST_BUFFER_DATA (buf), entry->size);
  } else {
    switch (type) {
      case G_TYPE_STRING:
      {
        gchar *value = NULL;

        if (gst_tag_list_get_string (list, tag, &value)) {
          if (entry->tag == EXIF_TAG_DATE_TIME_DIGITIZED
              || entry->tag == EXIF_TAG_DATE_TIME
              || entry->tag == EXIF_TAG_DATE_TIME_ORIGINAL) {
            GString *datetime = g_string_new_len (value,
                20);            /* enough memory to hold "YYYY:MM:DD HH:MM:SS" */

            if (metadatamux_exif_convert_from_datetime (datetime)) {
            } else {
              GST_ERROR ("Unexpected date & time format for %s", tag);
            }
            g_free (value);
            value = datetime->str;
            g_string_free (datetime, FALSE);
          } else if (value) {
            entry->components = strlen (value) + 1;
            entry->size =
                exif_format_get_size (entry->format) * entry->components;
            entry->data = (guint8 *) value;
            value = NULL;
          }
        }
      }
        break;
      case G_TYPE_UINT:
      case G_TYPE_INT:
      {
        gint value;
        ExifShort v_short;

        if (G_TYPE_UINT == type) {
          gst_tag_list_get_uint (list, tag, (guint *) & value);
        } else {
          gst_tag_list_get_int (list, tag, &value);
        }

        switch (entry->format) {
          case EXIF_FORMAT_SHORT:
            if (entry->tag == EXIF_TAG_CONTRAST
                || entry->tag == EXIF_TAG_SATURATION) {
              if (value < -33)
                value = 1;      /* low */
              else if (value < 34)
                value = 0;      /* normal */
              else
                value = 2;      /* high */
            }
            v_short = value;
            exif_set_short (entry->data, byte_order, v_short);
            break;
          case EXIF_FORMAT_LONG:
            exif_set_long (entry->data, byte_order, value);
            break;
          default:
            break;
        }

      }
        break;
      case G_TYPE_DOUBLE:
      {
        gdouble value;

        gst_tag_list_get_double (list, tag, &value);
        if (entry->tag == EXIF_TAG_GPS_LATITUDE
            || entry->tag == EXIF_TAG_GPS_LONGITUDE) {
          ExifRational *rt = (ExifRational *) entry->data;
          gdouble v = fabs (value);
          ExifEntry *ref_entry = NULL;
          char ref;
          const ExifTag ref_tag = entry->tag == EXIF_TAG_GPS_LATITUDE ?
              EXIF_TAG_GPS_LATITUDE_REF : EXIF_TAG_GPS_LONGITUDE_REF;

          /* DDD - degrees */
          rt->numerator = (gulong) v;
          rt->denominator = 1;
          GST_DEBUG ("deg: %lf : %lu / %lu", v, (gulong) rt->numerator,
              (gulong) rt->denominator);
          v -= rt->numerator;
          rt++;

          /* MM - minutes */
          rt->numerator = (gulong) (v * 60.0);
          rt->denominator = 1;
          GST_DEBUG ("min: %lf : %lu / %lu", v, (gulong) rt->numerator,
              (gulong) rt->denominator);
          v -= ((gdouble) rt->numerator / 60.0);
          rt++;

          /* SS - seconds */
          rt->numerator = (gulong) (0.5 + v * 3600.0);
          rt->denominator = 1;
          GST_DEBUG ("sec: %lf : %lu / %lu", v, (gulong) rt->numerator,
              (gulong) rt->denominator);

          if (entry->tag == EXIF_TAG_GPS_LONGITUDE) {
            GST_DEBUG ("longitude : %lf", value);
            ref = (value < 0.0) ? 'W' : 'E';
          } else {
            GST_DEBUG ("latitude : %lf", value);
            ref = (value < 0.0) ? 'S' : 'N';
          }

          ref_entry = exif_data_get_entry (ed, ref_tag);
          if (ref_entry) {
            exif_entry_ref (ref_entry);
          } else {
            ref_entry = exif_entry_new ();
            exif_content_add_entry (ed->ifd[EXIF_IFD_GPS], ref_entry);
            exif_entry_initialize (ref_entry, ref_tag);
          }
          if (ref_entry->data == NULL) {
            ref_entry->format = EXIF_FORMAT_ASCII;
            ref_entry->components = 2;
            ref_entry->size = 2;
            ref_entry->data = g_malloc (2);
          }
          ref_entry->data[0] = ref;
          ref_entry->data[1] = 0;
          exif_entry_unref (ref_entry);
        } else if (entry->tag == EXIF_TAG_GPS_ALTITUDE) {
          ExifEntry *ref_entry = NULL;
          ExifRational *rt = (ExifRational *) entry->data;

          rt->numerator = (gulong) fabs (10.0 * value);
          rt->denominator = 10;

          GST_DEBUG ("altitude : %lf", value);

          ref_entry = exif_data_get_entry (ed, EXIF_TAG_GPS_ALTITUDE_REF);
          if (ref_entry) {
            exif_entry_ref (ref_entry);
          } else {
            ref_entry = exif_entry_new ();
            exif_content_add_entry (ed->ifd[EXIF_IFD_GPS], ref_entry);
            exif_entry_initialize (ref_entry, EXIF_TAG_GPS_ALTITUDE_REF);
          }
          if (ref_entry->data == NULL) {
            ref_entry->format = EXIF_FORMAT_BYTE;
            ref_entry->components = 1;
            ref_entry->size = 1;
            ref_entry->data = g_malloc (1);
          }
          if (value > 0.0) {
            ref_entry->data[0] = 0;
          } else {
            ref_entry->data[0] = 1;
          }
          exif_entry_unref (ref_entry);
        }
      }
        break;
      default:
        break;
    }
  }

done:

  if (entry)
    exif_entry_unref (entry);

}