/* 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 ); }
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; }
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; }
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; }
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; }
/** * 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; }
/** * 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; }
// 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,' '); } }
/* 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)); } } } } }
/** * 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"); }
/* 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 ); }
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; }
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; }
/** * 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; }
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" ); }
/** * 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; }
/** * 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; }
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); }
/* 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); } } } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }