int
main ()
{
	ExifData *d;
	ExifEntry *e;
	char v[1024];
	ExifSRational r = {1., 20.};
	unsigned int i;

	d = exif_data_new ();
	if (!d) {
		printf ("Error running exif_data_new()\n");
		exit(13);
	}

	e = exif_entry_new ();
	if (!e) {
		printf ("Error running exif_entry_new()\n");
		exit(13);
	}

	exif_content_add_entry (d->ifd[EXIF_IFD_0], e);
	exif_entry_initialize (e, EXIF_TAG_SHUTTER_SPEED_VALUE);
	exif_set_srational (e->data, exif_data_get_byte_order (d), r);

	for (i = 30; i > 0; i--) {
		printf ("Length %2i: '%s'\n", i, 
			exif_entry_get_value (e, v, i));
	}

	exif_entry_unref (e);
	exif_data_unref (d);

	return 0;
}
Example #2
0
/* Write a tag. Update what's there, or make a new one.
 */
static void
vips_exif_set_tag( ExifData *ed, int ifd, ExifTag tag, write_fn fn, void *data )
{
	ExifEntry *entry;

	if( (entry = exif_content_get_entry( ed->ifd[ifd], tag )) ) {
		fn( ed, entry, 0, data );
	}
	else {
		entry = exif_entry_new();

		/* tag must be set before calling exif_content_add_entry.
		 */
		entry->tag = tag; 
		exif_content_add_entry( ed->ifd[ifd], entry );
		exif_entry_unref( entry );

		/* libexif makes us have a special path for string-valued
		 * fields :(
		 */
		if( tag_is_encoding( tag ) ) 
			vips_exif_set_string_encoding( ed, entry, 0, data );
		else if( tag_is_ascii( tag ) ) 
			vips_exif_set_string_ascii( ed, entry, 0, data );
		else if( tag_is_utf16( tag ) )
			vips_exif_set_string_utf16( ed, entry, 0, data );
		else {
			exif_entry_initialize( entry, tag );
			fn( ed, entry, 0, data );
		}
	}
}
Example #3
0
/**! If the entry doesn't exist, create it.
 * Based on exif command line action_create_value function in exif 0.6.20
 */
static ExifEntry* my_exif_create_value (ExifData *ed, ExifTag tag, ExifIfd ifd)
{
	ExifEntry *e = exif_content_get_entry (ed->ifd[ifd], tag);
	if ( !e ) {
	    e = exif_entry_new ();
	    exif_content_add_entry (ed->ifd[ifd], e);

		exif_entry_initialize (e, tag);

		// exif_entry_initialize doesn't seem to do much, especially for the GPS tags
		//   so have to setup fields ourselves:
		e->tag = tag;

		if ( tag == EXIF_TAG_GPS_VERSION_ID ) {
			e->format = EXIF_FORMAT_BYTE;
			e->components = 4;
			e->size = sizeof (char) * e->components;
			if ( e->data )
				g_free (e->data);
			e->data = g_malloc (e->size);
		}
		if ( tag == EXIF_TAG_GPS_MAP_DATUM ||
			 tag == EXIF_TAG_GPS_LATITUDE_REF || tag == EXIF_TAG_GPS_LONGITUDE_REF ||
			 tag == EXIF_TAG_GPS_PROCESSING_METHOD ) {
			e->format = EXIF_FORMAT_ASCII;
			// NB Allocation is handled later on when the actual string used is known
		}
		if ( tag == EXIF_TAG_GPS_LATITUDE || tag == EXIF_TAG_GPS_LONGITUDE ) {
			e->format = EXIF_FORMAT_RATIONAL;
			e->components = 3;
			e->size = sizeof (ExifRational) * e->components;
			if ( e->data )
				g_free (e->data);
			e->data = g_malloc (e->size);
		}
		if ( tag == EXIF_TAG_GPS_ALTITUDE ) {
			e->format = EXIF_FORMAT_RATIONAL;
			e->components = 1;
			e->size = sizeof (ExifRational) * e->components;
			if ( e->data )
				g_free (e->data);
			e->data = g_malloc (e->size);
		}
		if ( tag == EXIF_TAG_GPS_ALTITUDE_REF ) {
			e->components = 1;
			e->size = sizeof (char) * e->components;
			if ( e->data )
				g_free (e->data);
			e->data = g_malloc (e->size);
		}
	    /* The entry has been added to the IFD, so we can unref it */
	    //exif_entry_unref(e);
		// Crashes later on, when saving to jpeg if the above unref is enabled!!
		// ?Some other malloc problem somewhere?
	}
	return e;
}
// Create an entry and place it in |exifData|, the entry is default initialized
// by the exif library based on |tag|
static bool createEntry(ExifData* exifData,
                        ExifIfd ifd,
                        int tag) {
    removeExistingEntry(exifData, ifd, tag);
    ExifEntry* entry = exif_entry_new();
    exif_content_add_entry(exifData->ifd[ifd], entry);
    exif_entry_initialize(entry, static_cast<ExifTag>(tag));
    // Unref entry after changing owner to the ExifData struct
    exif_entry_unref(entry);
    return true;
}
Example #5
0
void
exif_content_fix (ExifContent *c)
{
	ExifIfd ifd = exif_content_get_ifd (c);
	ExifDataType dt;
	ExifEntry *e;
	unsigned int i, num;

	if (!c)
		return;

	dt = exif_data_get_data_type (c->parent);

	/*
	 * First of all, fix all existing entries.
	 */
	exif_content_foreach_entry (c, fix_func, NULL);

	/*
	 * Go through each tag and if it's not recorded, remove it. If one
	 * is removed, exif_content_foreach_entry() will skip the next entry,
	 * so if this happens do the loop again from the beginning to ensure
	 * they're all checked. This could be avoided if we stop relying on
	 * exif_content_foreach_entry but loop intelligently here.
	 */
	do {
		num = c->count;
		exif_content_foreach_entry (c, remove_not_recorded, NULL);
	} while (num != c->count);

	/*
	 * Then check for non-existing mandatory tags and create them if needed
	 */
	num = exif_tag_table_count();
	for (i = 0; i < num; ++i) {
		const ExifTag t = exif_tag_table_get_tag (i);
		if (exif_tag_get_support_level_in_ifd (t, ifd, dt) ==
			EXIF_SUPPORT_LEVEL_MANDATORY) {
			if (exif_content_get_entry (c, t))
				/* This tag already exists */
				continue;
			exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content",
					"Tag '%s' is mandatory in IFD '%s' and has therefore been added.",
					exif_tag_get_name_in_ifd (t, ifd), exif_ifd_get_name (ifd));
			e = exif_entry_new ();
			exif_content_add_entry (c, e);
			exif_entry_initialize (e, t);
			exif_entry_unref (e);
		}
	}
}
void exif_entry_set_gps_altitude(ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifRational r1)
{
    ExifEntry *pE;
    ExifByteOrder eO;

    pE = exif_entry_new ();
    exif_content_add_entry (pEdata->ifd[eEifd], pE);
    exif_entry_gps_initialize(pE, eEtag);
    eO = exif_data_get_byte_order (pE->parent->parent);
    if (pE->data) {
        exif_set_rational (pE->data, eO, r1);
    } else {
        printf ("ERROR: unallocated e->data Tag %d\n", eEtag);
    }
    exif_entry_fix (pE);
    exif_entry_unref (pE);
}
Example #7
0
void
exif_content_fix (ExifContent *c)
{
	ExifIfd ifd = exif_content_get_ifd (c);
	ExifDataType dt;
	ExifTag t;
	ExifEntry *e;

	if (!c) return;

	dt = exif_data_get_data_type (c->parent);

	/* First of all, fix all existing entries. */
	exif_content_foreach_entry (c, fix_func, NULL);

	/*
	 * Then check for existing tags that are not allowed and for
	 * non-existing mandatory tags.
	 */
	for (t = 0; t <= 0xffff; t++) {
		switch (exif_tag_get_support_level_in_ifd (t, ifd, dt)) {
		case EXIF_SUPPORT_LEVEL_MANDATORY:
			if (exif_content_get_entry (c, t)) break;
			exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content",
					"Tag '%s' is mandatory in IFD '%s' and has therefore been added.",
					exif_tag_get_name_in_ifd (t, ifd), exif_ifd_get_name (ifd));
			e = exif_entry_new ();
			exif_content_add_entry (c, e);
			exif_entry_initialize (e, t);
			exif_entry_unref (e);
			break;
		case EXIF_SUPPORT_LEVEL_NOT_RECORDED:
			e = exif_content_get_entry (c, t);
			if (!e) break;
			exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content",
					"Tag '%s' is not recoreded in IFD '%s' and has therefore been "
					"removed.", exif_tag_get_name_in_ifd (t, ifd),
					exif_ifd_get_name (ifd));
			exif_content_remove_entry (c, e);
			break;
		case EXIF_SUPPORT_LEVEL_OPTIONAL:
		default:
			break;
		}
	}
}
void  exif_entry_set_byte(ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag,
    ExifByte n)
{
    ExifEntry *pE;
    unsigned char *pData;

    pE = exif_entry_new ();
    exif_content_add_entry (pEdata->ifd[eEifd], pE);
    exif_entry_initialize (pE, eEtag);

    pData = (unsigned char *) (pE->data);
    if (pData) {
      *pData = n;
    } else {
      printf ("ERROR: unallocated e->data Tag %d\n", eEtag);
    }
    exif_entry_fix (pE);
    exif_entry_unref (pE);
}
void exif_entry_set_gps_version(ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifByte r1, ExifByte r2, ExifByte r3, ExifByte r4)
{
    ExifEntry *pE;
    ExifByteOrder eO;

    pE = exif_entry_new ();
    exif_content_add_entry (pEdata->ifd[eEifd], pE);
    exif_entry_gps_initialize(pE, eEtag);
    eO = exif_data_get_byte_order (pE->parent->parent);
    if (pE->data) {
        pE->data[0] = r1;
        pE->data[1] = r2;
        pE->data[2] = r3;
        pE->data[3] = r4;
    } else {
        printf ("ERROR: unallocated e->data Tag %d\n", eEtag);
    }
    exif_entry_fix (pE);
    exif_entry_unref (pE);
}
void exif_entry_set_string (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, const char *s)
{
  ExifEntry *pE;

  pE = exif_entry_new ();
  exif_content_add_entry (pEdata->ifd[eEifd], pE);
  exif_entry_initialize (pE, eEtag);
  if (pE->data)
    free (pE->data);
  pE->components = strlen (s) + 1;
  pE->size = sizeof (char) * pE->components;
  pE->data = (unsigned char *) malloc (pE->size);
  if (!pE->data) {
    printf ("Cannot allocate %d bytes.\nTerminating.\n", (int) pE->size);
    exit (1);
  }
  strcpy ((char *) pE->data, (char *) s);
  exif_entry_fix (pE);
  exif_entry_unref (pE);
}
Example #11
0
/* Write a tag. Update what's there, or make a new one.
 */
static void
write_tag( ExifData *ed, int ifd, ExifTag tag, write_fn fn, void *data )
{
	ExifEntry *entry;

	if( (entry = exif_content_get_entry( ed->ifd[ifd], tag )) ) {
		fn( ed, entry, 0, data );
	}
	else {
		entry = exif_entry_new();

		/* tag must be set before calling exif_content_add_entry.
		 */
		entry->tag = tag; 

		exif_content_add_entry( ed->ifd[ifd], entry );
		exif_entry_initialize( entry, tag );
		exif_entry_unref( entry );

		fn( ed, entry, 0, data );
	}
}
Example #12
0
void
exif_content_fix (ExifContent *c)
{
	ExifIfd ifd = exif_content_get_ifd (c);
	ExifDataType dt;
	ExifEntry *e;
	unsigned int i, num;

	if (!c)
		return;

	dt = exif_data_get_data_type (c->parent);

	exif_content_foreach_entry (c, fix_func, NULL);

	do {
		num = c->count;
		exif_content_foreach_entry (c, remove_not_recorded, NULL);
	} while (num != c->count);

	num = exif_tag_table_count();
	for (i = 0; i < num; ++i) {
		const ExifTag t = exif_tag_table_get_tag (i);
		if (exif_tag_get_support_level_in_ifd (t, ifd, dt) ==
			EXIF_SUPPORT_LEVEL_MANDATORY) {
			if (exif_content_get_entry (c, t))
				
				continue;
			exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content",
					"Tag '%s' is mandatory in IFD '%s' and has therefore been added.",
					exif_tag_get_name_in_ifd (t, ifd), exif_ifd_get_name (ifd));
			e = exif_entry_new ();
			exif_content_add_entry (c, e);
			exif_entry_initialize (e, t);
			exif_entry_unref (e);
		}
	}
}
void exif_entry_set_undefined (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag,
    exif_buffer * buf)
{
    ExifEntry *pE;

    pE = exif_entry_new ();
    exif_content_add_entry (pEdata->ifd[eEifd], pE);
    exif_entry_initialize (pE, eEtag);
    if (buf != NULL) {
        if (pE->data)
            free (pE->data);
        pE->components = buf->size;
        pE->size = buf->size;
        pE->data = (unsigned char *) malloc (pE->size);
        if (!pE->data) {
            printf ("Cannot allocate %d bytes.\nTerminating.\n", (int) pE->size);
            exit (1);
        }
        memcpy ((void *) pE->data, (void *) buf->data, buf->size);
    }
    exif_entry_fix (pE);
    exif_entry_unref (pE);
}
Example #14
0
static int
write_tag( ExifData *ed, ExifTag tag, ExifFormat f, write_fn fn, void *data )
{
	ExifByteOrder bo;
	int found;
	int i;

	bo = exif_data_get_byte_order( ed );

	/* Need to set the tag in all sections which have it :-(
	 */
	found = 0;
	for( i = 0; i < EXIF_IFD_COUNT; i++ ) {
		ExifEntry *entry;

		if( (entry = exif_content_get_entry( ed->ifd[i], tag )) &&
			entry->format == f &&
			entry->components == 1 ) {
			fn( entry, bo, data );
			found = 1;
		}
	}

	if( !found ) {
		/* There was no tag we could update ... make one in ifd[0].
		 */
		ExifEntry *entry;

		entry = exif_entry_new();
		exif_content_add_entry( ed->ifd[0], entry );
		exif_entry_initialize( entry, tag );
		fn( entry, bo, data );
	}

	return( 0 );
}
Example #15
0
void ChatImageItem::downloadOrViewImage()
{
    if (retryButton)
    {
        message.status = FMessage::Uploading;
        retryButton = false;
        setButton();

        emit mediaUpload(message);

    } else if (message.media_wa_type == FMessage::Location)
    {
        QString url = (message.media_url.isEmpty())
                ? URL_LOCATION_SHARING +
                    QString::number(message.latitude) + "," +
                    QString::number(message.longitude) + "+(" +
                    message.notify_name.replace("<","&lt;").replace(">","&gt;") + ")"
                : message.media_url;
        QDesktopServices::openUrl(QUrl(url));
    }
    else if (!message.local_file_uri.isEmpty())
    {
        QString uri = "file://" + message.local_file_uri;

        QDBusConnection dbus = QDBusConnection::sessionBus();


        switch (message.media_wa_type)
        {
            case FMessage::Audio:
                if (message.live)
                {
                    AudioPlayer *player = new AudioPlayer(this);

                    connect(player,SIGNAL(progress(int)),this,SLOT(updateTime(int)));
                    connect(player,SIGNAL(finished()),this,SLOT(finishedAudioPlay()));

                    ui->viewImageButton->setEnabled(false);

                    player->play(uri);

                    // We need to notificate the sender that we played the audio
                    emit voiceNotePlayed(message);
                    break;
                }

            case FMessage::Video:
                {
                    DBusNokiaMediaPlayerIf *mediaPlayerBus =
                            new DBusNokiaMediaPlayerIf(NOKIA_MEDIAPLAYER_DBUS_NAME,
                                                       NOKIA_MEDIAPLAYER_DBUS_PATH,
                                                       dbus,this);

                    mediaPlayerBus->mime_open(uri);
                }
                break;

            case FMessage::Image:
                {
                    // The following is to avoid an Image Viewer bug where files without
                    // EXIF data can't be opened.

                    QImageReader image(message.local_file_uri);

                    if (image.format() == "jpeg")
                    {
                        ExifData *ed = exif_data_new_from_file(message.local_file_uri.toUtf8().constData());

                        if (!ed)
                        {
                            ed = exif_data_new();
                            if (ed)
                            {
                                Utilities::logData("Creating default Exif data.");
                                ExifEntry *entry = exif_entry_new();

                                exif_content_add_entry(ed->ifd[EXIF_IFD_0], entry);

                                exif_entry_initialize(entry, EXIF_TAG_IMAGE_DESCRIPTION);
                                entry->data = (unsigned char *) YAPPARI_APPLICATION_NAME;

                                JPEGData *jpeg = jpeg_data_new_from_file(message.local_file_uri.toUtf8().constData());

                                jpeg_data_set_exif_data(jpeg, ed);

                                jpeg_data_save_file(jpeg, message.local_file_uri.toUtf8().constData());
                                jpeg_data_unref(jpeg);
                            }
                        }

                        if (ed)
                            exif_data_unref(ed);
                    }

                    DBusNokiaImageViewerIf *imageViewerBus =
                    new DBusNokiaImageViewerIf(NOKIA_IMAGEVIEWER_DBUS_NAME,
                                               NOKIA_IMAGEVIEWER_DBUS_PATH,
                                               dbus,this);

                    imageViewerBus->mime_open(uri);
                }
                break;
        }
Example #16
0
static int iExifWriteTag(ExifData* exif, int index, const char* name, int data_type, int attrib_count, const void* attrib_data)
{
  int c;

  ExifTag tag = exif_tag_from_name(name);
  if (tag == 0)
  {
    if (!imStrEqual(name, "GPSVersionID"))  // EXIF_TAG_GPS_VERSION_ID==0
      return 1;
  }

  ExifEntry *entry = exif_entry_new();
  ExifByteOrder byte_order = exif_data_get_byte_order(exif);

  ExifContent *content;
  if (name[0] == 'G' && name[1] == 'P' && name[2] == 'S')
  {
    content = exif->ifd[EXIF_IFD_GPS];      // GPS tags

    if (!iExifGetGPSTagInfo((int)tag, &(entry->format), &(entry->components)))
    {
      exif_entry_free(entry);
      return 1;
    }

  }
  else 
  {
    if (tag > EXIF_TAG_COPYRIGHT)
      content = exif->ifd[EXIF_IFD_EXIF];     // EXIF tags
    else
      content = exif->ifd[EXIF_IFD_0];        // TIFF tags 

    if (!iExifGetTagInfo(tag, &(entry->format), &(entry->components)))
    {
      exif_entry_free(entry);
      return 1;
    }
  }

  int format_size = exif_format_get_size(entry->format);
  if (entry->components == 0)
    entry->components = attrib_count;

  entry->tag = tag;
  entry->size = format_size * entry->components;
  entry->data = (imbyte*)malloc(entry->size);

  if (tag == EXIF_TAG_RESOLUTION_UNIT)
  {
    int res_unit;
    if (imStrEqual((char*)attrib_data, "DPI"))
      res_unit = 2;
    else
      res_unit = 3;

    exif_content_add_entry(content, entry);
    exif_set_short(entry->data, byte_order, (imushort)res_unit);
    return 1;
  }

  /* test if tag type is the same as the attribute type */
  if (iExifGetDataType(entry->format) != data_type)
  {
    exif_entry_free(entry);
    return 1;
  }

  exif_content_add_entry(content, entry);

  switch (entry->format) 
  {
  case EXIF_FORMAT_UNDEFINED:
  case EXIF_FORMAT_ASCII:
  case EXIF_FORMAT_SBYTE:
  case EXIF_FORMAT_BYTE:
    {
      imbyte *bvalue = (imbyte*)attrib_data;
      for (c = 0; c < (int)entry->components; c++) 
        entry->data[c] = bvalue[c];
    }
    break;
  case EXIF_FORMAT_SHORT:
    {
      imushort *usvalue = (imushort*)attrib_data;
      for (c = 0; c < (int)entry->components; c++) 
        exif_set_short(entry->data + format_size * c, byte_order, usvalue[c]);
    }
    break;
  case EXIF_FORMAT_SSHORT:
    {
      short *svalue = (short*)attrib_data;
      for (c = 0; c < (int)entry->components; c++) 
        exif_set_sshort(entry->data + format_size * c, byte_order, svalue[c]);
    }
    break;
  case EXIF_FORMAT_LONG:
    {
      int *ivalue = (int*)attrib_data;
      for (c = 0; c < (int)entry->components; c++) 
        exif_set_long(entry->data + format_size * c, byte_order, (unsigned int)ivalue[c]);
    }
    break;
  case EXIF_FORMAT_SLONG:
    {
      int *ivalue = (int*)attrib_data;
      for (c = 0; c < (int)entry->components; c++) 
        exif_set_slong(entry->data + format_size * c, byte_order, (int)ivalue[c]);
    }
    break;
  case EXIF_FORMAT_RATIONAL:
    {
      ExifRational v_rat;
      int num, den;
      float *fvalue = (float*)attrib_data;
      for (c = 0; c < (int)entry->components; c++) 
      {
        iGetRational(fvalue[c], &num, &den, 1);
        v_rat.numerator = num;
        v_rat.denominator = den;
        exif_set_rational(entry->data + format_size * c, byte_order, v_rat);
      }
    }
    break;
  case EXIF_FORMAT_SRATIONAL:
    {
      ExifSRational v_srat;
      int num, den;
      float *fvalue = (float*)attrib_data;
      for (c = 0; c < (int)entry->components; c++) 
      {
        iGetRational(fvalue[c], &num, &den, 1);
        v_srat.numerator = num;
        v_srat.denominator = den;
        exif_set_srational(entry->data + format_size * c, byte_order, v_srat);
      }
    }
    break;
  case EXIF_FORMAT_FLOAT:   // defined but unsupported in libEXIF
  case EXIF_FORMAT_DOUBLE:  // defined but unsupported in libEXIF
    break;
  }

  /* no need to release the entry here,
     it will be handled internally 
     because we added the entry to the ExifContent */

  (void)index;
  return 1;
}
Example #17
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);

}
Example #18
0
int createEXIF(dc1394featureset_t *xFeatures, ExifData ** pParentEd)
{
    ExifEntry *pE;
    ExifData * pEd;
    int i = !xFeatures->feature[DC1394_FEATURE_WHITE_BALANCE - DC1394_FEATURE_MIN].auto_active;

    ExifSRational xR = {xFeatures->feature[DC1394_FEATURE_BRIGHTNESS - DC1394_FEATURE_MIN].value, xFeatures->feature[DC1394_FEATURE_BRIGHTNESS - DC1394_FEATURE_MIN].max};;

    printf ("Creating EXIF data...\n");
    pEd = exif_data_new ();


    printf ("Adding a Make reference\n");
    pE = exif_entry_new ();
    exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE);
    exif_entry_initialize (pE, EXIF_TAG_MAKE);
    pE->data="AVT";
    exif_entry_unref (pE);

    printf ("Adding a Model reference\n");
    pE = exif_entry_new ();
    exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE);
    exif_entry_initialize (pE, EXIF_TAG_MODEL);
    pE->data="510c";
    exif_entry_unref (pE);

    printf ("Adding a Tag to reference # samples per pixel\n");
    pE = exif_entry_new ();
    exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE);
    exif_entry_initialize (pE, EXIF_TAG_SAMPLES_PER_PIXEL); 
    exif_entry_unref (pE);

    printf ("Adding a White Balance Reference\n");
    pE = exif_entry_new ();
    exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE);
    exif_entry_initialize (pE, EXIF_TAG_WHITE_BALANCE);
    exif_set_short(pE->data, exif_data_get_byte_order (pEd), i);  
    exif_entry_unref (pE);

    
    printf ("Adding a Sharpness Reference\n");
    pE = exif_entry_new ();
    exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE);
    exif_entry_initialize (pE, EXIF_TAG_SHARPNESS);
    exif_set_short(pE->data, exif_data_get_byte_order (pEd), 0);
    exif_entry_unref (pE);

    printf ("Adding a Brightness reference\n");

    
    

    pE = exif_entry_new ();
    exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE);
    exif_entry_initialize (pE, EXIF_TAG_BRIGHTNESS_VALUE);
    exif_set_srational (pE->data, exif_data_get_byte_order (pEd), xR);


    
    
    *pParentEd = pEd;
    printf("Done!\n");

    return 0;
}