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::__anon7dead4430111::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