static void vips_exif_exif_entry( ExifEntry *entry, VipsExifRemove *ve ) { const char *tag_name; char vips_name_txt[256]; VipsBuf vips_name = VIPS_BUF_STATIC( vips_name_txt ); if( !(tag_name = vips_exif_entry_get_name( entry )) ) return; vips_buf_appendf( &vips_name, "exif-ifd%d-%s", exif_entry_get_ifd( entry ), tag_name ); /* Does this field exist on the image? If not, schedule it for * removal. */ if( !vips_image_get_typeof( ve->image, vips_buf_all( &vips_name ) ) ) ve->to_remove = g_slist_prepend( ve->to_remove, entry ); /* Orientation is really set from the vips * VIPS_META_ORIENTATION tag. If that's been deleted, we must delete * any matching EXIF tags too. */ if( strcmp( tag_name, "Orientation" ) == 0 && vips_image_get_typeof( ve->image, VIPS_META_ORIENTATION ) ) ve->to_remove = g_slist_prepend( ve->to_remove, entry ); /* If this is a string tag, we must also remove it ready for * recreation, see the comment below. */ if( tag_is_encoding( entry->tag ) || tag_is_ascii( entry->tag ) || tag_is_utf16( entry->tag ) ) ve->to_remove = g_slist_prepend( ve->to_remove, entry ); }
/* tags do not uniquely set tag names: the same tag can have different * names in different ifds. * * As long as this entry has been linked to an ifd, get the tag name. */ static const char * vips_exif_entry_get_name( ExifEntry *entry ) { if( !entry->parent ) return( NULL ); return( exif_tag_get_name_in_ifd( entry->tag, exif_entry_get_ifd( entry ) ) ); }
static void remove_not_recorded (ExifEntry *e, void *UNUSED(data)) { ExifIfd ifd = exif_entry_get_ifd(e) ; ExifContent *c = e->parent; ExifDataType dt = exif_data_get_data_type (c->parent); ExifTag t = e->tag; if (exif_tag_get_support_level_in_ifd (t, ifd, dt) == EXIF_SUPPORT_LEVEL_NOT_RECORDED) { exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content", "Tag 0x%04x is not recorded in IFD '%s' and has therefore been " "removed.", t, exif_ifd_get_name (ifd)); exif_content_remove_entry (c, e); } }
static void attach_exif_entry( ExifEntry *entry, VipsExif *ve ) { char name_txt[256]; VipsBuf name = VIPS_BUF_STATIC( name_txt ); char value_txt[256]; VipsBuf value = VIPS_BUF_STATIC( value_txt ); vips_buf_appendf( &name, "exif-ifd%d-%s", exif_entry_get_ifd( entry ), exif_tag_get_title( entry->tag ) ); vips_exif_to_s( ve->ed, entry, &value ); /* Can't do anything sensible with the error return. */ (void) vips_image_set_string( ve->image, vips_buf_all( &name ), vips_buf_all( &value ) ); }
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); }
static void vips_exif_attach_entry( ExifEntry *entry, VipsExifParams *params ) { const char *tag_name; char vips_name_txt[256]; VipsBuf vips_name = VIPS_BUF_STATIC( vips_name_txt ); char value_txt[256]; VipsBuf value = VIPS_BUF_STATIC( value_txt ); if( !(tag_name = vips_exif_entry_get_name( entry )) ) return; vips_buf_appendf( &vips_name, "exif-ifd%d-%s", exif_entry_get_ifd( entry ), tag_name ); vips_exif_to_s( params->ed, entry, &value ); /* Can't do anything sensible with the error return. */ (void) vips_image_set_string( params->image, vips_buf_all( &vips_name ), vips_buf_all( &value ) ); }
static void * vips_exif_exif_remove( ExifEntry *entry, VipsExifRemove *ve ) { #ifdef DEBUG { const char *tag_name; char vips_name_txt[256]; VipsBuf vips_name = VIPS_BUF_STATIC( vips_name_txt ); tag_name = vips_exif_entry_get_name( entry ); vips_buf_appendf( &vips_name, "exif-ifd%d-%s", exif_entry_get_ifd( entry ), tag_name ); printf( "vips_exif_exif_remove: %s\n", vips_buf_all( &vips_name ) ); } #endif /*DEBUG*/ exif_content_remove_entry( ve->content, entry ); return( NULL ); }
static ExifCategory get_exif_category (ExifEntry *entry) { ExifCategory cat = EXIF_CATEGORY_OTHER; int i; /* Some GPS tag IDs overlap with other ones, so check the IFD */ if (exif_entry_get_ifd (entry) == EXIF_IFD_GPS) { return EXIF_CATEGORY_GPS_DATA; } for (i = 0; exif_tag_category_map [i].id != -1; i++) { if (exif_tag_category_map[i].id == (int) entry->tag) { cat = exif_tag_category_map[i].category; break; } } return cat; }
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 exif_entry_cb (ExifEntry *entry, gpointer data) { GtkTreeStore *store; EogExifDetails *view; EogExifDetailsPrivate *priv; ExifCategory cat; ExifIfd ifd = exif_entry_get_ifd (entry); char *path; char b[1024]; const gint key = ifd << 16 | entry->tag; /* This should optimize away if comparision is correct */ g_warn_if_fail (EXIF_IFD_COUNT <= G_MAXUINT16); view = EOG_EXIF_DETAILS (data); priv = view->priv; store = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view))); /* Take the tag's IFD into account when caching their GtkTreePaths. * That should fix key collisions for tags that have the same number * but are stored in different IFDs. Exif tag numbers are 16-bit * values so we should be able to set the high word to the IFD number. */ path = g_hash_table_lookup (priv->id_path_hash, GINT_TO_POINTER (key)); if (path != NULL) { set_row_data (store, path, NULL, exif_tag_get_name_in_ifd (entry->tag, ifd), eog_exif_entry_get_value (entry, b, sizeof(b))); } else { ExifMnoteData *mnote = (entry->tag == EXIF_TAG_MAKER_NOTE ? exif_data_get_mnote_data (entry->parent->parent) : NULL); if (mnote) { // Supported MakerNote Found unsigned int i, c = exif_mnote_data_count (mnote); for (i = 0; i < c; i++) { path = g_hash_table_lookup (priv->id_path_hash_mnote, GINT_TO_POINTER (i)); if (path != NULL) { set_row_data (store, path, NULL, exif_mnote_data_get_title (mnote, i), exif_mnote_data_get_value (mnote, i, b, sizeof(b))); } else { path = set_row_data (store, NULL, exif_categories[EXIF_CATEGORY_MAKER_NOTE].path, exif_mnote_data_get_title (mnote, i), exif_mnote_data_get_value (mnote, i, b, sizeof(b))); g_hash_table_insert (priv->id_path_hash_mnote, GINT_TO_POINTER (i), path); } } } else { cat = get_exif_category (entry); path = set_row_data (store, NULL, exif_categories[cat].path, exif_tag_get_name_in_ifd (entry->tag, ifd), eog_exif_entry_get_value (entry, b, sizeof(b))); g_hash_table_insert (priv->id_path_hash, GINT_TO_POINTER (key), path); } } }
static const char * eog_exif_entry_get_value (ExifEntry *e, char *buf, guint n_buf) { ExifByteOrder bo; /* For now we only want to reformat some GPS values */ if (G_LIKELY (exif_entry_get_ifd (e) != EXIF_IFD_GPS)) return exif_entry_get_value (e, buf, n_buf); bo = exif_data_get_byte_order (e->parent->parent); /* Cast to number to avoid warnings about values not in enumeration */ switch ((guint16) e->tag) { case EXIF_TAG_GPS_LATITUDE: case EXIF_TAG_GPS_LONGITUDE: { gsize rational_size; ExifRational r; gfloat h = 0., m = 0.; rational_size = exif_format_get_size (EXIF_FORMAT_RATIONAL); if (G_UNLIKELY (e->components != 3 || e->format != EXIF_FORMAT_RATIONAL)) return exif_entry_get_value (e, buf, n_buf); r = exif_get_rational (e->data, bo); if (r.denominator != 0) h = (gfloat)r.numerator / r.denominator; r = exif_get_rational (e->data + rational_size, bo); if (r.denominator != 0) m = (gfloat)r.numerator / (gfloat)r.denominator; r = exif_get_rational (e->data + (2 * rational_size), bo); if (r.numerator != 0 && r.denominator != 0) { gfloat s; s = (gfloat)r.numerator / (gfloat)r.denominator; g_snprintf (buf, n_buf, "%.0f° %.0f' %.2f\"", h, m, s); } else { g_snprintf (buf, n_buf, "%.0f° %.2f'", h, m); } break; } case EXIF_TAG_GPS_LATITUDE_REF: case EXIF_TAG_GPS_LONGITUDE_REF: { if (G_UNLIKELY (e->components != 2 || e->format != EXIF_FORMAT_ASCII)) return exif_entry_get_value (e, buf, n_buf); switch (e->data[0]) { case 'N': g_snprintf (buf, n_buf, "%s", _("North")); break; case 'E': g_snprintf (buf, n_buf, "%s", _("East")); break; case 'W': g_snprintf (buf, n_buf, "%s", _("West")); break; case 'S': g_snprintf (buf, n_buf, "%s", _("South")); break; default: return exif_entry_get_value (e, buf, n_buf); break; } break; } default: return exif_entry_get_value (e, buf, n_buf); break; } return buf; }
/* Function to populate TSK Blackboard exif related attributes */ void extractExifData(ExifData * exifData, TskFile * pFile) { std::map<ExifTag, TSK_ATTRIBUTE_TYPE>::iterator it; std::vector<TskBlackboardAttribute> attrs; std::string datetime = ""; int timezone = 0; for (it = tagMap.begin(); it != tagMap.end(); ++it) { ExifEntry * exifEntry = exif_data_get_entry(exifData, it->first); char tag_data[256]; if (exifEntry == NULL) continue; if (it->first == EXIF_TAG_GPS_LATITUDE || it->first == EXIF_TAG_GPS_LONGITUDE) { // Check for the EXIF_IFD_GPS image file directory to avoid interoperability value ExifIfd ifd = exif_entry_get_ifd(exifEntry); if (ifd != EXIF_IFD_GPS) continue; exif_entry_get_value(exifEntry, tag_data, 256); float decDegrees = getDecimalDegrees(tag_data); char refValue[2]; if (it->first == EXIF_TAG_GPS_LATITUDE) { // Get the latitude reference value; used to determine if positive or negative decimal value ExifEntry * latitudeRef = exif_data_get_entry(exifData, it->first); exif_entry_get_value(latitudeRef, refValue,2); if (strcmp(refValue, "S") == 0) decDegrees *= -1; } else { // Get the longitude reference value; used to determine if positive or negative decimal value ExifEntry * longitudeRef = exif_data_get_entry(exifData, it->first); exif_entry_get_value(longitudeRef, refValue,2); if (strcmp(refValue, "W") == 0) decDegrees *= -1; } TskBlackboardAttribute attr(it->second, name(), "", decDegrees); attrs.push_back(attr); } else if (it->first == EXIF_TAG_GPS_SPEED) { // Check for the EXIF_IFD_GPS image file directory to avoid interoperability value ExifIfd ifd = exif_entry_get_ifd(exifEntry); if (ifd != EXIF_IFD_GPS) continue; //Get the GPS speed value exif_entry_get_value(exifEntry, tag_data, 256); float speed = getGPSSpeed(tag_data); char refValue[2]; //Get the GPS speed reference value ExifEntry * speedRef = exif_data_get_entry(exifData, it->first); exif_entry_get_value(speedRef, refValue,2); //Convert Kilometers per hour to meters per second if (strcmp(refValue, "K") == 0) { speed *= 0.277778; } //Convert Miles per hour to meters per second if (strcmp(refValue, "M") == 0) { speed *= 0.44704; } //Convert Knots to meters per second if (strcmp(refValue, "N") == 0) { speed *= 0.514444; } TskBlackboardAttribute attr(it->second, name(), "", speed); attrs.push_back(attr); } else if (it->first == EXIF_TAG_DATE_TIME_ORIGINAL) { exif_entry_get_value(exifEntry, tag_data, 256); datetime = std::string(tag_data); } else if(it->first == EXIF_TAG_TIME_ZONE_OFFSET){ exif_entry_get_value(exifEntry, tag_data, 256); timezone = atoi(tag_data); } else { // Get the tag's data exif_entry_get_value(exifEntry, tag_data, 256); // Add tag data to blackboard TskBlackboardAttribute attr(it->second, name(), "", tag_data); attrs.push_back(attr); } } if(!datetime.empty()){ Poco::DateTime parsedDT; int tzd; Poco::DateTimeParser::tryParse(datetime, parsedDT, tzd); if(timezone) parsedDT.makeUTC(timezone); else parsedDT.makeUTC(tzd); TskBlackboardAttribute attr(TSK_DATETIME, name(), "", (uint64_t)parsedDT.utcTime()); attrs.push_back(attr); } if(attrs.size() > 0){ TskBlackboardArtifact art = pFile->createArtifact(TSK_METADATA_EXIF); for(size_t i = 0; i < attrs.size(); i++){ art.addAttribute(attrs[i]); } } }
static int Egettag (lua_State *L) { /** entry.tag */ ExifEntry *entry = checkentry(L); ExifIfd ifd = exif_entry_get_ifd(entry); lua_pushstring(L, exif_tag_get_name_in_ifd(entry->tag, ifd)); return 1; }