1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "EmulatedCamera_Exif"
19 #include <log/log.h>
20 #include <cutils/properties.h>
21 
22 #include <inttypes.h>
23 #include <math.h>
24 #include <stdint.h>
25 
26 #include "Exif.h"
27 #include <libexif/exif-data.h>
28 #include <libexif/exif-entry.h>
29 #include <libexif/exif-ifd.h>
30 #include <libexif/exif-tag.h>
31 
32 #include <string>
33 #include <vector>
34 
35 #include "fake-pipeline2/Sensor.h"
36 
37 // For GPS timestamping we want to ensure we use a 64-bit time_t, 32-bit
38 // platforms have time64_t but 64-bit platforms do not.
39 #if defined(__LP64__)
40 #include <time.h>
41 using Timestamp = time_t;
42 #define TIMESTAMP_TO_TM(timestamp, tm) gmtime_r(timestamp, tm)
43 #else
44 #include <time64.h>
45 using Timestamp = time64_t;
46 #define TIMESTAMP_TO_TM(timestamp, tm) gmtime64_r(timestamp, tm)
47 #endif
48 
49 namespace android {
50 
51 // A prefix that is used for tags with the "undefined" format to indicate that
52 // the contents are ASCII encoded. See the user comment section of the EXIF spec
53 // for more details http://www.exif.org/Exif2-2.PDF
54 static const unsigned char kAsciiPrefix[] = {
55     0x41, 0x53, 0x43, 0x49, 0x49, 0x00, 0x00, 0x00 // "ASCII\0\0\0"
56 };
57 
58 // Remove an existing EXIF entry from |exifData| if it exists. This is useful
59 // when replacing existing data, it's easier to just remove the data and
60 // re-allocate it than to adjust the amount of allocated data.
removeExistingEntry(ExifData * exifData,ExifIfd ifd,int tag)61 static void removeExistingEntry(ExifData* exifData, ExifIfd ifd, int tag) {
62     ExifEntry* entry = exif_content_get_entry(exifData->ifd[ifd],
63                                               static_cast<ExifTag>(tag));
64     if (entry) {
65         exif_content_remove_entry(exifData->ifd[ifd], entry);
66     }
67 }
68 
allocateEntry(int tag,ExifFormat format,unsigned int numComponents)69 static ExifEntry* allocateEntry(int tag,
70                                 ExifFormat format,
71                                 unsigned int numComponents) {
72     ExifMem* mem = exif_mem_new_default();
73     ExifEntry* entry = exif_entry_new_mem(mem);
74 
75     unsigned int size = numComponents * exif_format_get_size(format);
76     entry->data = reinterpret_cast<unsigned char*>(exif_mem_alloc(mem, size));
77     entry->size = size;
78     entry->tag = static_cast<ExifTag>(tag);
79     entry->components = numComponents;
80     entry->format = format;
81 
82     exif_mem_unref(mem);
83     return entry;
84 }
85 
86 // Create an entry and place it in |exifData|, the entry is initialized with an
87 // array of floats from |values|
88 template<size_t N>
createEntry(ExifData * exifData,ExifIfd ifd,int tag,const float (& values)[N],float denominator=1000.0)89 static bool createEntry(ExifData* exifData,
90                         ExifIfd ifd,
91                         int tag,
92                         const float (&values)[N],
93                         float denominator = 1000.0) {
94     removeExistingEntry(exifData, ifd, tag);
95     ExifByteOrder byteOrder = exif_data_get_byte_order(exifData);
96     ExifEntry* entry = allocateEntry(tag, EXIF_FORMAT_RATIONAL, N);
97     exif_content_add_entry(exifData->ifd[ifd], entry);
98     unsigned int rationalSize = exif_format_get_size(EXIF_FORMAT_RATIONAL);
99     for (size_t i = 0; i < N; ++i) {
100         ExifRational rational = {
101             static_cast<uint32_t>(values[i] * denominator),
102             static_cast<uint32_t>(denominator)
103         };
104 
105         exif_set_rational(&entry->data[i * rationalSize], byteOrder, rational);
106     }
107 
108     // Unref entry after changing owner to the ExifData struct
109     exif_entry_unref(entry);
110     return true;
111 }
112 
113 // Create an entry with a single float |value| in it and place it in |exifData|
createEntry(ExifData * exifData,ExifIfd ifd,int tag,const float value,float denominator=1000.0)114 static bool createEntry(ExifData* exifData,
115                         ExifIfd ifd,
116                         int tag,
117                         const float value,
118                         float denominator = 1000.0) {
119     float values[1] = { value };
120     // Recycling functions is good for the environment
121     return createEntry(exifData, ifd, tag, values, denominator);
122 }
123 
124 // Create an entry and place it in |exifData|, the entry contains the raw data
125 // pointed to by |data| of length |size|.
createEntry(ExifData * exifData,ExifIfd ifd,int tag,const unsigned char * data,size_t size,ExifFormat format=EXIF_FORMAT_UNDEFINED)126 static bool createEntry(ExifData* exifData,
127                         ExifIfd ifd,
128                         int tag,
129                         const unsigned char* data,
130                         size_t size,
131                         ExifFormat format = EXIF_FORMAT_UNDEFINED) {
132     removeExistingEntry(exifData, ifd, tag);
133     ExifEntry* entry = allocateEntry(tag, format, size);
134     memcpy(entry->data, data, size);
135     exif_content_add_entry(exifData->ifd[ifd], entry);
136     // Unref entry after changing owner to the ExifData struct
137     exif_entry_unref(entry);
138     return true;
139 }
140 
141 // Create an entry and place it in |exifData|, the entry is initialized with
142 // the string provided in |value|
createEntry(ExifData * exifData,ExifIfd ifd,int tag,const char * value)143 static bool createEntry(ExifData* exifData,
144                         ExifIfd ifd,
145                         int tag,
146                         const char* value) {
147     unsigned int length = strlen(value) + 1;
148     const unsigned char* data = reinterpret_cast<const unsigned char*>(value);
149     return createEntry(exifData, ifd, tag, data, length, EXIF_FORMAT_ASCII);
150 }
151 
152 // Create an entry and place it in |exifData|, the entry is initialized with a
153 // single byte in |value|
154 //static bool createEntry(ExifData* exifData,
155 //                        ExifIfd ifd,
156 //                        int tag,
157 //                        uint8_t value) {
158 //    return createEntry(exifData, ifd, tag, &value, 1, EXIF_FORMAT_BYTE);
159 //}
160 
161 // Create an entry and place it in |exifData|, the entry is default initialized
162 // by the exif library based on |tag|
createEntry(ExifData * exifData,ExifIfd ifd,int tag)163 static bool createEntry(ExifData* exifData,
164                         ExifIfd ifd,
165                         int tag) {
166     removeExistingEntry(exifData, ifd, tag);
167     ExifEntry* entry = exif_entry_new();
168     exif_content_add_entry(exifData->ifd[ifd], entry);
169     exif_entry_initialize(entry, static_cast<ExifTag>(tag));
170     // Unref entry after changing owner to the ExifData struct
171     exif_entry_unref(entry);
172     return true;
173 }
174 
175 // Create an entry with a single EXIF LONG (32-bit value) and place it in
176 // |exifData|.
createEntry(ExifData * exifData,ExifIfd ifd,int tag,int value)177 static bool createEntry(ExifData* exifData,
178                         ExifIfd ifd,
179                         int tag,
180                         int value) {
181     removeExistingEntry(exifData, ifd, tag);
182     ExifByteOrder byteOrder = exif_data_get_byte_order(exifData);
183     ExifEntry* entry = allocateEntry(tag, EXIF_FORMAT_LONG, 1);
184     exif_content_add_entry(exifData->ifd[ifd], entry);
185     exif_set_long(entry->data, byteOrder, value);
186 
187     // Unref entry after changing owner to the ExifData struct
188     exif_entry_unref(entry);
189     return true;
190 }
191 
192 // Create an entry with a single EXIF SHORT (16-bit value) and place it in
193 // |exifData|.
createEntry(ExifData * exifData,ExifIfd ifd,int tag,uint16_t value)194 static bool createEntry(ExifData* exifData,
195                         ExifIfd ifd,
196                         int tag,
197                         uint16_t value) {
198     removeExistingEntry(exifData, ifd, tag);
199     ExifByteOrder byteOrder = exif_data_get_byte_order(exifData);
200     ExifEntry* entry = allocateEntry(tag, EXIF_FORMAT_SHORT, 1);
201     exif_content_add_entry(exifData->ifd[ifd], entry);
202     exif_set_short(entry->data, byteOrder, value);
203 
204     // Unref entry after changing owner to the ExifData struct
205     exif_entry_unref(entry);
206     return true;
207 }
208 
getCameraParam(const CameraParameters & parameters,const char * parameterKey,const char ** outValue)209 static bool getCameraParam(const CameraParameters& parameters,
210                            const char* parameterKey,
211                            const char** outValue) {
212     const char* value = parameters.get(parameterKey);
213     if (value) {
214         *outValue = value;
215         return true;
216     }
217     return false;
218 }
219 
getCameraParam(const CameraParameters & parameters,const char * parameterKey,float * outValue)220 static bool getCameraParam(const CameraParameters& parameters,
221                            const char* parameterKey,
222                            float* outValue) {
223     const char* value = parameters.get(parameterKey);
224     if (value) {
225         *outValue = parameters.getFloat(parameterKey);
226         return true;
227     }
228     return false;
229 }
230 
getCameraParam(const CameraParameters & parameters,const char * parameterKey,int64_t * outValue)231 static bool getCameraParam(const CameraParameters& parameters,
232                            const char* parameterKey,
233                            int64_t* outValue) {
234     const char* value = parameters.get(parameterKey);
235     if (value) {
236         char trailing = 0;
237         // Attempt to scan an extra character and then make sure it was not
238         // scanned by checking that the return value indicates only one item.
239         // This way we fail on any trailing characters
240         if (sscanf(value, "%" SCNd64 "%c", outValue, &trailing) == 1) {
241             return true;
242         }
243     }
244     return false;
245 }
246 
247 // Convert a GPS coordinate represented as a decimal degree value to sexagesimal
248 // GPS coordinates comprised of <degrees> <minutes>' <seconds>"
convertGpsCoordinate(float degrees,float (* result)[3])249 static void convertGpsCoordinate(float degrees, float (*result)[3]) {
250     float absDegrees = fabs(degrees);
251     // First value is degrees without any decimal digits
252     (*result)[0] = floor(absDegrees);
253 
254     // Subtract degrees so we only have the fraction left, then multiply by
255     // 60 to get the minutes
256     float minutes = (absDegrees - (*result)[0]) * 60.0f;
257     (*result)[1] = floor(minutes);
258 
259     // Same thing for seconds but here we store seconds with the fraction
260     float seconds = (minutes - (*result)[1]) * 60.0f;
261     (*result)[2] = seconds;
262 }
263 
264 // Convert a UNIX epoch timestamp to a timestamp comprised of three floats for
265 // hour, minute and second, and a date part that is represented as a string.
convertTimestampToTimeAndDate(int64_t timestamp,float (* timeValues)[3],std::string * date)266 static bool convertTimestampToTimeAndDate(int64_t timestamp,
267                                           float (*timeValues)[3],
268                                           std::string* date) {
269     Timestamp time = timestamp;
270     struct tm utcTime;
271     if (TIMESTAMP_TO_TM(&time, &utcTime) == nullptr) {
272         ALOGE("Could not decompose timestamp into components");
273         return false;
274     }
275     (*timeValues)[0] = utcTime.tm_hour;
276     (*timeValues)[1] = utcTime.tm_min;
277     (*timeValues)[2] = utcTime.tm_sec;
278 
279     char buffer[64] = {};
280     if (strftime(buffer, sizeof(buffer), "%Y:%m:%d", &utcTime) == 0) {
281         ALOGE("Could not construct date string from timestamp");
282         return false;
283     }
284     *date = buffer;
285     return true;
286 }
287 
288 // Convert and store key values in CameraMetadata
convertToMetadata(const CameraParameters & src,CameraMetadata & dst)289 static void convertToMetadata(const CameraParameters& src, CameraMetadata& dst) {
290     int64_t longValue;
291     float floatValue, floatGps[3];
292     const char* stringValue;
293 
294     // Orientation
295     if (getCameraParam(src,
296                        CameraParameters::KEY_ROTATION,
297                        &longValue)) {
298         int32_t degrees = (int32_t)longValue;
299         dst.update(ANDROID_JPEG_ORIENTATION, &degrees, 1);
300     }
301     // Focal length
302     if (getCameraParam(src,
303                        CameraParameters::KEY_FOCAL_LENGTH,
304                        &floatValue)) {
305         dst.update(ANDROID_LENS_FOCAL_LENGTH, &floatValue, 1);
306     }
307     // GPS latitude longitude and altitude
308     if (getCameraParam(src,
309                        CameraParameters::KEY_GPS_LATITUDE,
310                        &floatGps[0]) &&
311         getCameraParam(src,
312                        CameraParameters::KEY_GPS_LONGITUDE,
313                        &floatGps[1]) &&
314         getCameraParam(src,
315                        CameraParameters::KEY_GPS_ALTITUDE,
316                        &floatGps[2])) {
317         double gps[3];
318         gps[0] = (double)floatGps[0];
319         gps[1] = (double)floatGps[1];
320         gps[2] = (double)floatGps[2];
321         dst.update(ANDROID_JPEG_GPS_COORDINATES, gps, 3);
322     }
323     // GPS timestamp and datestamp
324     if (getCameraParam(src,
325                        CameraParameters::KEY_GPS_TIMESTAMP,
326                        &longValue)) {
327         dst.update(ANDROID_JPEG_GPS_TIMESTAMP, &longValue, 1);
328     }
329     // GPS processing method
330     if (getCameraParam(src,
331                        CameraParameters::KEY_GPS_PROCESSING_METHOD,
332                        &stringValue)) {
333         dst.update(ANDROID_JPEG_GPS_PROCESSING_METHOD, (unsigned char*)stringValue,
334                    strlen(stringValue));
335     }
336 }
337 
338 // Create Exif data common for both HAL1 and HAL3
createExifDataCommon(const CameraMetadata & params,int width,int height)339 static ExifData* createExifDataCommon(const CameraMetadata& params, int width, int height) {
340     ExifData* exifData = exif_data_new();
341 
342     exif_data_set_option(exifData, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
343     exif_data_set_data_type(exifData, EXIF_DATA_TYPE_COMPRESSED);
344     exif_data_set_byte_order(exifData, EXIF_BYTE_ORDER_INTEL);
345 
346     // Create mandatory exif fields and set their default values
347     exif_data_fix(exifData);
348 
349     float triplet[3];
350     const char* stringValue;
351     int32_t degrees;
352     float focalLength;
353 
354     // Datetime, creating and initializing a datetime tag will automatically
355     // set the current date and time in the tag so just do that.
356     createEntry(exifData, EXIF_IFD_0, EXIF_TAG_DATE_TIME);
357 
358     // Make and model
359     std::vector<char> prop(PROPERTY_VALUE_MAX);
360     property_get("ro.product.manufacturer", &prop[0], "");
361     createEntry(exifData, EXIF_IFD_0, EXIF_TAG_MAKE, &prop[0]);
362     property_get("ro.product.model", &prop[0], "");
363     createEntry(exifData, EXIF_IFD_0, EXIF_TAG_MODEL, &prop[0]);
364 
365     // Width and height
366     if (width > 0 && height > 0) {
367         createEntry(exifData, EXIF_IFD_EXIF,
368                     EXIF_TAG_PIXEL_X_DIMENSION, width);
369         createEntry(exifData, EXIF_IFD_EXIF,
370                     EXIF_TAG_PIXEL_Y_DIMENSION, height);
371     }
372 
373     camera_metadata_ro_entry_t entry;
374     entry = params.find(ANDROID_LENS_FOCAL_LENGTH);
375     focalLength = (entry.count > 0) ? entry.data.f[0] : 5.0f;
376     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, focalLength);
377     entry = params.find(ANDROID_JPEG_ORIENTATION);
378     degrees = (entry.count > 0) ? entry.data.i32[0] : 0;
379     ALOGV("degrees %d focalLength %f", degrees, focalLength);
380     enum {
381         EXIF_ROTATE_CAMERA_CW0 = 1,
382         EXIF_ROTATE_CAMERA_CW90 = 6,
383         EXIF_ROTATE_CAMERA_CW180 = 3,
384         EXIF_ROTATE_CAMERA_CW270 = 8,
385     };
386     uint16_t exifOrien = 1;
387     switch (degrees) {
388         case 0:
389             exifOrien = EXIF_ROTATE_CAMERA_CW0;
390             break;
391         case 90:
392             exifOrien = EXIF_ROTATE_CAMERA_CW90;
393             break;
394         case 180:
395             exifOrien = EXIF_ROTATE_CAMERA_CW180;
396             break;
397         case 270:
398             exifOrien = EXIF_ROTATE_CAMERA_CW270;
399             break;
400     }
401     createEntry(exifData, EXIF_IFD_0, EXIF_TAG_ORIENTATION, exifOrien);
402 
403     // GPS information
404     entry = params.find(ANDROID_JPEG_GPS_COORDINATES);
405     if (entry.count > 0) {
406         ALOGV("Latitude %f Longitude %f Altitude %f", entry.data.d[0], entry.data.d[1], entry.data.d[2]);
407         convertGpsCoordinate(entry.data.d[0], &triplet);
408         createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, triplet);
409 
410         const char* ref = entry.data.d[0] < 0.0f ? "S" : "N";
411         createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF, ref);
412 
413         // GPS longitude and reference, reference indicates sign, store unsigned
414         convertGpsCoordinate(entry.data.d[1], &triplet);
415         createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE, triplet);
416 
417         ref = entry.data.d[1] < 0.0f ? "W" : "E";
418         createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF, ref);
419 
420         createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_ALTITUDE,
421                     static_cast<float>(fabs(entry.data.d[2])));
422         int ref1;
423         // 1 indicated below sea level, 0 indicates above sea level
424         ref1 = entry.data.d[2] < 0.0f ? 1 : 0;
425         createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_ALTITUDE_REF, ref1);
426     }
427 
428     int64_t timestamp = 0;
429     entry = params.find(ANDROID_JPEG_GPS_TIMESTAMP);
430     if (entry.count > 0) {
431         timestamp = entry.data.i64[0];
432         std::string date;
433         if (convertTimestampToTimeAndDate(timestamp, &triplet, &date)) {
434             createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_TIME_STAMP,
435                         triplet, 1.0f);
436             createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_DATE_STAMP,
437                         date.c_str());
438         }
439     }
440 
441     // GPS processing method
442     entry = params.find(ANDROID_JPEG_GPS_PROCESSING_METHOD);
443     if (entry.count > 0) {
444         stringValue = (const char*)entry.data.u8;
445         ALOGV("ANDROID_JPEG_GPS_PROCESSING_METHOD(len=%d) %s", entry.count, stringValue);
446         std::vector<unsigned char> data;
447         // Because this is a tag with an undefined format it has to be prefixed
448         // with the encoding type. Insert an ASCII prefix first, then the
449         // actual string. Undefined tags do not have to be null terminated.
450         data.insert(data.end(),
451                     std::begin(kAsciiPrefix),
452                     std::end(kAsciiPrefix));
453         data.insert(data.end(), stringValue, stringValue + entry.count);
454         createEntry(exifData, EXIF_IFD_GPS, EXIF_TAG_GPS_PROCESSING_METHOD,
455                     &data[0], data.size());
456     }
457     return exifData;
458 }
459 
createExifData(const CameraMetadata & params,int width,int height)460 ExifData* createExifData(const CameraMetadata& params, int width, int height) {
461     ExifData* exifData = createExifDataCommon(params, width, height);
462     // Exposure Time
463     camera_metadata_ro_entry entry;
464     entry= params.find(ANDROID_SENSOR_EXPOSURE_TIME);
465     int64_t exposureTimesNs =
466         (entry.count > 0) ? entry.data.i64[0] : Sensor::kExposureTimeRange[0];
467     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME,
468                 exposureTimesNs/1000000000.0f, 1000000000);
469     // Aperture
470     entry = params.find(ANDROID_LENS_APERTURE);
471     float aperture = (entry.count > 0) ? entry.data.f[0] : 2.8;
472     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, aperture);
473     // Flash, 0 for off
474     entry = params.find(ANDROID_FLASH_MODE);
475     uint16_t flash = (entry.count > 0) ? entry.data.i32[0] : 0;
476     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
477     // White balance, 0 for auto, 1 for manual.
478     entry = params.find(ANDROID_CONTROL_AWB_MODE);
479     uint16_t awb = 1;
480     if (entry.count > 0 && entry.data.i32[0] == ANDROID_CONTROL_AWB_MODE_AUTO) {
481         awb = 0;
482     }
483     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, awb);
484     // ISO
485     entry = params.find(ANDROID_SENSOR_SENSITIVITY);
486     int isoSpeedRating = (entry.count > 0) ?
487         entry.data.i32[0] : Sensor::kSensitivityRange[0];
488     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS,
489                 (uint16_t)isoSpeedRating);
490     // Date and time
491     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED);
492     // Sub second time
493     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME, "0");
494     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_ORIGINAL, "0");
495     createEntry(exifData, EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_DIGITIZED, "0");
496 
497     return exifData;
498 }
499 
createExifData(const CameraParameters & params)500 ExifData* createExifData(const CameraParameters& params) {
501     int width = -1, height = -1;
502     CameraMetadata cameraMetadata;
503     convertToMetadata(params, cameraMetadata);
504     params.getPictureSize(&width, &height);
505     ExifData* exifData =  createExifDataCommon(cameraMetadata, width, height);
506     return exifData;
507 }
508 
freeExifData(ExifData * exifData)509 void freeExifData(ExifData* exifData) {
510     exif_data_free(exifData);
511 }
512 
513 }  // namespace android
514 
515