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; }
/* Write a tag. Update what's there, or make a new one. */ static void vips_exif_set_tag( ExifData *ed, int ifd, ExifTag tag, write_fn fn, void *data ) { ExifEntry *entry; if( (entry = exif_content_get_entry( ed->ifd[ifd], tag )) ) { fn( ed, entry, 0, data ); } else { entry = exif_entry_new(); /* tag must be set before calling exif_content_add_entry. */ entry->tag = tag; exif_content_add_entry( ed->ifd[ifd], entry ); exif_entry_unref( entry ); /* libexif makes us have a special path for string-valued * fields :( */ if( tag_is_encoding( tag ) ) vips_exif_set_string_encoding( ed, entry, 0, data ); else if( tag_is_ascii( tag ) ) vips_exif_set_string_ascii( ed, entry, 0, data ); else if( tag_is_utf16( tag ) ) vips_exif_set_string_utf16( ed, entry, 0, data ); else { exif_entry_initialize( entry, tag ); fn( ed, entry, 0, data ); } } }
/**! If the entry doesn't exist, create it. * Based on exif command line action_create_value function in exif 0.6.20 */ static ExifEntry* my_exif_create_value (ExifData *ed, ExifTag tag, ExifIfd ifd) { ExifEntry *e = exif_content_get_entry (ed->ifd[ifd], tag); if ( !e ) { e = exif_entry_new (); exif_content_add_entry (ed->ifd[ifd], e); exif_entry_initialize (e, tag); // exif_entry_initialize doesn't seem to do much, especially for the GPS tags // so have to setup fields ourselves: e->tag = tag; if ( tag == EXIF_TAG_GPS_VERSION_ID ) { e->format = EXIF_FORMAT_BYTE; e->components = 4; e->size = sizeof (char) * e->components; if ( e->data ) g_free (e->data); e->data = g_malloc (e->size); } if ( tag == EXIF_TAG_GPS_MAP_DATUM || tag == EXIF_TAG_GPS_LATITUDE_REF || tag == EXIF_TAG_GPS_LONGITUDE_REF || tag == EXIF_TAG_GPS_PROCESSING_METHOD ) { e->format = EXIF_FORMAT_ASCII; // NB Allocation is handled later on when the actual string used is known } if ( tag == EXIF_TAG_GPS_LATITUDE || tag == EXIF_TAG_GPS_LONGITUDE ) { e->format = EXIF_FORMAT_RATIONAL; e->components = 3; e->size = sizeof (ExifRational) * e->components; if ( e->data ) g_free (e->data); e->data = g_malloc (e->size); } if ( tag == EXIF_TAG_GPS_ALTITUDE ) { e->format = EXIF_FORMAT_RATIONAL; e->components = 1; e->size = sizeof (ExifRational) * e->components; if ( e->data ) g_free (e->data); e->data = g_malloc (e->size); } if ( tag == EXIF_TAG_GPS_ALTITUDE_REF ) { e->components = 1; e->size = sizeof (char) * e->components; if ( e->data ) g_free (e->data); e->data = g_malloc (e->size); } /* The entry has been added to the IFD, so we can unref it */ //exif_entry_unref(e); // Crashes later on, when saving to jpeg if the above unref is enabled!! // ?Some other malloc problem somewhere? } return e; }
// Create an entry and place it in |exifData|, the entry is default initialized // by the exif library based on |tag| static bool createEntry(ExifData* exifData, ExifIfd ifd, int tag) { removeExistingEntry(exifData, ifd, tag); ExifEntry* entry = exif_entry_new(); exif_content_add_entry(exifData->ifd[ifd], entry); exif_entry_initialize(entry, static_cast<ExifTag>(tag)); // Unref entry after changing owner to the ExifData struct exif_entry_unref(entry); return true; }
void exif_content_fix (ExifContent *c) { ExifIfd ifd = exif_content_get_ifd (c); ExifDataType dt; ExifEntry *e; unsigned int i, num; if (!c) return; dt = exif_data_get_data_type (c->parent); /* * First of all, fix all existing entries. */ exif_content_foreach_entry (c, fix_func, NULL); /* * Go through each tag and if it's not recorded, remove it. If one * is removed, exif_content_foreach_entry() will skip the next entry, * so if this happens do the loop again from the beginning to ensure * they're all checked. This could be avoided if we stop relying on * exif_content_foreach_entry but loop intelligently here. */ do { num = c->count; exif_content_foreach_entry (c, remove_not_recorded, NULL); } while (num != c->count); /* * Then check for non-existing mandatory tags and create them if needed */ num = exif_tag_table_count(); for (i = 0; i < num; ++i) { const ExifTag t = exif_tag_table_get_tag (i); if (exif_tag_get_support_level_in_ifd (t, ifd, dt) == EXIF_SUPPORT_LEVEL_MANDATORY) { if (exif_content_get_entry (c, t)) /* This tag already exists */ continue; exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content", "Tag '%s' is mandatory in IFD '%s' and has therefore been added.", exif_tag_get_name_in_ifd (t, ifd), exif_ifd_get_name (ifd)); e = exif_entry_new (); exif_content_add_entry (c, e); exif_entry_initialize (e, t); exif_entry_unref (e); } } }
void exif_entry_set_gps_altitude(ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifRational r1) { ExifEntry *pE; ExifByteOrder eO; pE = exif_entry_new (); exif_content_add_entry (pEdata->ifd[eEifd], pE); exif_entry_gps_initialize(pE, eEtag); eO = exif_data_get_byte_order (pE->parent->parent); if (pE->data) { exif_set_rational (pE->data, eO, r1); } else { printf ("ERROR: unallocated e->data Tag %d\n", eEtag); } exif_entry_fix (pE); exif_entry_unref (pE); }
void exif_content_fix (ExifContent *c) { ExifIfd ifd = exif_content_get_ifd (c); ExifDataType dt; ExifTag t; ExifEntry *e; if (!c) return; dt = exif_data_get_data_type (c->parent); /* First of all, fix all existing entries. */ exif_content_foreach_entry (c, fix_func, NULL); /* * Then check for existing tags that are not allowed and for * non-existing mandatory tags. */ for (t = 0; t <= 0xffff; t++) { switch (exif_tag_get_support_level_in_ifd (t, ifd, dt)) { case EXIF_SUPPORT_LEVEL_MANDATORY: if (exif_content_get_entry (c, t)) break; exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content", "Tag '%s' is mandatory in IFD '%s' and has therefore been added.", exif_tag_get_name_in_ifd (t, ifd), exif_ifd_get_name (ifd)); e = exif_entry_new (); exif_content_add_entry (c, e); exif_entry_initialize (e, t); exif_entry_unref (e); break; case EXIF_SUPPORT_LEVEL_NOT_RECORDED: e = exif_content_get_entry (c, t); if (!e) break; exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content", "Tag '%s' is not recoreded in IFD '%s' and has therefore been " "removed.", exif_tag_get_name_in_ifd (t, ifd), exif_ifd_get_name (ifd)); exif_content_remove_entry (c, e); break; case EXIF_SUPPORT_LEVEL_OPTIONAL: default: break; } } }
void exif_entry_set_byte(ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifByte n) { ExifEntry *pE; unsigned char *pData; pE = exif_entry_new (); exif_content_add_entry (pEdata->ifd[eEifd], pE); exif_entry_initialize (pE, eEtag); pData = (unsigned char *) (pE->data); if (pData) { *pData = n; } else { printf ("ERROR: unallocated e->data Tag %d\n", eEtag); } exif_entry_fix (pE); exif_entry_unref (pE); }
void exif_entry_set_gps_version(ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifByte r1, ExifByte r2, ExifByte r3, ExifByte r4) { ExifEntry *pE; ExifByteOrder eO; pE = exif_entry_new (); exif_content_add_entry (pEdata->ifd[eEifd], pE); exif_entry_gps_initialize(pE, eEtag); eO = exif_data_get_byte_order (pE->parent->parent); if (pE->data) { pE->data[0] = r1; pE->data[1] = r2; pE->data[2] = r3; pE->data[3] = r4; } else { printf ("ERROR: unallocated e->data Tag %d\n", eEtag); } exif_entry_fix (pE); exif_entry_unref (pE); }
void exif_entry_set_string (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, const char *s) { ExifEntry *pE; pE = exif_entry_new (); exif_content_add_entry (pEdata->ifd[eEifd], pE); exif_entry_initialize (pE, eEtag); if (pE->data) free (pE->data); pE->components = strlen (s) + 1; pE->size = sizeof (char) * pE->components; pE->data = (unsigned char *) malloc (pE->size); if (!pE->data) { printf ("Cannot allocate %d bytes.\nTerminating.\n", (int) pE->size); exit (1); } strcpy ((char *) pE->data, (char *) s); exif_entry_fix (pE); exif_entry_unref (pE); }
/* Write a tag. Update what's there, or make a new one. */ static void write_tag( ExifData *ed, int ifd, ExifTag tag, write_fn fn, void *data ) { ExifEntry *entry; if( (entry = exif_content_get_entry( ed->ifd[ifd], tag )) ) { fn( ed, entry, 0, data ); } else { entry = exif_entry_new(); /* tag must be set before calling exif_content_add_entry. */ entry->tag = tag; exif_content_add_entry( ed->ifd[ifd], entry ); exif_entry_initialize( entry, tag ); exif_entry_unref( entry ); fn( ed, entry, 0, data ); } }
void exif_content_fix (ExifContent *c) { ExifIfd ifd = exif_content_get_ifd (c); ExifDataType dt; ExifEntry *e; unsigned int i, num; if (!c) return; dt = exif_data_get_data_type (c->parent); exif_content_foreach_entry (c, fix_func, NULL); do { num = c->count; exif_content_foreach_entry (c, remove_not_recorded, NULL); } while (num != c->count); num = exif_tag_table_count(); for (i = 0; i < num; ++i) { const ExifTag t = exif_tag_table_get_tag (i); if (exif_tag_get_support_level_in_ifd (t, ifd, dt) == EXIF_SUPPORT_LEVEL_MANDATORY) { if (exif_content_get_entry (c, t)) continue; exif_log (c->priv->log, EXIF_LOG_CODE_DEBUG, "exif-content", "Tag '%s' is mandatory in IFD '%s' and has therefore been added.", exif_tag_get_name_in_ifd (t, ifd), exif_ifd_get_name (ifd)); e = exif_entry_new (); exif_content_add_entry (c, e); exif_entry_initialize (e, t); exif_entry_unref (e); } } }
void exif_entry_set_undefined (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, exif_buffer * buf) { ExifEntry *pE; pE = exif_entry_new (); exif_content_add_entry (pEdata->ifd[eEifd], pE); exif_entry_initialize (pE, eEtag); if (buf != NULL) { if (pE->data) free (pE->data); pE->components = buf->size; pE->size = buf->size; pE->data = (unsigned char *) malloc (pE->size); if (!pE->data) { printf ("Cannot allocate %d bytes.\nTerminating.\n", (int) pE->size); exit (1); } memcpy ((void *) pE->data, (void *) buf->data, buf->size); } exif_entry_fix (pE); exif_entry_unref (pE); }
static int write_tag( ExifData *ed, ExifTag tag, ExifFormat f, write_fn fn, void *data ) { ExifByteOrder bo; int found; int i; bo = exif_data_get_byte_order( ed ); /* Need to set the tag in all sections which have it :-( */ found = 0; for( i = 0; i < EXIF_IFD_COUNT; i++ ) { ExifEntry *entry; if( (entry = exif_content_get_entry( ed->ifd[i], tag )) && entry->format == f && entry->components == 1 ) { fn( entry, bo, data ); found = 1; } } if( !found ) { /* There was no tag we could update ... make one in ifd[0]. */ ExifEntry *entry; entry = exif_entry_new(); exif_content_add_entry( ed->ifd[0], entry ); exif_entry_initialize( entry, tag ); fn( entry, bo, data ); } return( 0 ); }
void ChatImageItem::downloadOrViewImage() { if (retryButton) { message.status = FMessage::Uploading; retryButton = false; setButton(); emit mediaUpload(message); } else if (message.media_wa_type == FMessage::Location) { QString url = (message.media_url.isEmpty()) ? URL_LOCATION_SHARING + QString::number(message.latitude) + "," + QString::number(message.longitude) + "+(" + message.notify_name.replace("<","<").replace(">",">") + ")" : message.media_url; QDesktopServices::openUrl(QUrl(url)); } else if (!message.local_file_uri.isEmpty()) { QString uri = "file://" + message.local_file_uri; QDBusConnection dbus = QDBusConnection::sessionBus(); switch (message.media_wa_type) { case FMessage::Audio: if (message.live) { AudioPlayer *player = new AudioPlayer(this); connect(player,SIGNAL(progress(int)),this,SLOT(updateTime(int))); connect(player,SIGNAL(finished()),this,SLOT(finishedAudioPlay())); ui->viewImageButton->setEnabled(false); player->play(uri); // We need to notificate the sender that we played the audio emit voiceNotePlayed(message); break; } case FMessage::Video: { DBusNokiaMediaPlayerIf *mediaPlayerBus = new DBusNokiaMediaPlayerIf(NOKIA_MEDIAPLAYER_DBUS_NAME, NOKIA_MEDIAPLAYER_DBUS_PATH, dbus,this); mediaPlayerBus->mime_open(uri); } break; case FMessage::Image: { // The following is to avoid an Image Viewer bug where files without // EXIF data can't be opened. QImageReader image(message.local_file_uri); if (image.format() == "jpeg") { ExifData *ed = exif_data_new_from_file(message.local_file_uri.toUtf8().constData()); if (!ed) { ed = exif_data_new(); if (ed) { Utilities::logData("Creating default Exif data."); ExifEntry *entry = exif_entry_new(); exif_content_add_entry(ed->ifd[EXIF_IFD_0], entry); exif_entry_initialize(entry, EXIF_TAG_IMAGE_DESCRIPTION); entry->data = (unsigned char *) YAPPARI_APPLICATION_NAME; JPEGData *jpeg = jpeg_data_new_from_file(message.local_file_uri.toUtf8().constData()); jpeg_data_set_exif_data(jpeg, ed); jpeg_data_save_file(jpeg, message.local_file_uri.toUtf8().constData()); jpeg_data_unref(jpeg); } } if (ed) exif_data_unref(ed); } DBusNokiaImageViewerIf *imageViewerBus = new DBusNokiaImageViewerIf(NOKIA_IMAGEVIEWER_DBUS_NAME, NOKIA_IMAGEVIEWER_DBUS_PATH, dbus,this); imageViewerBus->mime_open(uri); } break; }
static int iExifWriteTag(ExifData* exif, int index, const char* name, int data_type, int attrib_count, const void* attrib_data) { int c; ExifTag tag = exif_tag_from_name(name); if (tag == 0) { if (!imStrEqual(name, "GPSVersionID")) // EXIF_TAG_GPS_VERSION_ID==0 return 1; } ExifEntry *entry = exif_entry_new(); ExifByteOrder byte_order = exif_data_get_byte_order(exif); ExifContent *content; if (name[0] == 'G' && name[1] == 'P' && name[2] == 'S') { content = exif->ifd[EXIF_IFD_GPS]; // GPS tags if (!iExifGetGPSTagInfo((int)tag, &(entry->format), &(entry->components))) { exif_entry_free(entry); return 1; } } else { if (tag > EXIF_TAG_COPYRIGHT) content = exif->ifd[EXIF_IFD_EXIF]; // EXIF tags else content = exif->ifd[EXIF_IFD_0]; // TIFF tags if (!iExifGetTagInfo(tag, &(entry->format), &(entry->components))) { exif_entry_free(entry); return 1; } } int format_size = exif_format_get_size(entry->format); if (entry->components == 0) entry->components = attrib_count; entry->tag = tag; entry->size = format_size * entry->components; entry->data = (imbyte*)malloc(entry->size); if (tag == EXIF_TAG_RESOLUTION_UNIT) { int res_unit; if (imStrEqual((char*)attrib_data, "DPI")) res_unit = 2; else res_unit = 3; exif_content_add_entry(content, entry); exif_set_short(entry->data, byte_order, (imushort)res_unit); return 1; } /* test if tag type is the same as the attribute type */ if (iExifGetDataType(entry->format) != data_type) { exif_entry_free(entry); return 1; } exif_content_add_entry(content, entry); switch (entry->format) { case EXIF_FORMAT_UNDEFINED: case EXIF_FORMAT_ASCII: case EXIF_FORMAT_SBYTE: case EXIF_FORMAT_BYTE: { imbyte *bvalue = (imbyte*)attrib_data; for (c = 0; c < (int)entry->components; c++) entry->data[c] = bvalue[c]; } break; case EXIF_FORMAT_SHORT: { imushort *usvalue = (imushort*)attrib_data; for (c = 0; c < (int)entry->components; c++) exif_set_short(entry->data + format_size * c, byte_order, usvalue[c]); } break; case EXIF_FORMAT_SSHORT: { short *svalue = (short*)attrib_data; for (c = 0; c < (int)entry->components; c++) exif_set_sshort(entry->data + format_size * c, byte_order, svalue[c]); } break; case EXIF_FORMAT_LONG: { int *ivalue = (int*)attrib_data; for (c = 0; c < (int)entry->components; c++) exif_set_long(entry->data + format_size * c, byte_order, (unsigned int)ivalue[c]); } break; case EXIF_FORMAT_SLONG: { int *ivalue = (int*)attrib_data; for (c = 0; c < (int)entry->components; c++) exif_set_slong(entry->data + format_size * c, byte_order, (int)ivalue[c]); } break; case EXIF_FORMAT_RATIONAL: { ExifRational v_rat; int num, den; float *fvalue = (float*)attrib_data; for (c = 0; c < (int)entry->components; c++) { iGetRational(fvalue[c], &num, &den, 1); v_rat.numerator = num; v_rat.denominator = den; exif_set_rational(entry->data + format_size * c, byte_order, v_rat); } } break; case EXIF_FORMAT_SRATIONAL: { ExifSRational v_srat; int num, den; float *fvalue = (float*)attrib_data; for (c = 0; c < (int)entry->components; c++) { iGetRational(fvalue[c], &num, &den, 1); v_srat.numerator = num; v_srat.denominator = den; exif_set_srational(entry->data + format_size * c, byte_order, v_srat); } } break; case EXIF_FORMAT_FLOAT: // defined but unsupported in libEXIF case EXIF_FORMAT_DOUBLE: // defined but unsupported in libEXIF break; } /* no need to release the entry here, it will be handled internally because we added the entry to the ExifContent */ (void)index; return 1; }
static void metadatamux_exif_for_each_tag_in_list (const GstTagList * list, const gchar * tag, gpointer user_data) { ExifData *ed = (ExifData *) user_data; ExifTag exif_tag; GType type = G_TYPE_INVALID; ExifEntry *entry = NULL; ExifIfd ifd = EXIF_IFD_COUNT; const ExifByteOrder byte_order = exif_data_get_byte_order (ed); exif_tag = metadatamux_exif_get_exif_from_tag (tag, &type, &ifd); if (!exif_tag) goto done; entry = exif_data_get_entry (ed, exif_tag); if (entry) exif_entry_ref (entry); else { entry = exif_entry_new (); exif_content_add_entry (ed->ifd[ifd], entry); exif_entry_initialize (entry, exif_tag); } if (entry->data == NULL) { if (entry->tag == EXIF_TAG_GPS_ALTITUDE) { entry->format = EXIF_FORMAT_RATIONAL; entry->components = 1; entry->size = exif_format_get_size (entry->format) * entry->components; entry->data = g_malloc (entry->size); } else if (entry->tag == EXIF_TAG_GPS_LATITUDE || entry->tag == EXIF_TAG_GPS_LONGITUDE) { entry->format = EXIF_FORMAT_RATIONAL; entry->components = 3; entry->size = exif_format_get_size (entry->format) * entry->components; entry->data = g_malloc (entry->size); } } if (type == GST_TYPE_FRACTION) { const GValue *gvalue = gst_tag_list_get_value_index (list, tag, 0); gint numerator = gst_value_get_fraction_numerator (gvalue); gint denominator = gst_value_get_fraction_denominator (gvalue); switch (entry->format) { case EXIF_FORMAT_SRATIONAL: { ExifSRational sr = { numerator, denominator }; exif_set_srational (entry->data, byte_order, sr); } break; case EXIF_FORMAT_RATIONAL: { ExifRational r; if (entry->tag == EXIF_TAG_X_RESOLUTION || entry->tag == EXIF_TAG_Y_RESOLUTION) { ExifEntry *unit_entry = NULL; unit_entry = exif_data_get_entry (ed, EXIF_TAG_RESOLUTION_UNIT); if (unit_entry) { ExifShort vsh = exif_get_short (unit_entry->data, byte_order); if (vsh != 2) /* inches */ exif_set_short (unit_entry->data, byte_order, 2); } } r.numerator = numerator; r.denominator = denominator; if (numerator < 0) r.numerator = -numerator; if (denominator < 0) r.denominator = -denominator; exif_set_rational (entry->data, byte_order, r); } break; default: break; } } else if (type == GST_TYPE_BUFFER) { const GValue *val = NULL; GstBuffer *buf; val = gst_tag_list_get_value_index (list, tag, 0); buf = gst_value_get_buffer (val); entry->components = GST_BUFFER_SIZE (buf); entry->size = GST_BUFFER_SIZE (buf); entry->data = g_malloc (entry->size); memcpy (entry->data, GST_BUFFER_DATA (buf), entry->size); } else { switch (type) { case G_TYPE_STRING: { gchar *value = NULL; if (gst_tag_list_get_string (list, tag, &value)) { if (entry->tag == EXIF_TAG_DATE_TIME_DIGITIZED || entry->tag == EXIF_TAG_DATE_TIME || entry->tag == EXIF_TAG_DATE_TIME_ORIGINAL) { GString *datetime = g_string_new_len (value, 20); /* enough memory to hold "YYYY:MM:DD HH:MM:SS" */ if (metadatamux_exif_convert_from_datetime (datetime)) { } else { GST_ERROR ("Unexpected date & time format for %s", tag); } g_free (value); value = datetime->str; g_string_free (datetime, FALSE); } else if (value) { entry->components = strlen (value) + 1; entry->size = exif_format_get_size (entry->format) * entry->components; entry->data = (guint8 *) value; value = NULL; } } } break; case G_TYPE_UINT: case G_TYPE_INT: { gint value; ExifShort v_short; if (G_TYPE_UINT == type) { gst_tag_list_get_uint (list, tag, (guint *) & value); } else { gst_tag_list_get_int (list, tag, &value); } switch (entry->format) { case EXIF_FORMAT_SHORT: if (entry->tag == EXIF_TAG_CONTRAST || entry->tag == EXIF_TAG_SATURATION) { if (value < -33) value = 1; /* low */ else if (value < 34) value = 0; /* normal */ else value = 2; /* high */ } v_short = value; exif_set_short (entry->data, byte_order, v_short); break; case EXIF_FORMAT_LONG: exif_set_long (entry->data, byte_order, value); break; default: break; } } break; case G_TYPE_DOUBLE: { gdouble value; gst_tag_list_get_double (list, tag, &value); if (entry->tag == EXIF_TAG_GPS_LATITUDE || entry->tag == EXIF_TAG_GPS_LONGITUDE) { ExifRational *rt = (ExifRational *) entry->data; gdouble v = fabs (value); ExifEntry *ref_entry = NULL; char ref; const ExifTag ref_tag = entry->tag == EXIF_TAG_GPS_LATITUDE ? EXIF_TAG_GPS_LATITUDE_REF : EXIF_TAG_GPS_LONGITUDE_REF; /* DDD - degrees */ rt->numerator = (gulong) v; rt->denominator = 1; GST_DEBUG ("deg: %lf : %lu / %lu", v, (gulong) rt->numerator, (gulong) rt->denominator); v -= rt->numerator; rt++; /* MM - minutes */ rt->numerator = (gulong) (v * 60.0); rt->denominator = 1; GST_DEBUG ("min: %lf : %lu / %lu", v, (gulong) rt->numerator, (gulong) rt->denominator); v -= ((gdouble) rt->numerator / 60.0); rt++; /* SS - seconds */ rt->numerator = (gulong) (0.5 + v * 3600.0); rt->denominator = 1; GST_DEBUG ("sec: %lf : %lu / %lu", v, (gulong) rt->numerator, (gulong) rt->denominator); if (entry->tag == EXIF_TAG_GPS_LONGITUDE) { GST_DEBUG ("longitude : %lf", value); ref = (value < 0.0) ? 'W' : 'E'; } else { GST_DEBUG ("latitude : %lf", value); ref = (value < 0.0) ? 'S' : 'N'; } ref_entry = exif_data_get_entry (ed, ref_tag); if (ref_entry) { exif_entry_ref (ref_entry); } else { ref_entry = exif_entry_new (); exif_content_add_entry (ed->ifd[EXIF_IFD_GPS], ref_entry); exif_entry_initialize (ref_entry, ref_tag); } if (ref_entry->data == NULL) { ref_entry->format = EXIF_FORMAT_ASCII; ref_entry->components = 2; ref_entry->size = 2; ref_entry->data = g_malloc (2); } ref_entry->data[0] = ref; ref_entry->data[1] = 0; exif_entry_unref (ref_entry); } else if (entry->tag == EXIF_TAG_GPS_ALTITUDE) { ExifEntry *ref_entry = NULL; ExifRational *rt = (ExifRational *) entry->data; rt->numerator = (gulong) fabs (10.0 * value); rt->denominator = 10; GST_DEBUG ("altitude : %lf", value); ref_entry = exif_data_get_entry (ed, EXIF_TAG_GPS_ALTITUDE_REF); if (ref_entry) { exif_entry_ref (ref_entry); } else { ref_entry = exif_entry_new (); exif_content_add_entry (ed->ifd[EXIF_IFD_GPS], ref_entry); exif_entry_initialize (ref_entry, EXIF_TAG_GPS_ALTITUDE_REF); } if (ref_entry->data == NULL) { ref_entry->format = EXIF_FORMAT_BYTE; ref_entry->components = 1; ref_entry->size = 1; ref_entry->data = g_malloc (1); } if (value > 0.0) { ref_entry->data[0] = 0; } else { ref_entry->data[0] = 1; } exif_entry_unref (ref_entry); } } break; default: break; } } done: if (entry) exif_entry_unref (entry); }
int createEXIF(dc1394featureset_t *xFeatures, ExifData ** pParentEd) { ExifEntry *pE; ExifData * pEd; int i = !xFeatures->feature[DC1394_FEATURE_WHITE_BALANCE - DC1394_FEATURE_MIN].auto_active; ExifSRational xR = {xFeatures->feature[DC1394_FEATURE_BRIGHTNESS - DC1394_FEATURE_MIN].value, xFeatures->feature[DC1394_FEATURE_BRIGHTNESS - DC1394_FEATURE_MIN].max};; printf ("Creating EXIF data...\n"); pEd = exif_data_new (); printf ("Adding a Make reference\n"); pE = exif_entry_new (); exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE); exif_entry_initialize (pE, EXIF_TAG_MAKE); pE->data="AVT"; exif_entry_unref (pE); printf ("Adding a Model reference\n"); pE = exif_entry_new (); exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE); exif_entry_initialize (pE, EXIF_TAG_MODEL); pE->data="510c"; exif_entry_unref (pE); printf ("Adding a Tag to reference # samples per pixel\n"); pE = exif_entry_new (); exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE); exif_entry_initialize (pE, EXIF_TAG_SAMPLES_PER_PIXEL); exif_entry_unref (pE); printf ("Adding a White Balance Reference\n"); pE = exif_entry_new (); exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE); exif_entry_initialize (pE, EXIF_TAG_WHITE_BALANCE); exif_set_short(pE->data, exif_data_get_byte_order (pEd), i); exif_entry_unref (pE); printf ("Adding a Sharpness Reference\n"); pE = exif_entry_new (); exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE); exif_entry_initialize (pE, EXIF_TAG_SHARPNESS); exif_set_short(pE->data, exif_data_get_byte_order (pEd), 0); exif_entry_unref (pE); printf ("Adding a Brightness reference\n"); pE = exif_entry_new (); exif_content_add_entry (pEd->ifd[EXIF_IFD_0], pE); exif_entry_initialize (pE, EXIF_TAG_BRIGHTNESS_VALUE); exif_set_srational (pE->data, exif_data_get_byte_order (pEd), xR); *pParentEd = pEd; printf("Done!\n"); return 0; }