1 /*
2  * Copyright (C) 2023 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 FAILURE_DEBUG_PREFIX "exif"
18 
19 #include <vector>
20 
21 #if defined(__LP64__)
22 #include <time.h>
23 using Timestamp = time_t;
24 #define TIMESTAMP_TO_TM(timestamp, tm) gmtime_r(timestamp, tm)
25 #else
26 #include <time64.h>
27 using Timestamp = time64_t;
28 #define TIMESTAMP_TO_TM(timestamp, tm) gmtime64_r(timestamp, tm)
29 #endif
30 
31 #include <math.h>
32 
33 #include <android-base/properties.h>
34 #include <system/camera_metadata.h>
35 
36 #include "exif.h"
37 #include "debug.h"
38 
39 namespace android {
40 namespace hardware {
41 namespace camera {
42 namespace provider {
43 namespace implementation {
44 namespace exif {
45 namespace {
46 
47 struct ExifMemDeleter {
operator ()android::hardware::camera::provider::implementation::exif::__anon57c3d55e0111::ExifMemDeleter48     void operator()(ExifMem* allocator) const {
49         exif_mem_unref(allocator);
50     }
51 };
52 
53 typedef std::unique_ptr<ExifMem, ExifMemDeleter> ExifMemPtr;
54 
allocateEntry(ExifMem * mem,const ExifTag tag,const ExifFormat format,const size_t numComponents)55 ExifEntry* allocateEntry(ExifMem* mem, const ExifTag tag, const ExifFormat format,
56                          const size_t numComponents) {
57     ExifEntry* e = exif_entry_new_mem(mem);
58     const size_t size = numComponents * exif_format_get_size(format);
59     e->data = static_cast<unsigned char*>(exif_mem_alloc(mem, size));
60     e->size = size;
61     e->tag = tag;
62     e->components = numComponents;
63     e->format = format;
64     return e;
65 }
66 
appendEntry(ExifData * edata,ExifMem * mem,const ExifIfd ifd,const ExifTag tag)67 void appendEntry(ExifData* edata, ExifMem* mem,
68                  const ExifIfd ifd, const ExifTag tag) {
69     ExifEntry* e = exif_entry_new_mem(mem);
70     exif_entry_initialize(e, tag);
71     exif_content_add_entry(edata->ifd[ifd], e);
72     exif_entry_unref(e);
73 }
74 
appendEntryU8(ExifData * edata,ExifMem * mem,const ExifIfd ifd,const ExifTag tag,const uint8_t value)75 void appendEntryU8(ExifData* edata, ExifMem* mem,
76                     const ExifIfd ifd, const ExifTag tag,
77                     const uint8_t value) {
78     ExifEntry* e = allocateEntry(mem, tag, EXIF_FORMAT_BYTE, 1);
79     *e->data = value;
80     exif_content_add_entry(edata->ifd[ifd], e);
81     exif_entry_unref(e);
82 }
83 
appendEntryU16(ExifData * edata,ExifMem * mem,const ExifIfd ifd,const ExifTag tag,const uint16_t value)84 void appendEntryU16(ExifData* edata, ExifMem* mem,
85                     const ExifIfd ifd, const ExifTag tag,
86                     const uint16_t value) {
87     ExifEntry* e = allocateEntry(mem, tag, EXIF_FORMAT_SHORT, 1);
88     exif_set_short(e->data, exif_data_get_byte_order(edata), value);
89     exif_content_add_entry(edata->ifd[ifd], e);
90     exif_entry_unref(e);
91 }
92 
appendEntryU32(ExifData * edata,ExifMem * mem,const ExifIfd ifd,const ExifTag tag,const uint32_t value)93 void appendEntryU32(ExifData* edata, ExifMem* mem,
94                     const ExifIfd ifd, const ExifTag tag,
95                     const uint32_t value) {
96     ExifEntry* e = allocateEntry(mem, tag, EXIF_FORMAT_LONG, 1);
97     exif_set_long(e->data, exif_data_get_byte_order(edata), value);
98     exif_content_add_entry(edata->ifd[ifd], e);
99     exif_entry_unref(e);
100 }
101 
appendEntryR32(ExifData * edata,ExifMem * mem,const ExifIfd ifd,const ExifTag tag,const ExifRational * src,size_t n)102 void appendEntryR32(ExifData* edata, ExifMem* mem,
103                     const ExifIfd ifd, const ExifTag tag,
104                     const ExifRational* src, size_t n) {
105     ExifEntry* e = allocateEntry(mem, tag, EXIF_FORMAT_RATIONAL, n);
106 
107     for (uint8_t* dst = e->data; n > 0; --n, ++src, dst += sizeof(ExifRational)) {
108         exif_set_rational(dst, exif_data_get_byte_order(edata), *src);
109     }
110 
111     exif_content_add_entry(edata->ifd[ifd], e);
112     exif_entry_unref(e);
113 }
114 
appendEntryR32(ExifData * edata,ExifMem * mem,const ExifIfd ifd,const ExifTag tag,const uint32_t num,const uint32_t dem)115 void appendEntryR32(ExifData* edata, ExifMem* mem,
116                     const ExifIfd ifd, const ExifTag tag,
117                     const uint32_t num, const uint32_t dem) {
118     const ExifRational value = { num, dem };
119     appendEntryR32(edata, mem, ifd, tag, &value, 1);
120 }
121 
appendEntryS(ExifData * edata,ExifMem * mem,const ExifIfd ifd,const ExifTag tag,const char * value,const size_t size,const ExifFormat format)122 void appendEntryS(ExifData* edata, ExifMem* mem,
123                   const ExifIfd ifd, const ExifTag tag,
124                   const char* value, const size_t size,
125                   const ExifFormat format) {
126     ExifEntry* e = allocateEntry(mem, tag, format, size);
127     memcpy(e->data, value, size);
128     exif_content_add_entry(edata->ifd[ifd], e);
129     exif_entry_unref(e);
130 }
131 
convertDegToDegMmSs(double v)132 std::tuple<uint32_t, uint32_t, uint32_t> convertDegToDegMmSs(double v) {
133     const uint32_t ideg = floor(v);
134     v = (v - ideg) * 60;
135     const uint32_t minutes = floor(v);
136     v = (v - minutes) * 60;
137     const uint32_t secondsM = round(v * 1000000);
138     return {ideg, minutes, secondsM};
139 }
140 
convertT64ToTm(const int64_t t)141 struct tm convertT64ToTm(const int64_t t) {
142     Timestamp t2 = t;
143     struct tm result;
144     TIMESTAMP_TO_TM(&t2, &result);
145     return result;
146 }
147 
148 }  // namespace
149 
createExifData(const CameraMetadata & metadata,const Rect<uint16_t> size)150 ExifDataPtr createExifData(const CameraMetadata& metadata,
151                            const Rect<uint16_t> size) {
152     const camera_metadata_t* const rawMetadata =
153         reinterpret_cast<const camera_metadata_t*>(metadata.metadata.data());
154     camera_metadata_ro_entry_t metadataEntry;
155 
156     ExifMemPtr allocator(exif_mem_new_default());
157     ExifDataPtr exifData(exif_data_new_mem(allocator.get()));
158 
159     exif_data_set_option(exifData.get(), EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
160     exif_data_set_data_type(exifData.get(), EXIF_DATA_TYPE_COMPRESSED);
161     exif_data_set_byte_order(exifData.get(), EXIF_BYTE_ORDER_INTEL);
162     exif_data_fix(exifData.get());
163 
164     {
165         const std::string v = base::GetProperty("ro.product.manufacturer", "");
166         appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_0, EXIF_TAG_MAKE,
167                      v.c_str(), v.size() + 1, EXIF_FORMAT_ASCII);
168     }
169     {
170         const std::string v = base::GetProperty("ro.product.model", "");
171         appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_0, EXIF_TAG_MODEL,
172                      v.c_str(), v.size() + 1, EXIF_FORMAT_ASCII);
173     }
174 
175     {
176         struct tm now;
177         {
178             time_t t = time(nullptr);
179             localtime_r(&t, &now);
180         }
181 
182         char timeStr[20];
183         const int len = snprintf(timeStr, sizeof(timeStr),
184                                  "%04d:%02d:%02d %02d:%02d:%02d",
185                                  now.tm_year + 1900, now.tm_mon + 1, now.tm_mday,
186                                  now.tm_hour, now.tm_min, now.tm_sec) + 1;
187         appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_0,
188                      EXIF_TAG_DATE_TIME, timeStr, len, EXIF_FORMAT_ASCII);
189         appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
190                      EXIF_TAG_DATE_TIME_ORIGINAL, timeStr, len, EXIF_FORMAT_ASCII);
191         appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
192                      EXIF_TAG_DATE_TIME_DIGITIZED, timeStr, len, EXIF_FORMAT_ASCII);
193     }
194     {
195         char ddd[4];
196         const int len = snprintf(ddd, sizeof(ddd), "%03d", 0);
197         appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
198                      EXIF_TAG_SUB_SEC_TIME, ddd, len, EXIF_FORMAT_ASCII);
199         appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
200                      EXIF_TAG_SUB_SEC_TIME_ORIGINAL, ddd, len, EXIF_FORMAT_ASCII);
201         appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
202                      EXIF_TAG_SUB_SEC_TIME_DIGITIZED, ddd, len, EXIF_FORMAT_ASCII);
203     }
204 
205     if ((size.width > 0) && (size.height > 0)) {
206         appendEntryU32(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
207                        EXIF_TAG_PIXEL_X_DIMENSION, size.width);
208         appendEntryU32(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
209                        EXIF_TAG_PIXEL_Y_DIMENSION, size.width);
210     }
211 
212     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_JPEG_ORIENTATION,
213                                        &metadataEntry)) {
214         unsigned v;
215         switch (metadataEntry.data.i32[0]) {
216         default:
217         case 0:     v = 1; break;
218         case 90:    v = 6; break;
219         case 180:   v = 3; break;
220         case 270:   v = 8; break;
221         }
222 
223         appendEntryU16(exifData.get(), allocator.get(), EXIF_IFD_0,
224                        EXIF_TAG_ORIENTATION, v);
225     }
226 
227     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_LENS_APERTURE,
228                                        &metadataEntry)) {
229         const float v = metadataEntry.data.f[0];
230         appendEntryR32(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
231                        EXIF_TAG_FNUMBER, uint32_t(v * 1000U), 1000U);
232     }
233 
234     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_LENS_FOCAL_LENGTH,
235                                        &metadataEntry)) {
236         const float v = metadataEntry.data.f[0];
237         appendEntryR32(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
238                        EXIF_TAG_FOCAL_LENGTH, uint32_t(v * 1000U), 1000U);
239     }
240 
241     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_FLASH_MODE,
242                                        &metadataEntry)) {
243         const unsigned v =
244             (metadataEntry.data.i32[0] == ANDROID_FLASH_MODE_OFF) ? 0 : 1;
245         appendEntryU16(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
246                        EXIF_TAG_FLASH, v);
247     }
248 
249     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_SENSOR_EXPOSURE_TIME,
250                                        &metadataEntry)) {
251         int64_t num = metadataEntry.data.i64[0];
252         uint32_t dem = 1000000000U;
253         while (num > std::numeric_limits<uint32_t>::max()) {
254             num /= 10;
255             dem /= 10;
256         }
257 
258         appendEntryR32(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
259                        EXIF_TAG_EXPOSURE_TIME, uint32_t(num), dem);
260     }
261 
262     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_SENSOR_SENSITIVITY,
263                                        &metadataEntry)) {
264         appendEntryU16(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
265                        EXIF_TAG_ISO_SPEED_RATINGS, metadataEntry.data.i32[0]);
266     }
267 
268     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_CONTROL_AWB_MODE,
269                                        &metadataEntry)) {
270         const unsigned v =
271             (metadataEntry.data.i32[0] == ANDROID_CONTROL_AWB_MODE_AUTO) ? 0 : 1;
272 
273         appendEntryU16(exifData.get(), allocator.get(), EXIF_IFD_EXIF,
274                        EXIF_TAG_WHITE_BALANCE, v);
275     }
276 
277     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_JPEG_GPS_COORDINATES,
278                                        &metadataEntry)) {
279         {
280             const auto [ideg, minutes, secondsM] = convertDegToDegMmSs(
281                 fabs(metadataEntry.data.d[0]));
282             ExifRational degmmss[3] = {{ideg, 1}, {minutes, 1},
283                                        {secondsM, 1000000}};
284             appendEntryR32(exifData.get(), allocator.get(), EXIF_IFD_GPS,
285                            static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE),
286                            degmmss, 3);
287 
288             const char* latRef = (metadataEntry.data.d[0] < 0.0) ? "S" : "N";
289             appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_GPS,
290                          static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF),
291                          latRef, 2, EXIF_FORMAT_ASCII);
292         }
293         {
294             const auto [ideg, minutes, secondsM] = convertDegToDegMmSs(
295                 fabs(metadataEntry.data.d[1]));
296             ExifRational degmmss[3] = {{ideg, 1}, {minutes, 1},
297                                        {secondsM, 1000000}};
298             appendEntryR32(exifData.get(), allocator.get(), EXIF_IFD_GPS,
299                            static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE),
300                            degmmss, 3);
301 
302             const char* latRef = (metadataEntry.data.d[1] < 0.0) ? "W" : "E";
303             appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_GPS,
304                          static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF),
305                          latRef, 2, EXIF_FORMAT_ASCII);
306         }
307         {
308             appendEntryR32(exifData.get(), allocator.get(), EXIF_IFD_GPS,
309                            static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE),
310                            static_cast<uint32_t>(fabs(metadataEntry.data.d[2]) * 1000.0),
311                            1000);
312             appendEntryU8(exifData.get(), allocator.get(), EXIF_IFD_GPS,
313                           static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF),
314                           (metadataEntry.data.d[2] < 0.0) ? 1 : 0);
315         }
316     }
317 
318     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_JPEG_GPS_TIMESTAMP,
319                                        &metadataEntry)) {
320         struct tm gpsTime = convertT64ToTm(metadataEntry.data.i64[0]);
321 
322         {
323             char yyyymmdd[12];
324             const int len = snprintf(yyyymmdd, sizeof(yyyymmdd), "%04d:%02d:%02d",
325                                      gpsTime.tm_year + 1900, gpsTime.tm_mon + 1,
326                                      gpsTime.tm_mday) + 1;
327             appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_GPS,
328                          static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP),
329                          yyyymmdd, len, EXIF_FORMAT_ASCII);
330         }
331         {
332             ExifRational hhmmss[3] = {{static_cast<ExifLong>(gpsTime.tm_hour), 1},
333                                       {static_cast<ExifLong>(gpsTime.tm_min), 1},
334                                       {static_cast<ExifLong>(gpsTime.tm_sec), 1}};
335             appendEntryR32(exifData.get(), allocator.get(), EXIF_IFD_GPS,
336                            static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP),
337                            hhmmss, 3);
338         }
339     }
340 
341     if (!find_camera_metadata_ro_entry(rawMetadata, ANDROID_JPEG_GPS_PROCESSING_METHOD,
342                                        &metadataEntry)) {
343         // EXIF_FORMAT_UNDEFINED requires this prefix
344         std::vector<char> value = {0x41, 0x53, 0x43, 0x49, 0x49, 0x00, 0x00, 0x00};
345         value.insert(value.end(),
346                      reinterpret_cast<const char*>(metadataEntry.data.u8),
347                      reinterpret_cast<const char*>(metadataEntry.data.u8) + metadataEntry.count);
348 
349         appendEntryS(exifData.get(), allocator.get(), EXIF_IFD_GPS,
350                      static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD),
351                      value.data(), value.size(), EXIF_FORMAT_UNDEFINED);
352     }
353 
354     return exifData;
355 }
356 
exifDataAllocThumbnail(ExifData * const edata,const size_t size)357 void* exifDataAllocThumbnail(ExifData* const edata, const size_t size) {
358     // WARNING: maloc and free must match the functions that are used in
359     // exif_mem_new_default (see above) to manage memory. They will be used in
360     // exif_data_free to deallocate memory allocated here.
361     void* mem = malloc(size);
362     if (mem) {
363         if (edata->data) {
364             free(edata->data);
365         }
366         edata->size = size;
367         edata->data = static_cast<uint8_t*>(mem);
368     }
369     return mem;
370 }
371 
operator ()(ExifData * p) const372 void ExifDataDeleter::operator()(ExifData* p) const {
373     exif_data_free(p);
374 }
375 
376 }  // namespace exif
377 }  // namespace implementation
378 }  // namespace provider
379 }  // namespace camera
380 }  // namespace hardware
381 }  // namespace android
382