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; }
/* 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 ); } } }
/* Does both signed and unsigned rationals from a char *. */ static void vips_exif_set_rational( ExifData *ed, ExifEntry *entry, unsigned long component, void *data ) { char *value = (char *) data; ExifByteOrder bo; size_t sizeof_component; size_t offset; if( entry->components <= component ) { VIPS_DEBUG_MSG( "vips_exif_set_rational: " "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_rational: %s = \"%s\"\n", vips_exif_entry_get_name( entry ), value ); if( entry->format == EXIF_FORMAT_RATIONAL ) { ExifRational rv; vips_exif_parse_rational( value, &rv ); VIPS_DEBUG_MSG( "vips_exif_set_rational: %u / %u\n", rv.numerator, rv.denominator ); exif_set_rational( entry->data + offset, bo, rv ); } else if( entry->format == EXIF_FORMAT_SRATIONAL ) { ExifSRational srv; vips_exif_parse_srational( value, &srv ); VIPS_DEBUG_MSG( "vips_exif_set_rational: %d / %d\n", srv.numerator, srv.denominator ); exif_set_srational( entry->data + offset, bo, srv ); } }
void exif_entry_set_srational (ExifData * pEdata, ExifIfd eEifd, ExifTag eEtag, ExifSRational r) { ExifEntry *pE; ExifByteOrder eO; pE = exif_entry_new (); exif_content_add_entry (pEdata->ifd[eEifd], pE); exif_entry_initialize (pE, eEtag); eO = exif_data_get_byte_order (pE->parent->parent); if (pE->data) { exif_set_srational (pE->data, eO, r); } else { printf ("ERROR: unallocated e->data Tag %d\n", eEtag); } exif_entry_fix (pE); exif_entry_unref (pE); }
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; }
void write_sgeo_tags(ExifData *exif, ExifIfd ifd, SGeoTags * collection) { unsigned int i = 0; unsigned char *buf = NULL; ExifEntry *entry = NULL; ExifByteOrder order; ExifContent *content = NULL; order = exif_data_get_byte_order(exif); content = exif->ifd[ifd]; // VersionID exif_mem_write(content, SGEO_TAG_VERSIONID, EXIF_FORMAT_BYTE, collection->VersionID, sizeof(collection->VersionID), NULL); // Longitude exif_srational_write(content, SGEO_TAG_LONGITUDE, &collection->Longitude, order, &collection->ExistLongitude); // LongAccuracy exif_rational_write(content, SGEO_TAG_LONGACCURACY, &collection->LongitudeAccuracy, order, &collection->ExistLongitudeAccuracy); // Latitude exif_srational_write(content, SGEO_TAG_LATITUDE, &collection->Latitude, order, &collection->ExistLatitude); // LatAccuracy exif_rational_write(content, SGEO_TAG_LATACCURACY, &collection->LatitudeAccuracy, order, &collection->ExistLatitudeAccuracy); // Altitude exif_srational_write(content, SGEO_TAG_ALTITUDE, &collection->Altitude, order, &collection->ExistAltitude); // AltAccuracy exif_rational_write(content, SGEO_TAG_ALTACCURACY, &collection->AltitudeAccuracy, order, &collection->ExistAltitudeAccuracy); // Azimuth exif_srational_write(content, SGEO_TAG_AZIMUTH, &collection->Azimuth, order, &collection->ExistAzimuth); // AzimuthAccuracy exif_rational_write(content, SGEO_TAG_AZIMUTHACCURACY, &collection->AzimuthAccuracy, order, &collection->ExistAzimuthAccuracy); // Pitch exif_srational_write(content, SGEO_TAG_PITCH, &collection->Pitch, order, &collection->ExistPitch); // PitchAccuracy exif_rational_write(content, SGEO_TAG_PITCHACCURACY, &collection->PitchAccuracy, order, &collection->ExistPitchAccuracy); // Roll exif_srational_write(content, SGEO_TAG_ROLL, &collection->Roll, order, &collection->ExistRoll); // RollAccuracy exif_rational_write(content, SGEO_TAG_ROLLACCURACY, &collection->RollAccuracy, order, &collection->ExistRollAccuracy); // HViewAngle exif_rational_write(content, SGEO_TAG_HVIEWANGLE, &collection->HViewAngle, order, &collection->ExistHViewAngle); // HViewAngleAccuracy exif_rational_write(content, SGEO_TAG_HVIEWANGLEACCURACY, &collection->HViewAngleAccuracy, order, &collection->ExistHViewAngleAccuracy); // VViewAngle exif_rational_write(content, SGEO_TAG_VVIEWANGLE, &collection->VViewAngle, order, &collection->ExistVViewAngle); // VViewAngleAccuracy exif_rational_write(content, SGEO_TAG_VVIEWANGLEACCURACY, &collection->VViewAngleAccuracy, order, &collection->ExistVViewAngleAccuracy); // SatCount exif_mem_write(content, SGEO_TAG_SATCOUNT, EXIF_FORMAT_BYTE, &collection->SatCount, sizeof(collection->SatCount), NULL); // global time exif_mem_write(content, SGEO_TAG_GLOBAL_TIME, EXIF_FORMAT_BYTE, collection->GlobalTime, sizeof(collection->GlobalTime), NULL); // UserLongitude exif_srational_write(content, SGEO_TAG_USER_LONGITUDE, &collection->UserLongitude, order, NULL); // UserLongAccuracy exif_rational_write(content, SGEO_TAG_USER_LONGACCURACY, &collection->UserLongitudeAccuracy, order, NULL); // UserLatitude exif_srational_write(content, SGEO_TAG_USER_LATITUDE, &collection->UserLatitude, order, NULL); // UserLatAccuracy exif_rational_write(content, SGEO_TAG_USER_LATACCURACY, &collection->UserLatitudeAccuracy, order, NULL); // UserAltitude exif_srational_write(content, SGEO_TAG_USER_ALTITUDE, &collection->UserAltitude, order, NULL); // UserAltAccuracy exif_rational_write(content, SGEO_TAG_USER_ALTACCURACY, &collection->UserAltitudeAccuracy, order, NULL); // UserEarthLavel exif_srational_write(content, SGEO_TAG_USER_EARTH_LEVEL, &collection->UserEarthLevel, order, NULL); // UserAzimuth exif_srational_write(content, SGEO_TAG_USER_AZIMUTH, &collection->UserAzimuth, order, NULL); // UserAzimuthAccuracy exif_rational_write(content, SGEO_TAG_USER_AZIMUTHACCURACY, &collection->UserAzimuthAccuracy, order, NULL); // UserPitch exif_srational_write(content, SGEO_TAG_USER_PITCH, &collection->UserPitch, order, NULL); // UserPitchAccuracy exif_rational_write(content, SGEO_TAG_USER_PITCHACCURACY, &collection->UserPitchAccuracy, order, NULL); // UserRoll exif_srational_write(content, SGEO_TAG_USER_ROLL, &collection->UserRoll, order, NULL); // UserRollAccuracy exif_rational_write(content, SGEO_TAG_USER_ROLLACCURACY, &collection->UserRollAccuracy, order, NULL); // UserHViewAngle exif_rational_write(content, SGEO_TAG_USER_HVIEWANGLE, &collection->UserHViewAngle, order, NULL); // UserHViewAngleAccuracy exif_rational_write(content, SGEO_TAG_USER_HVIEWANGLEACCURACY, &collection->UserHViewAngleAccuracy, order, NULL); // UserVViewAngle exif_rational_write(content, SGEO_TAG_USER_VVIEWANGLE, &collection->UserVViewAngle, order, NULL); // UserVViewAngleAccuracy exif_rational_write(content, SGEO_TAG_USER_VVIEWANGLEACCURACY, &collection->UserVViewAngleAccuracy, order, NULL); // UserDeviceName write_unicode_string_to_exif(content, SGEO_TAG_USER_DEVICE_NAME, collection->UserDeviceName); // UserProgramName write_unicode_string_to_exif(content, SGEO_TAG_USER_PROGRAM_NAME, collection->UserProgramName); // UserUserName write_unicode_string_to_exif(content, SGEO_TAG_USER_USER_NAME, collection->UserUserName); // ResultLongitude exif_srational_write(content, SGEO_TAG_RESULT_LONGITUDE, &collection->ResultLongitude, order, NULL); // ResultLongAccuracy exif_rational_write(content, SGEO_TAG_RESULT_LONGACCURACY, &collection->ResultLongitudeAccuracy, order, NULL); // ResultLatitude exif_srational_write(content, SGEO_TAG_RESULT_LATITUDE, &collection->ResultLatitude, order, NULL); // ResultLatAccuracy exif_rational_write(content, SGEO_TAG_RESULT_LATACCURACY, &collection->ResultLatitudeAccuracy, order, NULL); // ResultAltitude exif_srational_write(content, SGEO_TAG_RESULT_ALTITUDE, &collection->ResultAltitude, order, NULL); // ResultAltAccuracy exif_rational_write(content, SGEO_TAG_RESULT_ALTACCURACY, &collection->ResultAltitudeAccuracy, order, NULL); // ResultAzimuth exif_srational_write(content, SGEO_TAG_RESULT_AZIMUTH, &collection->ResultAzimuth, order, NULL); // ResultAzimuthAccuracy exif_rational_write(content, SGEO_TAG_RESULT_AZIMUTHACCURACY, &collection->ResultAzimuthAccuracy, order, NULL); // ResultPitch exif_srational_write(content, SGEO_TAG_RESULT_PITCH, &collection->ResultPitch, order, NULL); // ResultPitchAccuracy exif_rational_write(content, SGEO_TAG_RESULT_PITCHACCURACY, &collection->ResultPitchAccuracy, order, NULL); // ResultRoll exif_srational_write(content, SGEO_TAG_RESULT_ROLL, &collection->ResultRoll, order, NULL); // ResultRollAccuracy exif_rational_write(content, SGEO_TAG_RESULT_ROLLACCURACY, &collection->ResultRollAccuracy, order, NULL); // ResultHViewAngle exif_rational_write(content, SGEO_TAG_RESULT_HVIEWANGLE, &collection->ResultHViewAngle, order, NULL); // ResultHViewAngleAccuracy exif_rational_write(content, SGEO_TAG_RESULT_HVIEWANGLEACCURACY, &collection->ResultHViewAngleAccuracy, order, NULL); // ResultVViewAngle exif_rational_write(content, SGEO_TAG_RESULT_VVIEWANGLE, &collection->ResultVViewAngle, order, NULL); // ResultVViewAngleAccuracy exif_rational_write(content, SGEO_TAG_RESULT_VVIEWANGLEACCURACY, &collection->ResultVViewAngleAccuracy, order, NULL); // GNSSType exif_long_write(content, SGEO_TAG_GNSS_TYPE, &collection->GNSSType, order, NULL); // DeviceName write_unicode_string_to_exif(content, SGEO_TAG_DEVICE_NAME, collection->DeviceName); // DeviceIMEI write_unicode_string_to_exif(content, SGEO_TAG_DEVICE_IMEI, collection->DeviceIMEI); // DeviceNumber write_unicode_string_to_exif(content, SGEO_TAG_DEVICE_NUMBER, collection->DeviceNumber); // DeviceOS write_unicode_string_to_exif(content, SGEO_TAG_DEVICE_OS, collection->DeviceOS); // DeviceOSVersion write_unicode_string_to_exif(content, SGEO_TAG_DEVICE_OS_VERSION, collection->DeviceOSVersion); // DeviceVersion write_unicode_string_to_exif(content, SGEO_TAG_DEVICE_VERSION, collection->DeviceVersion); // DeviceDateTimeMeasure exif_mem_write(content, SGEO_TAG_DEVICE_DATE_TIME_MEASURE, EXIF_FORMAT_BYTE, collection->DeviceDateTimeMeasure, sizeof(collection->DeviceDateTimeMeasure), NULL); // ProgramName write_unicode_string_to_exif(content, SGEO_TAG_PROGRAM_NAME, collection->ProgramName); // ProgramVersion write_unicode_string_to_exif(content, SGEO_TAG_PROGRAM_VERSION, collection->ProgramVersion); // ProgramUserName write_unicode_string_to_exif(content, SGEO_TAG_PROGRAM_USER_NAME, collection->ProgramUserName); // DeviceName write_unicode_string_to_exif(content, SGEO_TAG_USER_DEVICE_NAME, collection->UserDeviceName); // ProgramName write_unicode_string_to_exif(content, SGEO_TAG_USER_PROGRAM_NAME, collection->UserProgramName); // ProgramUserName write_unicode_string_to_exif(content, SGEO_TAG_USER_USER_NAME, collection->UserUserName); // encrypted table generateEncryptData(&buf, &i, &collection->SGeoEncrypt, order); if (i > 0) { exif_long_write(content, SGEO_TAG_ENCRYPT_TYPE, &collection->SGeoEncrypt.Type, order, NULL); exif_mem_write(content, SGEO_TAG_ENCRYPT_ALGORITHM_VERSION, EXIF_FORMAT_BYTE, collection->SGeoEncrypt.AlgorithmVersion, sizeof(collection->SGeoEncrypt.AlgorithmVersion), NULL); exif_mem_write(content, SGEO_TAG_ENCRYPT_PUBLIC_KEY, EXIF_FORMAT_BYTE, collection->SGeoEncrypt.PublicKey, sizeof(collection->SGeoEncrypt.PublicKey), NULL); entry = exif_content_get_entry(content, (ExifTag)SGEO_TAG_ENCRYPT_TABLE); if (!entry) entry = create_tag(exif, ifd, (ExifTag)SGEO_TAG_ENCRYPT_TABLE, i, EXIF_FORMAT_BYTE); memcpy(entry->data, buf, i); xorCryptData(entry->data, i); free(buf); } #ifdef _SGEO_FULL // Sighting entry = exif_content_get_entry(content, (ExifTag)SGEO_TAG_SIGHTING); if (!entry && collection->UserSightingCount > 0) { entry = create_tag(exif, ifd, (ExifTag)SGEO_TAG_SIGHTING, sizeof(*collection->UserSightingData) * collection->UserSightingCount, EXIF_FORMAT_BYTE); buf = entry->data; for (i = 0; i < collection->UserSightingCount; i++) { exif_set_srational(buf, order, collection->UserSightingData[i].Angle); buf += sizeof(ExifSRational); *buf = collection->UserSightingData[i].Flags; buf++; } } #endif if (collection->ObjectsTable != NULL && collection->ObjectsTableCount > 0) exif_mem_write(content, (ExifTag)SGEO_TAG_OBJECT_TABLE, EXIF_FORMAT_BYTE, collection->ObjectsTable, sizeof(*collection->ObjectsTable) * collection->ObjectsTableCount, NULL); }