50 #include <libexif/exif-data.h>
56 static ExifEntry *
init_tag(ExifData *exif, ExifIfd ifd, ExifTag tag)
60 if (!((entry = exif_content_get_entry(exif->ifd[ifd], tag)))) {
62 entry = exif_entry_new();
68 exif_content_add_entry(exif->ifd[ifd], entry);
71 exif_entry_initialize(entry, tag);
79 exif_entry_unref(entry);
89 static ExifEntry *
create_tag(ExifData *exif, ExifIfd ifd, ExifTag tag,
size_t len)
95 ExifMem *mem = exif_mem_new_default();
99 entry = exif_entry_new_mem(mem);
103 buf = exif_mem_alloc(mem, len);
110 entry->components = len;
111 entry->format = EXIF_FORMAT_UNDEFINED;
114 exif_content_add_entry(exif->ifd[ifd], entry);
118 exif_entry_unref(entry);
125 #define image_data_len (image_jpg_len - image_data_offset)
129 0xff, 0xd8, 0xff, 0xe1
135 #define FILE_BYTE_ORDER EXIF_BYTE_ORDER_INTEL
138 #define FILE_COMMENT "Paparazzi autopilot"
141 #define ASCII_COMMENT "ASCII\0\0\0"
146 int write_exif_jpeg(
char *filename,
const unsigned char *image_jpg,
const unsigned int image_jpg_len,
147 const unsigned int image_jpg_x,
const unsigned int image_jpg_y)
151 unsigned char *exif_data;
152 unsigned int exif_data_len;
154 ExifData *exif = exif_data_new();
156 fprintf(stderr,
"Out of memory\n");
161 exif_data_set_option(exif, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
162 exif_data_set_data_type(exif, EXIF_DATA_TYPE_COMPRESSED);
170 entry =
init_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION);
173 entry =
init_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION);
176 entry =
init_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE);
184 entry =
create_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_USER_COMMENT,
194 entry =
create_tag(exif, EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_AREA,
195 4 * exif_format_get_size(EXIF_FORMAT_SHORT));
196 entry->format = EXIF_FORMAT_SHORT;
197 entry->components = 4;
203 entry =
create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF, 2);
204 entry->format = EXIF_FORMAT_ASCII;
205 entry->components = 1;
208 entry->data[0] =
'S';
213 entry->data[0] =
'N';
216 entry =
create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF, 2);
217 entry->format = EXIF_FORMAT_ASCII;
218 entry->components = 1;
221 entry->data[0] =
'W';
226 entry->data[0] =
'E';
231 entry =
create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, 24);
233 entry->format = EXIF_FORMAT_RATIONAL;
234 entry->components = 3;
239 loc.numerator = lati;
241 exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, loc);
245 loc.numerator = lati;
246 exif_set_rational(entry->data + 8, EXIF_BYTE_ORDER_INTEL, loc);
250 loc.numerator = lati;
251 loc.denominator = 1000;
252 exif_set_rational(entry->data + 16, EXIF_BYTE_ORDER_INTEL, loc);
254 entry =
create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE, 24);
256 entry->format = EXIF_FORMAT_RATIONAL;
257 entry->components = 3;
262 loc.numerator = loni;
264 exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, loc);
268 loc.numerator = loni;
270 exif_set_rational(entry->data + 8, EXIF_BYTE_ORDER_INTEL, loc);
274 loc.numerator = loni;
275 loc.denominator = 1000;
276 exif_set_rational(entry->data + 16, EXIF_BYTE_ORDER_INTEL, loc);
278 entry =
create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_ALTITUDE_REF, 1);
279 entry->format = EXIF_FORMAT_BYTE;
280 entry->components = 1;
290 entry =
create_tag(exif, EXIF_IFD_GPS, EXIF_TAG_GPS_ALTITUDE, 8);
292 entry->format = EXIF_FORMAT_RATIONAL;
293 entry->components = 1;
297 alt.denominator = 1000;
298 exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, alt);
302 exif_data_save_data(exif, &exif_data, &exif_data_len);
305 f = fopen(filename,
"wb");
307 fprintf(stderr,
"Error creating file %s\n", filename);
308 exif_data_unref(exif);
313 fprintf(stderr,
"Error writing to file %s\n", filename);
317 if (fputc((exif_data_len + 2) >> 8, f) < 0) {
318 fprintf(stderr,
"Error writing to file %s\n", filename);
321 if (fputc((exif_data_len + 2) & 0xff, f) < 0) {
322 fprintf(stderr,
"Error writing to file %s\n", filename);
326 if (fwrite(exif_data, exif_data_len, 1, f) != 1) {
327 fprintf(stderr,
"Error writing to file %s\n", filename);
332 fprintf(stderr,
"Error writing to file %s\n", filename);
335 printf(
"Wrote file %s\n", filename);
340 fprintf(stderr,
"Error writing to file %s\n", filename);
347 exif_data_unref(exif);
volatile int32_t lon_em7deg
static const unsigned int image_data_offset
vector in Latitude, Longitude and Altitude
static ExifEntry * create_tag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len)
int32_t alt
in millimeters above WGS84 reference ellipsoid
void push_gps_to_vision(void)
volatile int32_t lat_em7deg
int32_t hmsl
height above mean sea level (MSL) in mm
int write_exif_jpeg(char *filename, const unsigned char *image_jpg, const unsigned int image_jpg_len, const unsigned int image_jpg_x, const unsigned int image_jpg_y)
Device independent GPS code (interface)
int32_t lon
in degrees*1e7
API to get/set the generic vehicle states.
static ExifEntry * init_tag(ExifData *exif, ExifIfd ifd, ExifTag tag)
Write JPEG images containing EXIF headers with GPS coordinates.
static const unsigned int exif_header_len
int32_t lat
in degrees*1e7
struct GpsState gps
global GPS state
static struct LlaCoor_i * stateGetPositionLla_i(void)
Get position in LLA coordinates (int).
static const unsigned char exif_header[]