Пример #1
0
/* Save an exif value to a string in a way that we can restore. We only bother
 * for the simple formats (that a client might try to change) though.
 *
 * Keep in sync with vips_exif_from_s() below.
 */
static void
vips_exif_to_s( ExifData *ed, ExifEntry *entry, VipsBuf *buf )
{
	unsigned long i;
	int iv;
	ExifRational rv;
	ExifSRational srv;
	char txt[256];

	if( entry->format == EXIF_FORMAT_ASCII )  {
		/* libexif does not null-terminate strings. Copy out and add
		 * the \0 ourselves.
		 */
		int len = VIPS_MIN( 254, entry->size ); 

		memcpy( txt, entry->data, len );
		txt[len] = '\0';
		vips_buf_appendf( buf, "%s ", txt );
	}
	else if( entry->components < 10 &&
		!vips_exif_get_int( ed, entry, 0, &iv ) ) {
		for( i = 0; i < entry->components; i++ ) {
			vips_exif_get_int( ed, entry, i, &iv );
			vips_buf_appendf( buf, "%d ", iv );
		}
	}
	else if( entry->components < 10 &&
		!vips_exif_get_rational( ed, entry, 0, &rv ) ) {
		for( i = 0; i < entry->components; i++ ) {
			vips_exif_get_rational( ed, entry, i, &rv );
			vips_buf_appendf( buf, "%u/%u ", 
				rv.numerator, rv.denominator );
		}
	}
	else if( entry->components < 10 &&
		!vips_exif_get_srational( ed, entry, 0, &srv ) ) {
		for( i = 0; i < entry->components; i++ ) {
			vips_exif_get_srational( ed, entry, i, &srv );
			vips_buf_appendf( buf, "%d/%d ", 
				srv.numerator, srv.denominator );
		}
	}
	else 
		vips_buf_appendf( buf, "%s ", 
			exif_entry_get_value( entry, txt, 256 ) );

	vips_buf_appendf( buf, "(%s, %s, %lu components, %d bytes)", 
		exif_entry_get_value( entry, txt, 256 ),
		exif_format_get_name( entry->format ),
		entry->components,
		entry->size );
}
Пример #2
0
static ExifDataTypeMakerNote
exif_data_get_type_maker_note (ExifData *d)
{
	ExifEntry *e, *em;
	char value[1024];

	if (!d) 
		return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
	
	e = exif_data_get_entry (d, EXIF_TAG_MAKER_NOTE);
	if (!e) 
		return EXIF_DATA_TYPE_MAKER_NOTE_NONE;

	/* Olympus & Nikon & Sanyo */
	if ((e->size >= 8) && ( !memcmp (e->data, "OLYMP", 6) ||
				!memcmp (e->data, "OLYMPUS", 8) ||
				!memcmp (e->data, "SANYO", 6) ||
				!memcmp (e->data, "Nikon", 6)))
		return EXIF_DATA_TYPE_MAKER_NOTE_OLYMPUS;

	em = exif_data_get_entry (d, EXIF_TAG_MAKE);
	if (!em) 
		return EXIF_DATA_TYPE_MAKER_NOTE_NONE;

	/* Canon */
	if (!strcmp (exif_entry_get_value (em, value, sizeof (value)), "Canon"))
		return EXIF_DATA_TYPE_MAKER_NOTE_CANON;

	/* Pentax & some variant of Nikon */
	if ((e->size >= 2) && (e->data[0] == 0x00) && (e->data[1] == 0x1b)) {
		if (!strncasecmp (
			    exif_entry_get_value (em, value, sizeof(value)),
			    "Nikon", 5))
			return EXIF_DATA_TYPE_MAKER_NOTE_NIKON;
		else
			return EXIF_DATA_TYPE_MAKER_NOTE_PENTAX;
	}
	if ((e->size >= 8) && !memcmp (e->data, "AOC", 4)) {
		return EXIF_DATA_TYPE_MAKER_NOTE_PENTAX;
	}
	if ((e->size >= 8) && !memcmp (e->data, "QVC", 4)) {
		return EXIF_DATA_TYPE_MAKER_NOTE_CASIO;
	}
	if ((e->size >= 12) && !memcmp (e->data, "FUJIFILM", 8)) {
		return EXIF_DATA_TYPE_MAKER_NOTE_FUJI;
	}

	return EXIF_DATA_TYPE_MAKER_NOTE_NONE;
}
Пример #3
0
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;
}
Пример #4
0
static int Egetvalue (lua_State *L) { /** entry.value */
  ExifEntry *entry = checkentry(L);
  char buffer[1024];
  exif_entry_get_value(entry, buffer, sizeof(buffer)/sizeof(char));
  lua_pushstring(L, buffer);
  return 1;
}
Пример #5
0
static bool readExif(const char* path, float& shutter)
{
  ExifData* data = exif_data_new_from_file(path);
  if (data == nullptr)
    return false;
  
  ExifEntry *shutterEnt;
  shutterEnt = exif_content_get_entry(data->ifd[EXIF_IFD_EXIF],
                                      EXIF_TAG_EXPOSURE_TIME);
  if(!shutterEnt)
    shutterEnt = exif_content_get_entry(data->ifd[EXIF_IFD_0],
                                        EXIF_TAG_EXPOSURE_TIME);
  if(!shutterEnt)
    shutterEnt = exif_content_get_entry(data->ifd[EXIF_IFD_1],
                                        EXIF_TAG_EXPOSURE_TIME);
  
  if(shutterEnt == NULL){
    fprintf(stderr, "Error: Cannot read photography info.\n");
    exif_data_unref(data);
    return false;
  }
  
  char buf[1024];
  exif_entry_get_value(shutterEnt, buf, sizeof(buf));
  printf("shutter = %s\n", buf);
  
  ExifSRational r;
  r = exif_get_srational(shutterEnt->data, exif_data_get_byte_order(data));
  shutter = (float)r.numerator / (float)r.denominator;
  
  // Close
  exif_data_unref(data);
  return true;
}
Пример #6
0
/**
 * a_geotag_create_waypoint_positioned:
 * @filename: The image file to process
 * @coord:    The location for positioning the Waypoint
 * @name:     Returns a name for the Waypoint (can be NULL)
 *
 * Returns: An allocated Waypoint or NULL if Waypoint could not be generated
 *
 *  Here EXIF processing is used to get non position related information (i.e. just the comment)
 *
 */
VikWaypoint* a_geotag_create_waypoint_positioned ( const gchar *filename, VikCoord coord, gdouble alt, gchar **name )
{
	*name = NULL;
	VikWaypoint *wp = vik_waypoint_new();
	wp->visible = TRUE;
	wp->coord = coord;
	wp->altitude = alt;

	ExifData *ed = exif_data_new_from_file ( filename );

	// Set info from exif values
	if ( ed ) {
		wp->comment = geotag_get_exif_comment ( ed );

		gchar str[128];
		ExifEntry *ee;
		// Name
		ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE);
		if ( ee ) {
			exif_entry_get_value ( ee, str, 128 );
			*name = g_strdup ( str );
		}

		// Finished with EXIF
		exif_data_free ( ed );
	}

	vik_waypoint_set_image ( wp, filename );


	return wp;
}
Пример #7
0
/**
 * a_geotag_get_exif_date_from_file:
 * @filename: The image file to process
 * @has_GPS_info: Returns whether the file has existing GPS information
 *
 * Returns: An allocated string with the date and time in EXIF_DATE_FORMAT, otherwise NULL if some kind of failure
 *
 *  Here EXIF processing is used to get time information
 *
 */
gchar* a_geotag_get_exif_date_from_file ( const gchar *filename, gboolean *has_GPS_info )
{
	gchar* datetime = NULL;

	ExifData *ed = exif_data_new_from_file ( filename );

	// Detect EXIF load failure
	if ( !ed )
		return datetime;

	gchar str[128];
	ExifEntry *ee;

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		datetime = g_strdup ( str );
	}

	// Check GPS Info
	*has_GPS_info = FALSE;
	
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID);
	// Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0"
	if ( ee && ee->components == 4 )
		*has_GPS_info = TRUE;

	exif_data_free ( ed );

	return datetime;
}
Пример #8
0
// get the tag
void get_tag(ExifData* d, ExifIfd ifd, ExifTag tag, char* buf, int len)
{
  ExifEntry *entry = exif_content_get_entry(d->ifd[ifd],tag);
  if (entry) {
    exif_entry_get_value(entry, buf, len);
    right_trim(buf,' ');
  }
}
Пример #9
0
/* get exif data in readable form */
void exif_get_info(ExifData * ed, char *buffer, unsigned int maxsize)
{
  ExifEntry *entry = NULL;
  char buf[64];

  if ( (buffer == NULL) || (maxsize == 0) )
  {
    return;
  }
  else if (ed == NULL)
  {
    snprintf(buffer, (size_t)maxsize, "%s\n", "No Exif data in file.");
    return;
  }
  else if ( ed != NULL )
  {
    /* normal exif tags */
    exif_get_tag(ed, EXIF_IFD_0, EXIF_TAG_MAKE, buffer, maxsize);
    exif_get_tag(ed, EXIF_IFD_0, EXIF_TAG_MODEL, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH, buffer + strlen(buffer), maxsize - strlen(buffer));
    exif_get_tag(ed, EXIF_IFD_EXIF, EXIF_TAG_FLASH_ENERGY, buffer + strlen(buffer), maxsize - strlen(buffer));

    /* vendor specific makernote tags */
    entry = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
    if (entry != NULL) 
    {
                
      if (exif_entry_get_value(entry, buf, sizeof(buf))) 
      {
        exif_trim_spaces(buf);
        
        /* Nikon */                                    
        if ( strcmp(buf, "Nikon") != 0 )
        {
          /* Digital Vari-Program */
          exif_get_mnote_tag(ed, 171, buffer + strlen(buffer), maxsize - strlen(buffer));
          /* Lens */
          exif_get_mnote_tag(ed, 132, buffer + strlen(buffer), maxsize - strlen(buffer));
        }

      }
    }
  }
}
Пример #10
0
/**
 * a_geotag_get_exif_date_from_file:
 * @filename: The image file to process
 * @has_GPS_info: Returns whether the file has existing GPS information
 *
 * Returns: An allocated string with the date and time in EXIF_DATE_FORMAT, otherwise NULL if some kind of failure
 *
 *  Here EXIF processing is used to get time information
 *
 */
gchar* a_geotag_get_exif_date_from_file ( const gchar *filename, gboolean *has_GPS_info )
{
	gchar* datetime = NULL;
	*has_GPS_info = FALSE;

#ifdef HAVE_LIBGEXIV2
	GExiv2Metadata *gemd = gexiv2_metadata_new ();
	if ( gexiv2_metadata_open_path ( gemd, filename, NULL ) ) {
		gdouble lat, lon;
		*has_GPS_info = ( gexiv2_metadata_get_gps_longitude(gemd,&lon) && gexiv2_metadata_get_gps_latitude(gemd,&lat) );

		// Prefer 'Photo' version over 'Image'
		if ( gexiv2_metadata_has_tag ( gemd, "Exif.Photo.DateTimeOriginal" ) )
			datetime = g_strdup ( gexiv2_metadata_get_tag_interpreted_string ( gemd, "Exif.Photo.DateTimeOriginal" ) );
		else
			datetime = g_strdup ( gexiv2_metadata_get_tag_interpreted_string ( gemd, "Exif.Image.DateTimeOriginal" ) );
	}
	metadata_free ( gemd );
#else
#ifdef HAVE_LIBEXIF
	ExifData *ed = exif_data_new_from_file ( filename );

	// Detect EXIF load failure
	if ( !ed )
		return datetime;

	gchar str[128];
	ExifEntry *ee;

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		datetime = g_strdup ( str );
	}

	// Check GPS Info

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID);
	// Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0"
	if ( ee && ee->components == 4 )
		*has_GPS_info = TRUE;

	// Check other basic GPS fields exist too
	// I have encountered some images which have just the EXIF_TAG_GPS_VERSION_ID but nothing else
	// So to confirm check more EXIF GPS TAGS:
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE);
	if ( !ee )
		*has_GPS_info = FALSE;
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE);
	if ( !ee )
		*has_GPS_info = FALSE;

	exif_data_free ( ed );
#endif
#endif
	return datetime;
}
int
exif_mnote_data_canon_identify (const ExifData *ed, const ExifEntry *e)
{
    char value[8];
    ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
    if (!em)
        return 0;
    return !strcmp (exif_entry_get_value (em, value, sizeof (value)), "Canon");
}
Пример #12
0
/* Save an exif value to a string in a way that we can restore. We only bother
 * for the simple formats (that a client might try to change) though.
 *
 * Keep in sync with vips_exif_from_s() in vips2jpeg.
 */
static void
vips_exif_to_s(  ExifData *ed, ExifEntry *entry, VipsBuf *buf )
{
    unsigned long i;
    int iv;
    ExifRational rv;
    ExifSRational srv;
    char txt[256];

    if( entry->format == EXIF_FORMAT_ASCII )
        vips_buf_appendf( buf, "%s ", entry->data );
    else if( entry->components < 10 &&
             !vips_exif_get_int( ed, entry, 0, &iv ) ) {
        for( i = 0; i < entry->components; i++ ) {
            vips_exif_get_int( ed, entry, i, &iv );
            vips_buf_appendf( buf, "%d ", iv );
        }
    }
    else if( entry->components < 10 &&
             !vips_exif_get_rational( ed, entry, 0, &rv ) ) {
        for( i = 0; i < entry->components; i++ ) {
            vips_exif_get_rational( ed, entry, i, &rv );
            vips_buf_appendf( buf, "%u/%u ",
                              rv.numerator, rv.denominator );
        }
    }
    else if( entry->components < 10 &&
             !vips_exif_get_srational( ed, entry, 0, &srv ) ) {
        for( i = 0; i < entry->components; i++ ) {
            vips_exif_get_srational( ed, entry, i, &srv );
            vips_buf_appendf( buf, "%d/%d ",
                              srv.numerator, srv.denominator );
        }
    }
    else
        vips_buf_appendf( buf, "%s ",
                          exif_entry_get_value( entry, txt, 256 ) );

    vips_buf_appendf( buf, "(%s, %s, %lu components, %d bytes)",
                      exif_entry_get_value( entry, txt, 256 ),
                      exif_format_get_name( entry->format ),
                      entry->components,
                      entry->size );
}
Пример #13
0
static struct LatLon get_latlon ( ExifData *ed )
{
	struct LatLon ll = { 0.0, 0.0 };
	const struct LatLon ll0 = { 0.0, 0.0 };

	gchar str[128];
	ExifEntry *ee;
	//
	// Lat & Long is necessary to form a waypoint.
	//
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE);
	if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		return ll0;

	ll.lat = Rational2Double ( ee->data,
							   exif_format_get_size(ee->format),
							   exif_data_get_byte_order(ed) );

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE_REF);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( str[0] == 'S' )
			ll.lat = -ll.lat;
	}

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE);
	if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		return ll0;

	ll.lon = Rational2Double ( ee->data,
							   exif_format_get_size(ee->format),
							   exif_data_get_byte_order(ed) );

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE_REF);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( str[0] == 'W' )
			ll.lon = -ll.lon;
	}

	return ll;
}
Пример #14
0
	std::string Exif::value(std::string tag_name) const {
		ExifEntry *entry;
		ExifTag tag;
		std::string value;
		char raw_value[1024];

		tag = exif_tag_from_name(tag_name.c_str());
		entry = exif_data_get_entry(m_data, tag);
		value = exif_entry_get_value(entry, raw_value, sizeof(raw_value));
		return value;
	}
Пример #15
0
/**
 * eog_exif_data_get_value:
 * @exif_data: pointer to an <structname>ExifData</structname> struct
 * @tag_id: the requested tag's id. See <filename>exif-tag.h</filename>
 * from the libexif package for possible values (e.g. %EXIF_TAG_EXPOSURE_MODE).
 * @buffer: a pre-allocated output buffer
 * @buf_size: size of @buffer
 *
 * Convenience function to extract a string representation of an Exif tag
 * directly from an <structname>ExifData</structname> struct. The string is
 * written into @buffer as far as @buf_size permits.
 *
 * Returns: a pointer to @buffer.
 */
const gchar *
eog_exif_data_get_value (EogExifData *exif_data, gint tag_id, gchar *buffer, guint buf_size)
{
	ExifEntry *exif_entry;
	const gchar *exif_value;

        exif_entry = exif_data_get_entry (exif_data, tag_id);

	buffer[0] = 0;

	exif_value = exif_entry_get_value (exif_entry, buffer, buf_size);

	return exif_value;
}
Пример #16
0
static void
show_entry( ExifEntry *entry, void *client )
{
	char exif_text[256];

	printf( "%s", exif_tag_get_title( entry->tag ) );
        printf( "|" );
	printf( "%s", exif_entry_get_value( entry, exif_text, 256 ) );
        printf( "|" );
	printf( "%s", exif_format_get_name( entry->format ) );
        printf( "|" );
	printf( "%d bytes", entry->size );
        printf( "\n" );
}
Пример #17
0
/**
 * Attempt to get a single comment from the various exif fields
 */
static gchar* geotag_get_exif_comment ( ExifData *ed )
{
	gchar str[128];
	ExifEntry *ee;
	//
	// Try various options to create a comment
	//
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_IMAGE_DESCRIPTION);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		return g_strdup ( str );
	}

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_COMMENT);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		return g_strdup ( str );
	}

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_SUBJECT);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		return g_strdup ( str );
	}

	// Consider using these for existing GPS info??
	//#define EXIF_TAG_GPS_TIME_STAMP        0x0007
	//#define EXIF_TAG_GPS_DATE_STAMP         0x001d
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		return g_strdup ( str );
	}
	
	// Otherwise nothing found
	return NULL;
}
///@todo create a dedicated EXIF class
QString ImageImporter::getEntry(ExifContent* c, ExifTag tag)
{

    QString retval;
    ExifEntry* entry = exif_content_get_entry(c, tag);

    if (entry) {
        const int len = 256;
        char charData[len];
        exif_entry_get_value(entry, charData, len);
        retval = QString(charData);
    }

    return retval;
}
Пример #19
0
/**
 * a_geotag_waypoint_positioned:
 * @filename: The image file to process
 * @coord:    The location for positioning the Waypoint
 * @name:     Returns a name for the Waypoint (can be NULL)
 * @waypoint: An existing waypoint to update (can be NULL to generate a new waypoint)
 *
 * Returns: An allocated waypoint if the input waypoint is NULL,
 *  otherwise the passed in waypoint is updated
 *
 *  Here EXIF processing is used to get non position related information (i.e. just the comment)
 *
 */
VikWaypoint* a_geotag_waypoint_positioned ( const gchar *filename, VikCoord coord, gdouble alt, gchar **name, VikWaypoint *wp )
{
	*name = NULL;
	if ( wp == NULL ) {
		// Need to create waypoint
		wp = vik_waypoint_new();
		wp->visible = TRUE;
	}
	wp->coord = coord;
	wp->altitude = alt;

#ifdef HAVE_LIBGEXIV2
	GExiv2Metadata *gemd = gexiv2_metadata_new ();
	if ( gexiv2_metadata_open_path ( gemd, filename, NULL ) ) {
			wp->comment = geotag_get_exif_comment ( gemd );
			if ( gexiv2_metadata_has_tag ( gemd, "Exif.Image.XPTitle" ) )
				*name = g_strdup ( gexiv2_metadata_get_tag_interpreted_string ( gemd, "Exif.Image.XPTitle" ) );
	}
	metadata_free ( gemd );
#else
#ifdef HAVE_LIBEXIF
	ExifData *ed = exif_data_new_from_file ( filename );

	// Set info from exif values
	if ( ed ) {
		wp->comment = geotag_get_exif_comment ( ed );

		gchar str[128];
		ExifEntry *ee;
		// Name
		ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE);
		if ( ee ) {
			exif_entry_get_value ( ee, str, 128 );
			*name = g_strdup ( str );
		}

		// Finished with EXIF
		exif_data_free ( ed );
	}
#endif
#endif

	vik_waypoint_set_image ( wp, filename );

	return wp;
}
Пример #20
0
static void parse_exif_entry(ExifEntry * e, void *data) {
  MediaScanResult *r = (MediaScanResult *)data;
  const char *key;
  char val[1024];

  // Get orientation
  if (e->tag == 0x112) {
    ExifByteOrder o = exif_data_get_byte_order(e->parent->parent);
    r->image->orientation = exif_get_short(e->data, o);
    LOG_DEBUG("Exif orientation: %d\n", r->image->orientation);
  }

  // Get key and value
  key = exif_tag_get_name_in_ifd(e->tag, exif_entry_get_ifd(e));
  exif_entry_get_value(e, val, sizeof(val));

  LOG_DEBUG("Saving Exif entry: %s: %s\n", key, val);

  tag_add_item(r->_tag, key, (const char *)val);
}
Пример #21
0
/* show given exif tag content */
static void exif_get_tag(ExifData *d, ExifIfd ifd, ExifTag tag, char* buffer, unsigned int maxsize)
{
  char s[MAX_EXIF_DATA];

  if ( (d != NULL) && (buffer != NULL) && (maxsize>0) )
  {
    ExifEntry *entry = exif_content_get_entry(d->ifd[ifd], tag);
    if (entry != NULL) 
    {
      /* Get the contents of the tag in human-readable form */
      exif_entry_get_value(entry, s, maxsize);

      /* Don't bother printing it if it's entirely blank */
      exif_trim_spaces(s);
      if (*s != '\0')
      {
        D(("%s: %s\n", exif_tag_get_name_in_ifd(tag,ifd), s));
        snprintf(buffer, (size_t)maxsize, "%s: %s\n", exif_tag_get_name_in_ifd(tag,ifd), s);
      }
    }
  }
}
Пример #22
0
QString ImageSlideInfo::readExifStringValue(ExifData* pExifData, ExifTag exifTag)
{
    QString exifValueStr;

    if (!pExifData)
        return exifValueStr;

    ExifEntry* pExifEntry = exif_data_get_entry(pExifData, exifTag);
    if (pExifEntry) {
        if (pExifEntry->format == EXIF_FORMAT_ASCII) {
            char* pBuffer = new char[pExifEntry->size];
            memset(pBuffer, '\0', pExifEntry->size);

            exif_entry_get_value(pExifEntry, pBuffer, pExifEntry->size);
            if (strlen(pBuffer) > 0)
                exifValueStr = pBuffer;

            delete[] pBuffer;
        }
    }

    return exifValueStr;
}
Пример #23
0
static void
attach_exif_entry( ExifEntry *entry, IMAGE *im )
{
	char name_text[256];
	VipsBuf name;
	char value_text[256];
	VipsBuf value;
	char exif_value[256];

	vips_buf_init_static( &name, name_text, 256 );
	vips_buf_init_static( &value, value_text, 256 );

	vips_buf_appendf( &name, "exif-%s", exif_tag_get_title( entry->tag ) );
	vips_buf_appendf( &value, "%s (%s, %d bytes)", 
		exif_entry_get_value( entry, exif_value, 256 ),
		exif_format_get_name( entry->format ),
		entry->size );

	/* Can't do anything sensible with the error return.
	 */
	(void) im_meta_set_string( im, 
		vips_buf_all( &name ), vips_buf_all( &value ) );
}
int
exif_mnote_data_olympus_identify (const ExifData *ed, const ExifEntry *e)
{
	int variant = exif_mnote_data_olympus_identify_variant(e->data, e->size);

	if (variant == nikonV0) {
		/* This variant needs some extra checking with the Make */
		char value[5];
		ExifEntry *em = exif_data_get_entry (ed, EXIF_TAG_MAKE);
		variant = unrecognized;

		if (em) {
			const char *v = exif_entry_get_value (em, value, sizeof(value));
			if (v && (!strncmp (v, "Nikon", sizeof(value)) || 
					  !strncmp (v, "NIKON", sizeof(value)) ))
				/* When saved, this variant will be written out like the
				 * alternative nikonV2 form above instead
				 */
				variant = nikonV0;
		}
	}

	return variant;
}
Пример #25
0
static int ypfs_write(const char *path, const char *buf, size_t size, off_t offset,
		      struct fuse_file_info *fi)
{
	char* full_path;
	FILE* logfile;
	int f;
	ExifData *ed;
	ExifEntry *entry;
	(void) fi;
	sqlite3_stmt *stmt;
	int year = -1;
	int month = -1;

#ifdef DEBUG
	if(1){
		FILE *f2 = fopen("/opfs/log2.txt", "a");
		fprintf(f2, "WRITE: %s\n", path);
		fclose(f2);
	}

#endif
	full_path = build_path(path);

	f = fi->fh;

	write(f, buf, size);

	if (offset == 0) {
		logfile = fopen("log.txt", "a");
		ed = exif_data_new_from_file(full_path);
		if (ed) {
			entry = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
			if (entry) {
				char buf[1024];
		        exif_entry_get_value(entry, buf, sizeof(buf));
		        fprintf(logfile, "%s had date %s\n", full_path, buf);
		        buf[4] = 0;
		        buf[7] = 0;
		        year = atoi(buf);
		        month = atoi(buf+5);
			} else {
				fprintf(logfile,"%s had exif data, but no date\n", full_path);
			}
		} else {
			fprintf(logfile,"%s had no exif data\n", full_path);
		}
		exif_data_unref(ed);
		fclose(logfile);

		if ( year == -1 || month == -1) {
			time_t cur_time;
			struct tm * full_time;
			time(&cur_time);
			full_time = localtime(&cur_time);
			if (year == -1)
				year = 1900 + full_time->tm_year;
			if (month == -1)
				month = full_time->tm_mon+1;
		}

		sqlite3_prepare_v2(conn, "insert into pictures values(?, ?, ?, ?)", -1, &stmt, NULL);
		sqlite3_bind_text(stmt, 1, path + last_index_of(path, '/'), -1, SQLITE_TRANSIENT);
		sqlite3_bind_int(stmt, 2, year);
		sqlite3_bind_int(stmt, 3, month);
		sqlite3_bind_int(stmt, 4, CURRENT->uid);
		sqlite3_step(stmt);
		sqlite3_finalize(stmt);

	}
	
	free(full_path);
	return size;
}
Пример #26
0
int64_t
GetImageMetadata(const char *path, char *name)
{
	ExifData *ed;
	ExifEntry *e = NULL;
	ExifLoader *l;
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	FILE *infile;
	int width=0, height=0, thumb=0;
	char make[32], model[64] = {'\0'};
	char b[1024];
	struct stat file;
	int64_t ret;
	image_s *imsrc;
	metadata_t m;
	uint32_t free_flags = 0xFFFFFFFF;
	memset(&m, '\0', sizeof(metadata_t));

	//DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing %s...\n", path);
	if ( stat(path, &file) != 0 )
		return 0;
	strip_ext(name);
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);

	/* MIME hard-coded to JPEG for now, until we add PNG support */
	m.mime = strdup("image/jpeg");

	l = exif_loader_new();
	exif_loader_write_file(l, path);
	ed = exif_loader_get_data(l);
	exif_loader_unref(l);
	if( !ed )
		goto no_exifdata;

	e = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if( e || (e = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_DIGITIZED)) )
	{
		m.date = strdup(exif_entry_get_value(e, b, sizeof(b)));
		if( strlen(m.date) > 10 )
		{
			m.date[4] = '-';
			m.date[7] = '-';
			m.date[10] = 'T';
		}
		else {
			free(m.date);
			m.date = NULL;
		}
	}
	else {
		/* One last effort to get the date from XMP */
		image_get_jpeg_date_xmp(path, &m.date);
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * date: %s\n", m.date);

	e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
	if( e )
	{
		strncpyt(make, exif_entry_get_value(e, b, sizeof(b)), sizeof(make));
		e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
		if( e )
		{
			strncpyt(model, exif_entry_get_value(e, b, sizeof(b)), sizeof(model));
			if( !strcasestr(model, make) )
				snprintf(model, sizeof(model), "%s %s", make, exif_entry_get_value(e, b, sizeof(b)));
			m.creator = escape_tag(trim(model), 1);
		}
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * model: %s\n", model);

	e = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_ORIENTATION);
	if( e )
	{
		int rotate;
		switch( exif_get_short(e->data, exif_data_get_byte_order(ed)) )
		{
		case 3:
			rotate = 180;
			break;
		case 6:
			rotate = 90;
			break;
		case 8:
			rotate = 270;
			break;
		default:
			rotate = 0;
			break;
		}
		if( rotate )
			xasprintf(&m.rotation, "%d", rotate);
	}

	if( ed->size )
	{
		/* We might need to verify that the thumbnail is 160x160 or smaller */
		if( ed->size > 12000 )
		{
			imsrc = image_new_from_jpeg(NULL, 0, (char *)ed->data, ed->size, 1, ROTATE_NONE);
			if( imsrc )
			{
 				if( (imsrc->width <= 160) && (imsrc->height <= 160) )
					thumb = 1;
				image_free(imsrc);
			}
		}
		else
		{
			thumb = 1;
			//- 20130708 Sungmin add
			if(ed->data && ed->size)
			{
				char* art_file;
				if( !thumb_cache_exists(path, &art_file) )
				{
					char cache_dir[MAXPATHLEN];
					strncpyt(cache_dir, art_file, sizeof(cache_dir));
					make_dir(dirname(cache_dir), S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);

					FILE *thumb = fopen(art_file, "wb");
					//DPRINTF(E_WARN, L_METADATA, " * cache_dir: %s\n", cache_dir);
					//DPRINTF(E_WARN, L_METADATA, " * thumbnail: %s\n", art_file);
					if(thumb)
					{
						fwrite(ed->data, 1, ed->size, thumb);
						fclose(thumb);
					}
				}
				free(art_file);
			}
		}
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * thumbnail: %d\n", thumb);

	exif_data_unref(ed);

no_exifdata:
	/* If SOF parsing fails, then fall through to reading the JPEG data with libjpeg to get the resolution */
	if( image_get_jpeg_resolution(path, &width, &height) != 0 || !width || !height )
	{
		infile = fopen(path, "r");
		if( infile )
		{
			cinfo.err = jpeg_std_error(&jerr);
			jerr.error_exit = libjpeg_error_handler;
			jpeg_create_decompress(&cinfo);
			if( setjmp(setjmp_buffer) )
				goto error;
			jpeg_stdio_src(&cinfo, infile);
			jpeg_read_header(&cinfo, TRUE);
			jpeg_start_decompress(&cinfo);
			width = cinfo.output_width;
			height = cinfo.output_height;
			error:
			jpeg_destroy_decompress(&cinfo);
			fclose(infile);
		}
	}
	//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * resolution: %dx%d\n", width, height);

	if( !width || !height )
	{
		free_metadata(&m, free_flags);
		return 0;
	}
	if( width <= 640 && height <= 480 )
		m.dlna_pn = strdup("JPEG_SM");
	else if( width <= 1024 && height <= 768 )
		m.dlna_pn = strdup("JPEG_MED");
	else if( (width <= 4096 && height <= 4096) || !GETFLAG(DLNA_STRICT_MASK) )
		m.dlna_pn = strdup("JPEG_LRG");
	xasprintf(&m.resolution, "%dx%d", width, height);

	ret = sql_exec(db, "INSERT into DETAILS"
	                   " (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION,"
	                    " ROTATION, THUMBNAIL, CREATOR, DLNA_PN, MIME) "
	                   "VALUES"
	                   " (%Q, '%q', %lld, %ld, %Q, %Q, %Q, %d, %Q, %Q, %Q);",
	                   path, name, (long long)file.st_size, file.st_mtime, m.date, m.resolution,
	                   m.rotation, thumb, m.creator, m.dlna_pn, m.mime);
	if( ret != SQLITE_OK )
	{
		fprintf(stderr, "Error inserting details for '%s'!\n", path);
		ret = 0;
	}
	else
	{
		ret = sqlite3_last_insert_rowid(db);
	}
	free_metadata(&m, free_flags);

	return ret;
}
Пример #27
0
QDateTime GalleryUtil::GetTimestamp(const QString &filePath)
{
    QDateTime timestamp;

    try
    {
#ifdef EXIF_SUPPORT
#if NEW_LIB_EXIF
        char *exifvalue = new char[20];
#endif
        ExifData *data = exif_data_new_from_file(
            filePath.toLocal8Bit().constData());
        if (data)
        {
            for (int i = 0; i < EXIF_IFD_COUNT; i++)
            {
                ExifEntry *entry = exif_content_get_entry (data->ifd[i],
                    EXIF_TAG_DATE_TIME_ORIGINAL);
                if (entry)
                {
#if NEW_LIB_EXIF
                    exif_entry_get_value(entry, exifvalue, 20);
                    QString formatted = exifvalue;
#else
                    QString formatted = exif_entry_get_value(entry);
#endif
                    timestamp = QDateTime::fromString(formatted,
                        "yyyy:MM:dd hh:mm:ss");
                    if (timestamp.isValid())
                    {
                        // Found one, done
                        break;
                    }
                    else
                    {
                        LOG(VB_FILE, LOG_ERR, LOC +
                            QString("Could not parse exif timestamp from '%1'")
                            .arg(filePath));
                    }
                }
            }
            exif_data_free(data);
        }
        else
        {
           LOG(VB_FILE, LOG_ERR, LOC +
               QString("Could not load exif data from '%1'") .arg(filePath));
        }
#if NEW_LIB_EXIF
        delete [] exifvalue;
#endif
#endif // EXIF_SUPPORT
    }
    catch (...)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            QString("Failed to extract EXIF headers from '%1'") .arg(filePath));
    }

    return timestamp;
}
Пример #28
0
QString GalleryUtil::GetCaption(const QString &filePath)
{
    QString caption("");

    try
    {
#ifdef EXIF_SUPPORT
#if NEW_LIB_EXIF
        char *exifvalue = new char[1024];
#endif
        ExifData *data = exif_data_new_from_file(
            filePath.toLocal8Bit().constData());
        if (data)
        {
            for (int i = 0; i < EXIF_IFD_COUNT; i++)
            {
                ExifEntry *entry = exif_content_get_entry (data->ifd[i],
                                                    EXIF_TAG_USER_COMMENT);
                if (entry)
                {
#if NEW_LIB_EXIF
                    exif_entry_get_value(entry, exifvalue, 1024);
                    caption = exifvalue;
#else
                    caption = exif_entry_get_value(entry);
#endif
                    // Found one, done
                    if(!caption.trimmed().isEmpty())
                       break;
                }

                entry = exif_content_get_entry (data->ifd[i],
                                                EXIF_TAG_IMAGE_DESCRIPTION);
                if (entry)
                {
#if NEW_LIB_EXIF
                    exif_entry_get_value(entry, exifvalue, 1024);
                    caption = exifvalue;
#else
                    caption = exif_entry_get_value(entry);
#endif
                    // Found one, done
                    if(!caption.trimmed().isEmpty())
                       break;
                }
            }
            exif_data_free(data);
        }
        else
        {
           LOG(VB_FILE, LOG_ERR, LOC +
               QString("Could not load exif data from '%1'") .arg(filePath));
        }
#if NEW_LIB_EXIF
        delete [] exifvalue;
#endif
#endif // EXIF_SUPPORT
    }
    catch (...)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            QString("Failed to extract EXIF headers from '%1'") .arg(filePath));
    }

    return caption;
}
Пример #29
0
GstTagList *
gst_droidcamsrc_exif_tags_from_jpeg_data (void *data, size_t size)
{
  GstTagList *tags = NULL;
  ExifMem *mem = exif_mem_new (g_malloc0, g_realloc, g_free);
  ExifData *exif = exif_data_new_mem (mem);
  unsigned char *exif_data = NULL;
  void *_exif_data = NULL;
  unsigned int exif_data_size = 0;
  GstBuffer *buffer;
  ExifEntry *iso;
  int x, i;

  exif_data_load_data (exif, data, size);
  exif_data_set_data_type (exif, EXIF_DATA_TYPE_COMPRESSED);

  exif_data_save_data (exif, &exif_data, &exif_data_size);
  if (!exif_data_size) {
    goto out;
  }

  if (exif_data_size <= 6) {
    goto out;
  }

  /* dump the data. based on libexif code */
  for (x = 0; x < EXIF_IFD_COUNT; x++) {
    if (exif->ifd[x] && exif->ifd[x]->count) {
      for (i = 0; i < exif->ifd[x]->count; i++) {
        char val[1024];
        ExifEntry *e = exif->ifd[x]->entries[i];
        GST_LOG ("Exif IFD: %s. Tag 0x%x (%s) = %s", exif_ifd_get_name (x),
            e->tag, exif_tag_get_name_in_ifd (e->tag, exif_entry_get_ifd (e)),
            exif_entry_get_value (e, val, sizeof (val)));
      }
    }
  }

  _exif_data = exif_data;

  exif_data += 6;
  exif_data_size -= 6;

  buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
      exif_data, exif_data_size, 0, exif_data_size, NULL, NULL);
  tags = gst_tag_list_from_exif_buffer_with_tiff_header (buffer);
  gst_buffer_unref (buffer);

  /* We don't want these tags */
  gst_tag_list_remove_tag (tags, GST_TAG_DEVICE_MANUFACTURER);
  gst_tag_list_remove_tag (tags, GST_TAG_DEVICE_MODEL);
  gst_tag_list_remove_tag (tags, GST_TAG_APPLICATION_NAME);
  gst_tag_list_remove_tag (tags, GST_TAG_DATE_TIME);

  /* we have a mess with ISO so we will just behave as N9 */
  iso = exif_content_get_entry (exif->ifd[EXIF_IFD_EXIF],
      EXIF_TAG_ISO_SPEED_RATINGS);

  if (iso) {
#ifdef __arm__
    guint16 val = exif_get_short (iso->data, EXIF_BYTE_ORDER_MOTOROLA);
#else
    guint16 val = exif_get_short (iso->data, EXIF_BYTE_ORDER_INTEL);
#endif
    gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE,
        GST_TAG_CAPTURING_ISO_SPEED, val, NULL);
  }

  /* TODO: the following are being dropped
   *
   * 0x213  EXIF_TAG_YCBCR_POSITIONING
   * 0x9004 EXIF_TAG_DATE_TIME_DIGITIZED
   * 0x9101 EXIF_TAG_COMPONENTS_CONFIGURATION
   * 0xa001 EXIF_TAG_COLOR_SPACE
   * 0xa002 EXIF_TAG_PIXEL_X_DIMENSION
   * 0xa003 EXIF_TAG_PIXEL_Y_DIMENSION
   * 0xa005 EXIF_TAG_INTEROPERABILITY_IFD_POINTER
   * thumbnail.
   * 0x100 EXIF_TAG_IMAGE_WIDTH
   * 0x101 EXIF_TAG_IMAGE_LENGTH
   * 0x9203 EXIF_TAG_BRIGHTNESS_VALUE
   * 0x9205 EXIF_TAG_MAX_APERTURE_VALUE
   * 0x9206 EXIF_TAG_SUBJECT_DISTANCE
   * 0x9208 EXIF_TAG_LIGHT_SOURCE
   * 0x9286 EXIF_TAG_USER_COMMENT
   */
out:
  if (_exif_data) {
    exif_mem_free (mem, _exif_data);
  }

  if (exif) {
    exif_data_free (exif);
  }

  exif_mem_unref (mem);

  return tags;
}
Пример #30
0
static void
metadataparse_exif_content_foreach_entry_func (ExifEntry * entry,
    void *user_data)
{
  MEUserData *meudata = (MEUserData *) user_data;
  GType type = G_TYPE_NONE;
  ExifByteOrder byte_order;
  const gchar *tag;

  /* We need the byte order */
  if (!entry || !entry->parent || !entry->parent->parent)
    return;

  tag = metadataparse_exif_get_tag_from_exif (entry->tag, &type);
  byte_order = exif_data_get_byte_order (entry->parent->parent);

  if (metadataparse_handle_unit_tags (entry, meudata, byte_order))
    goto done;

  if (!tag)
    goto done;

  if (type == GST_TYPE_FRACTION) {
    gint numerator = 0;
    gint denominator = 1;

    switch (entry->format) {
      case EXIF_FORMAT_SRATIONAL:
      {
        ExifSRational v_srat;

        v_srat = exif_get_srational (entry->data, byte_order);
        if (v_srat.denominator) {
          numerator = (gint) v_srat.numerator;
          denominator = (gint) v_srat.denominator;
        }
      }
        break;
      case EXIF_FORMAT_RATIONAL:
      {
        ExifRational v_rat;

        v_rat = exif_get_rational (entry->data, byte_order);
        if (v_rat.denominator) {
          numerator = (gint) v_rat.numerator;
          denominator = (gint) v_rat.denominator;
        }
        if (meudata->resolution_unit == 3) {
          /* converts from cm to inches */
          if (entry->tag == EXIF_TAG_X_RESOLUTION
              || entry->tag == EXIF_TAG_Y_RESOLUTION) {
            numerator *= 2;
            denominator *= 5;
          }
        }
      }
        break;
      default:
        GST_ERROR ("Unexpected Tag Type");
        goto done;
        break;
    }
    gst_tag_list_add (meudata->taglist, meudata->mode, tag, numerator,
        denominator, NULL);

  } else if (type == GST_TYPE_BUFFER) {
    GstBuffer *buf = gst_buffer_new_and_alloc (entry->components);

    memcpy (GST_BUFFER_DATA (buf), entry->data, entry->components);
    gst_tag_list_add (meudata->taglist, meudata->mode, tag, buf, NULL);
    gst_buffer_unref (buf);
  } else {
    switch (type) {
      case G_TYPE_STRING:
      {
        char buf[2048];
        const gchar *str = exif_entry_get_value (entry, buf, sizeof (buf));
        GString *value = NULL;

        if (entry->tag == EXIF_TAG_DATE_TIME_DIGITIZED
            || entry->tag == EXIF_TAG_DATE_TIME
            || entry->tag == EXIF_TAG_DATE_TIME_ORIGINAL) {
          value = g_string_new_len (str, 20);
          /* 20 is enough memory to hold "YYYY-MM-DDTHH:MM:SS" */

          if (metadataparse_exif_convert_to_datetime (value)) {
            str = value->str;
          } else {
            GST_ERROR ("Unexpected date & time format for %s", tag);
            str = NULL;
          }

        }
        if (str)
          gst_tag_list_add (meudata->taglist, meudata->mode, tag, str, NULL);
        if (value)
          g_string_free (value, TRUE);
      }
        break;
      case G_TYPE_INT:
        /* fall through */
      case G_TYPE_UINT:
      {
        gint value;

        switch (entry->format) {
          case EXIF_FORMAT_SHORT:
            value = exif_get_short (entry->data, byte_order);
            break;
          case EXIF_FORMAT_LONG:
            value = exif_get_long (entry->data, byte_order);
            break;
          default:
            GST_ERROR ("Unexpected Exif Tag Type (%s - %s)",
                tag, exif_format_get_name (entry->format));
            goto done;
            break;
        }
        if (entry->tag == EXIF_TAG_CONTRAST ||
            entry->tag == EXIF_TAG_SATURATION) {
          switch (value) {
            case 0:
              break;
            case 1:
              value = -67;      /* -100-34 /2 */
              break;
            case 2:
              value = 67;       /* 100+34 /2 */
              break;
            default:
              GST_ERROR ("Unexpected value");
              break;
          }
        }
        gst_tag_list_add (meudata->taglist, meudata->mode, tag, value, NULL);
      }
        break;
      case G_TYPE_DOUBLE:
      {
        gdouble value = 0.0;

        if (entry->tag == EXIF_TAG_GPS_LATITUDE
            || entry->tag == EXIF_TAG_GPS_LONGITUDE) {
          ExifRational *rt = (ExifRational *) entry->data;

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

          /* MM - minutes and SS - seconds */
          GST_DEBUG ("min: %lu / %lu", (gulong) rt->numerator,
              (gulong) rt->denominator);
          value += (gdouble) rt->numerator / ((gdouble) rt->denominator * 60.0);
          rt++;
          GST_DEBUG ("sec: %lu / %lu", (gulong) rt->numerator,
              (gulong) rt->denominator);
          value +=
              (gdouble) rt->numerator / ((gdouble) rt->denominator * 3600.0);

          /* apply sign */
          if (entry->tag == EXIF_TAG_GPS_LATITUDE) {
            if (((meudata->latitude_ref == 'S') && (value > 0.0)) ||
                ((meudata->latitude_ref == 'N') && (value < 0.0))) {
              value = -value;
            }
          } else {
            if (((meudata->longitude_ref == 'W') && (value > 0.0)) ||
                ((meudata->longitude_ref == 'E') && (value < 0.0))) {
              value = -value;
            }
          }
          GST_DEBUG ("long/lat : %lf", value);
        }
        if (entry->tag == EXIF_TAG_GPS_ALTITUDE) {
          ExifRational v_rat = exif_get_rational (entry->data, byte_order);
          value = (gdouble) v_rat.numerator / (gdouble) v_rat.denominator;
          if (((meudata->altitude_ref == 1) && (value > 0.0)) ||
              ((meudata->altitude_ref == 0) && (value < 0.0))) {
            value = -value;
          }
          GST_DEBUG ("altitude = %lf", value);
        }
        gst_tag_list_add (meudata->taglist, meudata->mode, tag, value, NULL);
      }
        break;
      default:
        break;
    }
  }


done:
  {
#ifndef GST_DISABLE_GST_DEBUG
    char buf[2048];
    GST_LOG ("\n    Entry %p: %s (%s)\n"
        "      Size, Comps: %d, %d\n"
        "      Value: %s\n"
        "      Title: %s\n"
        "      Description: %s\n",
        entry,
        exif_tag_get_name (entry->tag),
        exif_format_get_name (entry->format),
        entry->size,
        (int) (entry->components),
        exif_entry_get_value (entry, buf, sizeof (buf)),
        exif_tag_get_title (entry->tag), exif_tag_get_description (entry->tag));
#endif
  }
  return;

}