/* Print exif for debugging ... hacked from exif-0.6.9/actions.c */ static void show_tags( ExifData *data ) { int i; unsigned int tag; const char *name; printf( "show EXIF tags:\n" ); for( i = 0; i < EXIF_IFD_COUNT; i++ ) printf( "%-7.7s", exif_ifd_get_name( i ) ); printf( "\n" ); for( tag = 0; tag < 0xffff; tag++ ) { name = exif_tag_get_title( tag ); if( !name ) continue; printf( " 0x%04x %-29.29s", tag, name ); for( i = 0; i < EXIF_IFD_COUNT; i++ ) if( exif_content_get_entry( data->ifd[i], tag ) ) printf( " * " ); else printf( " - " ); printf( "\n" ); } }
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" ); }
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 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 ) ); }
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; }
void FileSystemScanner::readEXIF(File* file) { static QString EXIFIFD_NAME_EXIF = exif_ifd_get_name(EXIF_IFD_EXIF); int maxDataLength = 255; char* charData = new char[maxDataLength]; ExifData* exifData = exif_data_new_from_file(file->fileInfo()->absFilePath().ascii()); // exif_data_dump(exifData); for (int i = 0; i < EXIF_IFD_COUNT; i++) { ExifContent* content = exifData->ifd[i]; QString group = QString(exif_ifd_get_name((ExifIfd) i)); if (group == EXIFIFD_NAME_EXIF) { for (unsigned int e = 0; e < content->count; e++) { ExifEntry* entry = content->entries[e]; ExifTag exifTagType = entry->tag; QString title = QString(exif_tag_get_title(entry->tag)); QString name = QString(exif_tag_get_name(entry->tag)); exif_entry_get_value(entry, charData, maxDataLength); QString data = QString(charData); QString description = QString(exif_tag_get_description(entry->tag)); // tracer->sdebug(__func__) << " - " << title << " / " << name << " = " << data << " (" << description << ")" << endl; // get the exif tagnode title and the tagnode representing this tag from the engine TagNode* exifTagNodeTitle = m_engine->exifTagNodeTitle(); TagNode* exifTagNodeEntry = exifTagNodeTitle->child(title); switch (exifTagType) { case EXIF_TAG_DATE_TIME_ORIGINAL: case EXIF_TAG_DATE_TIME_DIGITIZED: { QDateTime dateTime = readExifDateTime(data); TagNodeDateTime* exifTagNodeEntryDateTime = dynamic_cast<TagNodeDateTime*>(exifTagNodeEntry); if (exifTagNodeEntryDateTime == 0) { // tagnode for this EXIF entry does not exist --> create it exifTagNodeEntryDateTime = dynamic_cast<TagNodeDateTime*>(m_engine->createTag(exifTagNodeTitle, TagNode::TYPE_DATETIME, title, description, QString::null)); exifTagNodeEntryDateTime->setReadonly(true); } if (dateTime.isValid()) { // create new assoc new FileTagNodeAssocDateTime(file, exifTagNodeEntryDateTime, dateTime); } break; } default: { TagNodeString* exifTagNodeEntryString = dynamic_cast<TagNodeString*>(exifTagNodeEntry); if (exifTagNodeEntryString == 0) { // tagnode for this EXIF entry does not exist --> create it exifTagNodeEntryString = dynamic_cast<TagNodeString*>(m_engine->createTag(exifTagNodeTitle, TagNode::TYPE_STRING, title, description, QString::null)); exifTagNodeEntryString->setReadonly(true); } // create new assoc new FileTagNodeAssocString(file, exifTagNodeEntryString, data); } } } } } exif_data_free(exifData); delete charData; }