static void compare_aperture_value (ExifEntry * entry, ExifTagCheckData * testdata) { gdouble gst_value, exif_value; ExifSRational rational; GValue value = { 0 }; if (!gst_tag_list_get_double_index (testdata->taglist, GST_TAG_CAPTURING_FOCAL_RATIO, 0, &gst_value)) { GST_WARNING ("Failed to get focal ratio from taglist"); return; } rational = exif_get_srational (entry->data, exif_data_get_byte_order (entry->parent->parent)); g_value_init (&value, GST_TYPE_FRACTION); gst_value_set_fraction (&value, rational.numerator, rational.denominator); gst_util_fraction_to_double (gst_value_get_fraction_numerator (&value), gst_value_get_fraction_denominator (&value), &exif_value); g_value_unset (&value); exif_value = pow (2, exif_value / 2); GST_LOG ("Aperture value in gst=%lf and in exif=%lf", gst_value, exif_value); fail_unless (ABS (gst_value - exif_value) < 0.001); testdata->result = TRUE; }
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; }
static void entry_getdata_aux (lua_State *L, ExifEntry *entry, unsigned int n) { ExifFormat format = entry->format; size_t formatsize = (size_t)exif_format_get_size(format); const unsigned char *ptr = entry->data+formatsize*n; ExifByteOrder order = exif_data_get_byte_order(entry->parent->parent); switch (format) { case EXIF_FORMAT_BYTE: lua_pushinteger(L, (ExifByte)*ptr); break; case EXIF_FORMAT_SBYTE: lua_pushinteger(L, (ExifSByte)*ptr); break; case EXIF_FORMAT_SHORT: lua_pushinteger(L, exif_get_short(ptr, order)); break; case EXIF_FORMAT_SSHORT: lua_pushinteger(L, exif_get_sshort(ptr, order)); break; case EXIF_FORMAT_LONG: lua_pushnumber(L, exif_get_long(ptr, order)); break; case EXIF_FORMAT_SLONG: lua_pushinteger(L, exif_get_slong(ptr, order)); break; case EXIF_FORMAT_RATIONAL: { ExifRational rat = exif_get_rational(ptr, order); pushrational(L, rat.numerator, rat.denominator); break; } case EXIF_FORMAT_SRATIONAL: { ExifSRational rat = exif_get_srational(ptr, order); pushrational(L, rat.numerator, rat.denominator); break; } case EXIF_FORMAT_ASCII: lua_pushinteger(L, *ptr); break; default: lua_pushnil(L); break; } }
static void compare_shutter_speed (ExifEntry * entry, ExifTagCheckData * testdata) { gdouble gst_num, exif_num; ExifSRational rational; GValue exif_value = { 0 }; const GValue *gst_value = NULL; gst_value = gst_tag_list_get_value_index (testdata->taglist, GST_TAG_CAPTURING_SHUTTER_SPEED, 0); if (gst_value == NULL) { GST_WARNING ("Failed to get shutter-speed from taglist"); return; } rational = exif_get_srational (entry->data, exif_data_get_byte_order (entry->parent->parent)); g_value_init (&exif_value, GST_TYPE_FRACTION); gst_value_set_fraction (&exif_value, rational.numerator, rational.denominator); gst_util_fraction_to_double (gst_value_get_fraction_numerator (&exif_value), gst_value_get_fraction_denominator (&exif_value), &exif_num); g_value_unset (&exif_value); gst_util_fraction_to_double (gst_value_get_fraction_numerator (gst_value), gst_value_get_fraction_denominator (gst_value), &gst_num); exif_num = pow (2, -exif_num); GST_LOG ("Shutter speed in gst=%lf and in exif=%lf", gst_num, exif_num); fail_unless (ABS (gst_num - exif_num) < 0.001); testdata->result = TRUE; }
static double exifDouble(ExifEntry *entry, ExifByteOrder byte_order) { switch (entry->format) { case EXIF_FORMAT_BYTE: return double(entry->data[0]); case EXIF_FORMAT_SHORT: return double(exif_get_short(entry->data, byte_order)); case EXIF_FORMAT_LONG: return double(exif_get_long(entry->data, byte_order)); case EXIF_FORMAT_RATIONAL: { ExifRational r = exif_get_rational(entry->data, byte_order); return double(r.numerator)/double(r.denominator); } case EXIF_FORMAT_SBYTE: return double(*(signed char *)entry->data); case EXIF_FORMAT_SSHORT: return double(exif_get_sshort(entry->data, byte_order)); case EXIF_FORMAT_SLONG: return double(exif_get_slong(entry->data, byte_order)); case EXIF_FORMAT_SRATIONAL: { ExifSRational r = exif_get_srational(entry->data, byte_order); return double(r.numerator)/double(r.denominator); } case EXIF_FORMAT_FLOAT: return double(((float *)entry->data)[0]); case EXIF_FORMAT_DOUBLE: return ((double *)entry->data)[0]; default: return nan(0); } }
/* Does both signed and unsigned rationals from a double*. * * Don't change the exit entry if the value currently there is a good * approximation of the double we are trying to set. */ static void vips_exif_set_double( ExifData *ed, ExifEntry *entry, unsigned long component, void *data ) { double value = *((double *) data); ExifByteOrder bo; size_t sizeof_component; size_t offset; double old_value; if( entry->components <= component ) { VIPS_DEBUG_MSG( "vips_exif_set_double: " "too few components\n" ); return; } /* Wait until after the component check to make sure we cant get /0. */ bo = exif_data_get_byte_order( ed ); sizeof_component = entry->size / entry->components; offset = component * sizeof_component; VIPS_DEBUG_MSG( "vips_exif_set_double: %s = %g\n", vips_exif_entry_get_name( entry ), value ); if( entry->format == EXIF_FORMAT_RATIONAL ) { ExifRational rv; rv = exif_get_rational( entry->data + offset, bo ); old_value = (double) rv.numerator / rv.denominator; if( VIPS_FABS( old_value - value ) > 0.0001 ) { vips_exif_double_to_rational( value, &rv ); VIPS_DEBUG_MSG( "vips_exif_set_double: %u / %u\n", rv.numerator, rv.denominator ); exif_set_rational( entry->data + offset, bo, rv ); } } else if( entry->format == EXIF_FORMAT_SRATIONAL ) { ExifSRational srv; srv = exif_get_srational( entry->data + offset, bo ); old_value = (double) srv.numerator / srv.denominator; if( VIPS_FABS( old_value - value ) > 0.0001 ) { vips_exif_double_to_srational( value, &srv ); VIPS_DEBUG_MSG( "vips_exif_set_double: %d / %d\n", srv.numerator, srv.denominator ); exif_set_srational( entry->data + offset, bo, srv ); } } }
MapTags *read_sgeo_tags_map(ExifData **exif_array, ExifIfd ifd, ExifShort map_count) { int i; MapTags *map_data = NULL; ExifData *exif = NULL; ExifEntry *entry; ExifByteOrder order; SGeoTag stag; ExifSRational *srational = NULL; ExifLong *elong = NULL; order = exif_data_get_byte_order(exif); map_data = (MapTags* )calloc(map_count, sizeof(*map_data)); for (i = 0; i < map_count; i++) { exif = exif_array[i]; entry = exif_content_get_entry (exif->ifd[ifd], (ExifTag)(SGEO_TAG_MAP_VERSION)); if (entry) memcpy(map_data[i].VersionID, entry->data, sizeof(map_data[i].VersionID)); entry = exif_content_get_entry (exif->ifd[ifd], (ExifTag)(SGEO_TAG_MAP_ID)); if (entry) map_data[i].ID = exif_get_long(entry->data, order); srational = &map_data[i].TopLeftLongitude; for (stag = SGEO_TAG_MAP_TOP_LEFT_LONGITUDE; stag <= SGEO_TAG_MAP_BOTTOM_RIGHT_LATITUDE; stag++) { entry = exif_content_get_entry (exif->ifd[ifd], (ExifTag)(stag)); if (entry) *srational = exif_get_srational(entry->data, order); srational++; } elong = &map_data[i].CoordinateSystem; for (stag = SGEO_TAG_MAP_COORDINATE_SYSTEM; stag <= SGEO_TAG_MAP_THUMBNAIL_FORMAT; stag++) { entry = exif_content_get_entry (exif->ifd[ifd], (ExifTag)(stag)); if (entry) *elong = exif_get_long(entry->data, order); elong++; } entry = exif_content_get_entry (exif->ifd[ifd], (ExifTag)(SGEO_TAG_MAP_THUMBNAIL)); if (entry) { map_data[i].Data = (void *)malloc(entry->size); map_data[i].DataSize = entry->size; memcpy(map_data[i].Data, entry->data, entry->size); } } return map_data; }
static int vips_exif_get_srational( ExifData *ed, ExifEntry *entry, unsigned long component, ExifSRational *out ) { if( entry->format == EXIF_FORMAT_SRATIONAL ) { ExifByteOrder bo = exif_data_get_byte_order( ed ); size_t sizeof_component = entry->size / entry->components; size_t offset = component * sizeof_component; *out = exif_get_srational( entry->data + offset, bo ); } else return( -1 ); return( 0 ); }
static int getDouble(ExifData *ed, ExifByteOrder bo, ExifTag t, double *d) { ExifEntry * e = exif_data_get_entry(ed, t); if (!e) return 0; char *b = e->data; switch (e->format) { case EXIF_FORMAT_SHORT: *d = (double) exif_get_short(b, bo); return 1; case EXIF_FORMAT_SSHORT: *d = (double) exif_get_sshort(b, bo); return 1; case EXIF_FORMAT_LONG: *d = (double) exif_get_long(b, bo); return 1; case EXIF_FORMAT_SLONG: *d = (double) exif_get_slong(b, bo); return 1; case EXIF_FORMAT_RATIONAL: { ExifRational r = exif_get_rational(b, bo); *d = (double) r.numerator / (double) r.denominator; return 1; } case EXIF_FORMAT_SRATIONAL: { ExifSRational r = exif_get_srational(b, bo); *d = (double) r.numerator / (double) r.denominator; return 1; } default: return 0; } }
void imFileFormatJPEG::iReadExifAttrib(unsigned char* data, int data_length, imAttribTable* attrib_table) { ExifData* exif = exif_data_new_from_data(data, data_length); if (!exif) return; void* value = NULL; int c, value_size = 0; ExifByteOrder byte_order = exif_data_get_byte_order(exif); for (int ifd = 0; ifd < EXIF_IFD_COUNT; ifd++) { if (ifd == EXIF_IFD_1 || ifd == EXIF_IFD_INTEROPERABILITY) // Skip thumbnail and interoperability continue; ExifContent *content = exif->ifd[ifd]; if (content && content->count) { for (int j = 0; j < (int)content->count; j++) { ExifEntry *entry = content->entries[j]; int type = 0; const char* name = exif_tag_get_name_in_ifd(entry->tag, (ExifIfd)ifd); if (!name) continue; if (value_size < (int)entry->size) { value = realloc(value, entry->size); value_size = entry->size; } int format_size = exif_format_get_size(entry->format); if (entry->tag == EXIF_TAG_RESOLUTION_UNIT) { int res_unit = (int)exif_get_short (entry->data, byte_order); if (res_unit == 2) attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPI"); else if (res_unit == 3) attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPC"); continue; } switch (entry->format) { case EXIF_FORMAT_UNDEFINED: case EXIF_FORMAT_ASCII: case EXIF_FORMAT_SBYTE: case EXIF_FORMAT_BYTE: { type = IM_BYTE; imbyte *bvalue = (imbyte*)value; for (c = 0; c < (int)entry->components; c++) bvalue[c] = entry->data[c]; } break; case EXIF_FORMAT_SSHORT: { type = IM_SHORT; short *svalue = (short*)value; for (c = 0; c < (int)entry->components; c++) svalue[c] = exif_get_short(entry->data + format_size * c, byte_order); } break; case EXIF_FORMAT_SHORT: { type = IM_USHORT; imushort *usvalue = (imushort*)value; for (c = 0; c < (int)entry->components; c++) usvalue[c] = exif_get_short(entry->data + format_size * c, byte_order); } break; case EXIF_FORMAT_LONG: { type = IM_INT; int *ivalue = (int*)value; for (c = 0; c < (int)entry->components; c++) ivalue[c] = (int)exif_get_long(entry->data + format_size * c, byte_order); } break; case EXIF_FORMAT_SLONG: { type = IM_INT; int *ivalue = (int*)value; for (c = 0; c < (int)entry->components; c++) ivalue[c] = (int)exif_get_slong(entry->data + format_size * c, byte_order); } break; case EXIF_FORMAT_RATIONAL: { ExifRational v_rat; type = IM_FLOAT; float *fvalue = (float*)value; for (c = 0; c < (int)entry->components; c++) { v_rat = exif_get_rational(entry->data + format_size * c, byte_order); fvalue[c] = (float)v_rat.numerator / (float)v_rat.denominator; } } break; case EXIF_FORMAT_SRATIONAL: { ExifSRational v_srat; type = IM_FLOAT; float *fvalue = (float*)value; for (c = 0; c < (int)entry->components; c++) { v_srat = exif_get_srational(entry->data + format_size * c, byte_order); fvalue[c] = (float)v_srat.numerator / (float)v_srat.denominator; } } break; case EXIF_FORMAT_FLOAT: // defined but unsupported in libEXIF case EXIF_FORMAT_DOUBLE: // defined but unsupported in libEXIF break; } attrib_table->Set(name, type, entry->components, value); } } } if (value) free(value); exif_data_free(exif); }
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 generateDecryptData(SGeoTagsEncrypt *collection, unsigned char *data, unsigned int size, ExifByteOrder order) { ExifEntry *entry = NULL; ExifData *exif = NULL; ExifContent *content = NULL; // create new exif data exif = exif_data_new_mem (exif_mem_new_default()); exif->priv->order = order; // fill exif fields exif_data_load_data_content(exif, EXIF_IFD_ENCRYPT, data, size, 0, 0); content = exif->ifd[EXIF_IFD_ENCRYPT]; // excrypt version exif_mem_read(collection->VersionID, NULL, content, SGEO_TAG_ENCRYPT_VERSION, sizeof(collection->VersionID)); // FileName read_unicode_string_from_exif(content, SGEO_TAG_ENCRYPT_FILE_NAME, collection->FileName, sizeof(collection->FileName) / sizeof(*collection->FileName)); // FileSize exif_long_read(&collection->FileSize, NULL, content, SGEO_TAG_ENCRYPT_FILE_SIZE, order); // datetime exif_mem_read(collection->DateTimeOriginal, &collection->ExistDateTimeOriginal, content, EXIF_TAG_DATE_TIME_ORIGINAL, sizeof(collection->DateTimeOriginal)); // Longitude exif_srational_read(&collection->Longitude, &collection->ExistLongitude, content, SGEO_TAG_LONGITUDE, order); // LongAccuracy exif_rational_read(&collection->LongitudeAccuracy, &collection->ExistLongitudeAccuracy, content, SGEO_TAG_LONGACCURACY, order); // Latitude exif_srational_read(&collection->Latitude, &collection->ExistLatitude, content, SGEO_TAG_LATITUDE, order); // LatAccuracy exif_rational_read(&collection->LatitudeAccuracy, &collection->ExistLatitudeAccuracy, content, SGEO_TAG_LATACCURACY, order); // Altitude exif_srational_read(&collection->Altitude, &collection->ExistAltitude, content, SGEO_TAG_ALTITUDE, order); // AltAccuracy exif_rational_read(&collection->AltitudeAccuracy, &collection->ExistAltitudeAccuracy, content, SGEO_TAG_ALTACCURACY, order); // Azimuth exif_srational_read(&collection->Altitude, &collection->ExistAltitude, content, SGEO_TAG_ALTITUDE, order); entry = exif_content_get_entry (content, (ExifTag)(SGEO_TAG_AZIMUTH)); if (entry) collection->Azimuth = exif_get_srational(entry->data, order); // AzimuthAccuracy exif_rational_read(&collection->AzimuthAccuracy, &collection->ExistAzimuthAccuracy, content, SGEO_TAG_AZIMUTHACCURACY, order); // Pitch exif_srational_read(&collection->Pitch, &collection->ExistPitch, content, SGEO_TAG_PITCH, order); // PitchAccuracy exif_rational_read(&collection->PitchAccuracy, &collection->ExistPitchAccuracy, content, SGEO_TAG_PITCHACCURACY, order); // Roll exif_srational_read(&collection->Roll, &collection->ExistRoll, content, SGEO_TAG_ROLL, order); // RollAccuracy exif_rational_read(&collection->RollAccuracy, &collection->ExistRollAccuracy, content, SGEO_TAG_ROLLACCURACY, order); // HViewAngle exif_rational_read(&collection->HViewAngle, &collection->ExistHViewAngle, content, SGEO_TAG_HVIEWANGLE, order); // HViewAngleAccuracy exif_rational_read(&collection->HViewAngleAccuracy, &collection->ExistHViewAngleAccuracy, content, SGEO_TAG_HVIEWANGLEACCURACY, order); // VViewAngle exif_rational_read(&collection->VViewAngle, &collection->ExistVViewAngle, content, SGEO_TAG_VVIEWANGLE, order); // VViewAngleAccuracy exif_rational_read(&collection->VViewAngleAccuracy, &collection->ExistVViewAngleAccuracy, content, SGEO_TAG_VVIEWANGLEACCURACY, order); // SatCount exif_mem_read(&collection->SatCount, NULL, content, SGEO_TAG_SATCOUNT, sizeof(collection->SatCount)); // global time exif_mem_read(&collection->GlobalTime, &collection->ExistGlobalTime, content, SGEO_TAG_GLOBAL_TIME, sizeof(collection->GlobalTime)); // GNSSType exif_long_read(&collection->GNSSType, NULL, content, SGEO_TAG_GNSS_TYPE, order); // DeviceName read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_NAME, collection->DeviceName, sizeof(collection->DeviceName) / sizeof(*collection->DeviceName)); // DeviceIMEI read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_IMEI, collection->DeviceIMEI, sizeof(collection->DeviceIMEI) / sizeof(*collection->DeviceIMEI)); // DeviceNumber read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_NUMBER, collection->DeviceNumber, sizeof(collection->DeviceNumber) / sizeof(*collection->DeviceNumber)); // DeviceOS read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_OS, collection->DeviceOS, sizeof(collection->DeviceOS) / sizeof(*collection->DeviceOS)); // DeviceOSVersion read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_OS_VERSION, collection->DeviceOSVersion, sizeof(collection->DeviceOSVersion) / sizeof(*collection->DeviceOSVersion)); // DeviceVersion read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_VERSION, collection->DeviceVersion, sizeof(collection->DeviceVersion) / sizeof(*collection->DeviceVersion)); // DeviceDateTimeMeasure exif_mem_read(&collection->DeviceDateTimeMeasure, NULL, content, SGEO_TAG_DEVICE_DATE_TIME_MEASURE, sizeof(collection->DeviceDateTimeMeasure)); // ProgramVersion read_unicode_string_from_exif(content, SGEO_TAG_PROGRAM_VERSION, collection->ProgramVersion, sizeof(collection->ProgramVersion) / sizeof(*collection->ProgramVersion)); // ProgramName read_unicode_string_from_exif(content, SGEO_TAG_PROGRAM_NAME, collection->ProgramName, sizeof(collection->ProgramName) / sizeof(*collection->ProgramName)); // ProgramUserName read_unicode_string_from_exif(content, SGEO_TAG_PROGRAM_USER_NAME, collection->ProgramUserName, sizeof(collection->ProgramUserName) / sizeof(*collection->ProgramUserName)); exif_data_unref(exif); }
SGeoTags read_sgeo_tags(ExifContent *content, ExifByteOrder order) { int i = 0; unsigned char *buf = NULL; SGeoTags collect = {0}; ExifEntry *entry = NULL; //ExifContent *content = exif->ifd[EXIF_IFD_SGEO]; SGeoTags *collection = NULL; collection = &collect; // Longitude exif_srational_read(&collection->Longitude, &collection->ExistLongitude, content, SGEO_TAG_LONGITUDE, order); // LongAccuracy exif_rational_read(&collection->LongitudeAccuracy, &collection->ExistLongitudeAccuracy, content, SGEO_TAG_LONGACCURACY, order); // Latitude exif_srational_read(&collection->Latitude, &collection->ExistLatitude, content, SGEO_TAG_LATITUDE, order); // LatAccuracy exif_rational_read(&collection->LatitudeAccuracy, &collection->ExistLatitudeAccuracy, content, SGEO_TAG_LATACCURACY, order); // Altitude exif_srational_read(&collection->Altitude, &collection->ExistAltitude, content, SGEO_TAG_ALTITUDE, order); // AltAccuracy exif_rational_read(&collection->AltitudeAccuracy, &collection->ExistAltitudeAccuracy, content, SGEO_TAG_ALTACCURACY, order); // Azimuth exif_srational_read(&collection->Azimuth, &collection->ExistAzimuth, content, SGEO_TAG_AZIMUTH, order); // AzimuthAccuracy exif_rational_read(&collection->AzimuthAccuracy, &collection->ExistAzimuthAccuracy, content, SGEO_TAG_AZIMUTHACCURACY, order); // Pitch exif_srational_read(&collection->Pitch, &collection->ExistPitch, content, SGEO_TAG_PITCH, order); // PitchAccuracy exif_rational_read(&collection->PitchAccuracy, &collection->ExistPitchAccuracy, content, SGEO_TAG_PITCHACCURACY, order); // Roll exif_srational_read(&collection->Roll, &collection->ExistRoll, content, SGEO_TAG_ROLL, order); // RollAccuracy exif_rational_read(&collection->RollAccuracy, &collection->ExistRollAccuracy, content, SGEO_TAG_ROLLACCURACY, order); // HViewAngle exif_rational_read(&collection->HViewAngle, &collection->ExistHViewAngle, content, SGEO_TAG_HVIEWANGLE, order); // HViewAngleAccuracy exif_rational_read(&collection->HViewAngleAccuracy, &collection->ExistHViewAngleAccuracy, content, SGEO_TAG_HVIEWANGLEACCURACY, order); // VViewAngle exif_rational_read(&collection->VViewAngle, &collection->ExistVViewAngle, content, SGEO_TAG_VVIEWANGLE, order); // VViewAngleAccuracy exif_rational_read(&collection->VViewAngleAccuracy, &collection->ExistVViewAngleAccuracy, content, SGEO_TAG_VVIEWANGLEACCURACY, order); // SatCount exif_mem_read(&collection->SatCount, &collection->ExistSatCount, content, SGEO_TAG_SATCOUNT, sizeof(collection->SatCount)); // global time exif_mem_read(collection->GlobalTime, &collection->ExistGlobalTime, content, SGEO_TAG_GLOBAL_TIME, sizeof(collection->GlobalTime)); // UserLongitude exif_srational_read(&collection->UserLongitude, NULL, content, SGEO_TAG_USER_LONGITUDE, order); // UserLongAccuracy exif_rational_read(&collection->UserLongitudeAccuracy, NULL, content, SGEO_TAG_USER_LONGACCURACY, order); // UserLatitude exif_srational_read(&collection->UserLatitude, NULL, content, SGEO_TAG_USER_LATITUDE, order); // UserLatAccuracy exif_rational_read(&collection->UserLatitudeAccuracy, NULL, content, SGEO_TAG_USER_LATACCURACY, order); // UserAltitude exif_srational_read(&collection->UserAltitude, NULL, content, SGEO_TAG_USER_ALTITUDE, order); // UserAltAccuracy exif_rational_read(&collection->UserAltitudeAccuracy, NULL, content, SGEO_TAG_USER_ALTACCURACY, order); // UserEarthLavel exif_srational_read(&collection->UserEarthLevel, NULL, content, SGEO_TAG_USER_EARTH_LEVEL, order); // UserAzimuth exif_srational_read(&collection->UserAzimuth, NULL, content, SGEO_TAG_USER_AZIMUTH, order); // UserAzimuthAccuracy exif_rational_read(&collection->UserAzimuthAccuracy, NULL, content, SGEO_TAG_USER_AZIMUTHACCURACY, order); // UserPitch exif_srational_read(&collection->UserPitch, NULL, content, SGEO_TAG_USER_PITCH, order); // UserPitchAccuracy exif_rational_read(&collection->UserPitchAccuracy, NULL, content, SGEO_TAG_USER_PITCHACCURACY, order); // UserRoll exif_srational_read(&collection->UserRoll, NULL, content, SGEO_TAG_USER_ROLL, order); // UserRollAccuracy exif_rational_read(&collection->UserRollAccuracy, NULL, content, SGEO_TAG_USER_ROLLACCURACY, order); // UserHViewAngle exif_rational_read(&collection->UserHViewAngle, NULL, content, SGEO_TAG_USER_HVIEWANGLE, order); // UserHViewAngleAccuracy exif_rational_read(&collection->UserHViewAngleAccuracy, NULL, content, SGEO_TAG_USER_HVIEWANGLEACCURACY, order); // UserVViewAngle exif_rational_read(&collection->UserVViewAngle, NULL, content, SGEO_TAG_USER_VVIEWANGLE, order); // UserVViewAngleAccuracy exif_rational_read(&collection->UserVViewAngleAccuracy, NULL, content, SGEO_TAG_USER_VVIEWANGLEACCURACY, order); // UserDeviceName read_unicode_string_from_exif(content, SGEO_TAG_USER_DEVICE_NAME, collection->UserDeviceName, sizeof(collection->UserDeviceName) / sizeof(*collection->UserDeviceName)); // UserProgramName read_unicode_string_from_exif(content, SGEO_TAG_USER_PROGRAM_NAME, collection->UserProgramName, sizeof(collection->UserProgramName) / sizeof(*collection->UserProgramName)); // UserUserName read_unicode_string_from_exif(content, SGEO_TAG_USER_USER_NAME, collection->UserUserName, sizeof(collection->UserUserName) / sizeof(*collection->UserUserName)); // ResultLongitude exif_srational_read(&collection->ResultLongitude, NULL, content, SGEO_TAG_RESULT_LONGITUDE, order); // ResultLongAccuracy exif_rational_read(&collection->ResultLongitudeAccuracy, NULL, content, SGEO_TAG_RESULT_LONGACCURACY, order); // ResultLatitude exif_srational_read(&collection->ResultLatitude, NULL, content, SGEO_TAG_RESULT_LATITUDE, order); // ResultLatAccuracy exif_rational_read(&collection->ResultLatitudeAccuracy, NULL, content, SGEO_TAG_RESULT_LATACCURACY, order); // ResultAltitude exif_srational_read(&collection->ResultAltitude, NULL, content, SGEO_TAG_RESULT_ALTITUDE, order); // ResultAltAccuracy exif_rational_read(&collection->ResultAltitudeAccuracy, NULL, content, SGEO_TAG_RESULT_ALTACCURACY, order); // ResultAzimuth exif_srational_read(&collection->ResultAzimuth, NULL, content, SGEO_TAG_RESULT_AZIMUTH, order); // ResultAzimuthAccuracy exif_rational_read(&collection->ResultAzimuthAccuracy, NULL, content, SGEO_TAG_RESULT_AZIMUTHACCURACY, order); // ResultPitch exif_srational_read(&collection->ResultPitch, NULL, content, SGEO_TAG_RESULT_PITCH, order); // ResultPitchAccuracy exif_rational_read(&collection->ResultPitchAccuracy, NULL, content, SGEO_TAG_RESULT_PITCHACCURACY, order); // ResultRoll exif_srational_read(&collection->ResultRoll, NULL, content, SGEO_TAG_RESULT_ROLL, order); // ResultRollAccuracy exif_rational_read(&collection->ResultRollAccuracy, NULL, content, SGEO_TAG_RESULT_ROLLACCURACY, order); // ResultHViewAngle exif_rational_read(&collection->ResultHViewAngle, NULL, content, SGEO_TAG_RESULT_HVIEWANGLE, order); // ResultHViewAngleAccuracy exif_rational_read(&collection->ResultHViewAngleAccuracy, NULL, content, SGEO_TAG_RESULT_HVIEWANGLEACCURACY, order); // ResultVViewAngle exif_rational_read(&collection->ResultVViewAngle, NULL, content, SGEO_TAG_RESULT_VVIEWANGLE, order); // ResultVViewAngleAccuracy exif_rational_read(&collection->ResultVViewAngleAccuracy, NULL, content, SGEO_TAG_RESULT_VVIEWANGLEACCURACY, order); // GNSSType exif_long_read(&collection->GNSSType, NULL, content, SGEO_TAG_GNSS_TYPE, order); // DeviceName read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_NAME, collection->DeviceName, sizeof(collection->DeviceName) / sizeof(*collection->DeviceName)); // DeviceIMEI read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_IMEI, collection->DeviceIMEI, sizeof(collection->DeviceIMEI) / sizeof(*collection->DeviceIMEI)); // DeviceNumber read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_NUMBER, collection->DeviceNumber, sizeof(collection->DeviceNumber) / sizeof(*collection->DeviceNumber)); // DeviceOS read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_OS, collection->DeviceOS, sizeof(collection->DeviceOS) / sizeof(*collection->DeviceOS)); // DeviceOSVersion read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_OS_VERSION, collection->DeviceOSVersion, sizeof(collection->DeviceOSVersion) / sizeof(*collection->DeviceOSVersion)); // DeviceVersion read_unicode_string_from_exif(content, SGEO_TAG_DEVICE_VERSION, collection->DeviceVersion, sizeof(collection->DeviceVersion) / sizeof(*collection->DeviceVersion)); // DeviceDateTimeMeasure exif_mem_read(collection->DeviceDateTimeMeasure, NULL, content, SGEO_TAG_DEVICE_DATE_TIME_MEASURE, sizeof(collection->DeviceDateTimeMeasure)); // ProgramVersion read_unicode_string_from_exif(content, SGEO_TAG_PROGRAM_VERSION, collection->ProgramVersion, sizeof(collection->ProgramVersion) / sizeof(*collection->ProgramVersion)); // ProgramName read_unicode_string_from_exif(content, SGEO_TAG_PROGRAM_NAME, collection->ProgramName, sizeof(collection->ProgramName) / sizeof(*collection->ProgramName)); // ProgramUserName read_unicode_string_from_exif(content, SGEO_TAG_PROGRAM_USER_NAME, collection->ProgramUserName, sizeof(collection->ProgramUserName) / sizeof(*collection->ProgramUserName)); // ObjectType //entry = exif_content_get_entry (content, (ExifTag)(SGEO_TAG_OBJECT_TYPE)); //if (entry) collection.ObjectType = *entry->data; // object data //entry = exif_content_get_entry (content, (ExifTag)(SGEO_TAG_OBJECT_DATA)); //if (entry) //{ // collection->ObjectDataSize = 0; // collection->ObjectData = (ExifByte* )malloc(entry->size); // if (collection->ObjectData) // { // collection->ObjectDataSize = entry->size; // memcpy(collection->ObjectData, exif->data, collection->ObjectDataSize); // } //} // encrypted table entry = exif_content_get_entry (content, (ExifTag)(SGEO_TAG_ENCRYPT_TABLE)); if (entry) { exif_long_read(&collection->SGeoEncrypt.Type, NULL, content, SGEO_TAG_ENCRYPT_TYPE, order); exif_mem_read(collection->SGeoEncrypt.AlgorithmVersion, NULL, content, SGEO_TAG_ENCRYPT_ALGORITHM_VERSION, sizeof(collection->SGeoEncrypt.AlgorithmVersion)); exif_mem_read(collection->SGeoEncrypt.PublicKey, NULL, content, SGEO_TAG_ENCRYPT_PUBLIC_KEY, sizeof(collection->SGeoEncrypt.PublicKey)); xorCryptData(entry->data, entry->size); generateDecryptData(&collection->SGeoEncrypt, entry->data, entry->size, order); } #ifdef _SGEO_FULL // Sighting collection->UserSightingCount = 0; entry = exif_content_get_entry (content, (ExifTag)(SGEO_TAG_SIGHTING)); if (entry) { collection->UserSightingCount = entry->size / sizeof(SightingTags); collection->UserSightingData = (SightingTags* )malloc(sizeof(*collection->UserSightingData) * collection->UserSightingCount); buf = entry->data; for (i = 0; i < collection->UserSightingCount; i++) { collection->UserSightingData[i].Angle = exif_get_srational(buf, order); buf += sizeof(ExifSRational); collection->UserSightingData[i].Flags = *buf; buf++; } } #endif // read objects collection->ObjectsTableCount = 60; collection->ObjectsTable = (SGeoObject *)calloc(collection->ObjectsTableCount, sizeof(*collection->ObjectsTable)); exif_mem_read(collection->ObjectsTable, NULL, content, (ExifTag)SGEO_TAG_OBJECT_TABLE, sizeof(*collection->ObjectsTable) * collection->ObjectsTableCount); return *collection; }
static void foreach_exif_entry( ExifEntry * entry , void * _closure ) { if ( ! entry ) { return; } //......................................................................... // Bail out of types we don't handle switch( entry->format ) { case EXIF_FORMAT_UNDEFINED: case EXIF_FORMAT_FLOAT: case EXIF_FORMAT_DOUBLE: return; default: break; } //......................................................................... unsigned char component_size = exif_format_get_size( entry->format ); ExifIfd ifd = exif_content_get_ifd( entry->parent ); const char * tag_name = exif_tag_get_name_in_ifd( entry->tag , ifd ); if ( ! tag_name || ! entry->data || ! entry->size || ! component_size || ! entry->components ) { return; } //......................................................................... // Add a prefix based on the IFD String name( tag_name ); switch( ifd ) { case EXIF_IFD_0: name = "IMAGE/" + name; break; case EXIF_IFD_1: name = "THUMBNAIL/" + name; break; case EXIF_IFD_EXIF: name = "EXIF/" + name; break; case EXIF_IFD_GPS: name = "GPS/" + name; break; case EXIF_IFD_INTEROPERABILITY: name = "INTEROP/" + name; break; default: return; } ExifClosure * closure = ( ExifClosure * ) _closure; JSON::Object * tags = closure->tags; //......................................................................... // ASCII ones are easy if ( entry->format == EXIF_FORMAT_ASCII ) { (*tags)[ name ] = String( ( const char * ) entry->data , entry->size ); return; } //......................................................................... if ( ( entry->components * component_size ) != entry->size ) { return; } ExifByteOrder byte_order = exif_data_get_byte_order( closure->exif_data ); const unsigned char * data = entry->data; JSON::Array array; for ( unsigned long i = 0; i < entry->components; ++i ) { switch( entry->format ) { case EXIF_FORMAT_BYTE: array.append( JSON::Value( int( * data ) ) ); break; case EXIF_FORMAT_SHORT: array.append( JSON::Value( int( exif_get_short( data , byte_order ) ) ) ); break; case EXIF_FORMAT_LONG: array.append( JSON::Value( int( exif_get_long( data , byte_order ) ) ) ); break; case EXIF_FORMAT_SBYTE: array.append( JSON::Value( int( * ( ( const char * ) data ) ) ) ); break; case EXIF_FORMAT_SSHORT: array.append( JSON::Value( exif_get_sshort( data , byte_order ) ) ); break; case EXIF_FORMAT_SLONG: array.append( JSON::Value( exif_get_slong( data , byte_order ) ) ); break; // TODO: I don't like representing a rational number as a string with a slash, case EXIF_FORMAT_SRATIONAL: { ExifSRational r = exif_get_srational( data , byte_order ); array.append( Util::format("%ld/%ld" , r.numerator , r.denominator ) ); break; } case EXIF_FORMAT_RATIONAL: { ExifRational r = exif_get_rational( data , byte_order ); array.append( Util::format("%lu/%lu" , r.numerator , r.denominator ) ); break; } default: break; } data += component_size; } if ( array.size() == 1 ) { (*tags)[ name ] = array[ 0 ]; } else if ( array.size() > 1 ) { (*tags)[ name ] = array; } }