blob: f4b2a3189e32b987891076548e2683bb5c832f24 [file] [log] [blame]
Yuriy Romanenko33d5f662018-01-23 13:00:17 -08001/*
2 * Copyright (C) 2018 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_TAG "CamComm1.0-Exif"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -070019// #define LOG_NDEBUG 0
Yuriy Romanenko33d5f662018-01-23 13:00:17 -080020
Sasha Smundak769c0532019-01-31 17:19:58 -080021#include <android/log.h>
Yuriy Romanenko33d5f662018-01-23 13:00:17 -080022
23#include <inttypes.h>
24#include <math.h>
25#include <stdint.h>
26#include <string>
27#include <vector>
28
29#include "Exif.h"
30
31extern "C" {
32#include <libexif/exif-data.h>
33}
34
35namespace std {
36
37template <>
38struct default_delete<ExifEntry> {
39 inline void operator()(ExifEntry* entry) const { exif_entry_unref(entry); }
40};
41
42} // namespace std
43
Yuriy Romanenko33d5f662018-01-23 13:00:17 -080044namespace android {
45namespace hardware {
46namespace camera {
47namespace common {
Yuriy Romanenko33d5f662018-01-23 13:00:17 -080048namespace helper {
49
Yuriy Romanenko33d5f662018-01-23 13:00:17 -080050class ExifUtilsImpl : public ExifUtils {
51 public:
52 ExifUtilsImpl();
53
54 virtual ~ExifUtilsImpl();
55
56 // Initialize() can be called multiple times. The setting of Exif tags will be
57 // cleared.
58 virtual bool initialize();
59
60 // set all known fields from a metadata structure
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -070061 virtual bool setFromMetadata(const CameraMetadata& metadata, const size_t imageWidth,
Yuriy Romanenko33d5f662018-01-23 13:00:17 -080062 const size_t imageHeight);
63
64 // sets the len aperture.
65 // Returns false if memory allocation fails.
66 virtual bool setAperture(uint32_t numerator, uint32_t denominator);
67
68 // sets the value of brightness.
69 // Returns false if memory allocation fails.
70 virtual bool setBrightness(int32_t numerator, int32_t denominator);
71
72 // sets the color space.
73 // Returns false if memory allocation fails.
74 virtual bool setColorSpace(uint16_t color_space);
75
76 // sets the information to compressed data.
77 // Returns false if memory allocation fails.
78 virtual bool setComponentsConfiguration(const std::string& components_configuration);
79
80 // sets the compression scheme used for the image data.
81 // Returns false if memory allocation fails.
82 virtual bool setCompression(uint16_t compression);
83
84 // sets image contrast.
85 // Returns false if memory allocation fails.
86 virtual bool setContrast(uint16_t contrast);
87
88 // sets the date and time of image last modified. It takes local time. The
89 // name of the tag is DateTime in IFD0.
90 // Returns false if memory allocation fails.
91 virtual bool setDateTime(const struct tm& t);
92
93 // sets the image description.
94 // Returns false if memory allocation fails.
95 virtual bool setDescription(const std::string& description);
96
97 // sets the digital zoom ratio. If the numerator is 0, it means digital zoom
98 // was not used.
99 // Returns false if memory allocation fails.
100 virtual bool setDigitalZoomRatio(uint32_t numerator, uint32_t denominator);
101
102 // sets the exposure bias.
103 // Returns false if memory allocation fails.
104 virtual bool setExposureBias(int32_t numerator, int32_t denominator);
105
106 // sets the exposure mode set when the image was shot.
107 // Returns false if memory allocation fails.
108 virtual bool setExposureMode(uint16_t exposure_mode);
109
110 // sets the program used by the camera to set exposure when the picture is
111 // taken.
112 // Returns false if memory allocation fails.
113 virtual bool setExposureProgram(uint16_t exposure_program);
114
115 // sets the exposure time, given in seconds.
116 // Returns false if memory allocation fails.
117 virtual bool setExposureTime(uint32_t numerator, uint32_t denominator);
118
119 // sets the status of flash.
120 // Returns false if memory allocation fails.
121 virtual bool setFlash(uint16_t flash);
122
123 // sets the F number.
124 // Returns false if memory allocation fails.
125 virtual bool setFNumber(uint32_t numerator, uint32_t denominator);
126
127 // sets the focal length of lens used to take the image in millimeters.
128 // Returns false if memory allocation fails.
129 virtual bool setFocalLength(uint32_t numerator, uint32_t denominator);
130
131 // sets the degree of overall image gain adjustment.
132 // Returns false if memory allocation fails.
133 virtual bool setGainControl(uint16_t gain_control);
134
135 // sets the altitude in meters.
136 // Returns false if memory allocation fails.
137 virtual bool setGpsAltitude(double altitude);
138
139 // sets the latitude with degrees minutes seconds format.
140 // Returns false if memory allocation fails.
141 virtual bool setGpsLatitude(double latitude);
142
143 // sets the longitude with degrees minutes seconds format.
144 // Returns false if memory allocation fails.
145 virtual bool setGpsLongitude(double longitude);
146
147 // sets GPS processing method.
148 // Returns false if memory allocation fails.
149 virtual bool setGpsProcessingMethod(const std::string& method);
150
151 // sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
152 // Returns false if memory allocation fails.
153 virtual bool setGpsTimestamp(const struct tm& t);
154
155 // sets the length (number of rows) of main image.
156 // Returns false if memory allocation fails.
157 virtual bool setImageHeight(uint32_t length);
158
159 // sets the width (number of columes) of main image.
160 // Returns false if memory allocation fails.
161 virtual bool setImageWidth(uint32_t width);
162
163 // sets the ISO speed.
164 // Returns false if memory allocation fails.
165 virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
166
167 // sets the kind of light source.
168 // Returns false if memory allocation fails.
169 virtual bool setLightSource(uint16_t light_source);
170
171 // sets the smallest F number of the lens.
172 // Returns false if memory allocation fails.
173 virtual bool setMaxAperture(uint32_t numerator, uint32_t denominator);
174
175 // sets the metering mode.
176 // Returns false if memory allocation fails.
177 virtual bool setMeteringMode(uint16_t metering_mode);
178
179 // sets image orientation.
180 // Returns false if memory allocation fails.
181 virtual bool setOrientation(uint16_t orientation);
182
183 // sets the unit for measuring XResolution and YResolution.
184 // Returns false if memory allocation fails.
185 virtual bool setResolutionUnit(uint16_t resolution_unit);
186
187 // sets image saturation.
188 // Returns false if memory allocation fails.
189 virtual bool setSaturation(uint16_t saturation);
190
191 // sets the type of scene that was shot.
192 // Returns false if memory allocation fails.
193 virtual bool setSceneCaptureType(uint16_t type);
194
195 // sets image sharpness.
196 // Returns false if memory allocation fails.
197 virtual bool setSharpness(uint16_t sharpness);
198
199 // sets the shutter speed.
200 // Returns false if memory allocation fails.
201 virtual bool setShutterSpeed(int32_t numerator, int32_t denominator);
202
203 // sets the distance to the subject, given in meters.
204 // Returns false if memory allocation fails.
205 virtual bool setSubjectDistance(uint32_t numerator, uint32_t denominator);
206
207 // sets the fractions of seconds for the <DateTime> tag.
208 // Returns false if memory allocation fails.
209 virtual bool setSubsecTime(const std::string& subsec_time);
210
211 // sets the white balance mode set when the image was shot.
212 // Returns false if memory allocation fails.
213 virtual bool setWhiteBalance(uint16_t white_balance);
214
215 // sets the number of pixels per resolution unit in the image width.
216 // Returns false if memory allocation fails.
217 virtual bool setXResolution(uint32_t numerator, uint32_t denominator);
218
219 // sets the position of chrominance components in relation to the luminance
220 // component.
221 // Returns false if memory allocation fails.
222 virtual bool setYCbCrPositioning(uint16_t ycbcr_positioning);
223
224 // sets the number of pixels per resolution unit in the image length.
225 // Returns false if memory allocation fails.
226 virtual bool setYResolution(uint32_t numerator, uint32_t denominator);
227
228 // sets the manufacturer of camera.
229 // Returns false if memory allocation fails.
230 virtual bool setMake(const std::string& make);
231
232 // sets the model number of camera.
233 // Returns false if memory allocation fails.
234 virtual bool setModel(const std::string& model);
235
236 // Generates APP1 segment.
237 // Returns false if generating APP1 segment fails.
238 virtual bool generateApp1(const void* thumbnail_buffer, uint32_t size);
239
240 // Gets buffer of APP1 segment. This method must be called only after calling
241 // GenerateAPP1().
242 virtual const uint8_t* getApp1Buffer();
243
244 // Gets length of APP1 segment. This method must be called only after calling
245 // GenerateAPP1().
246 virtual unsigned int getApp1Length();
247
248 protected:
249 // sets the version of this standard supported.
250 // Returns false if memory allocation fails.
251 virtual bool setExifVersion(const std::string& exif_version);
252
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800253 // Resets the pointers and memories.
254 virtual void reset();
255
256 // Adds a variable length tag to |exif_data_|. It will remove the original one
257 // if the tag exists.
258 // Returns the entry of the tag. The reference count of returned ExifEntry is
259 // two.
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700260 virtual std::unique_ptr<ExifEntry> addVariableLengthEntry(ExifIfd ifd, ExifTag tag,
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800261 ExifFormat format,
262 uint64_t components,
263 unsigned int size);
264
265 // Adds a entry of |tag| in |exif_data_|. It won't remove the original one if
266 // the tag exists.
267 // Returns the entry of the tag. It adds one reference count to returned
268 // ExifEntry.
269 virtual std::unique_ptr<ExifEntry> addEntry(ExifIfd ifd, ExifTag tag);
270
271 // Helpe functions to add exif data with different types.
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700272 virtual bool setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800273
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700274 virtual bool setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800275
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700276 virtual bool setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator, uint32_t denominator,
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800277 const std::string& msg);
278
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700279 virtual bool setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator, int32_t denominator,
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800280 const std::string& msg);
281
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700282 virtual bool setString(ExifIfd ifd, ExifTag tag, ExifFormat format, const std::string& buffer,
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800283 const std::string& msg);
284
285 // Destroys the buffer of APP1 segment if exists.
286 virtual void destroyApp1();
287
288 // The Exif data (APP1). Owned by this class.
289 ExifData* exif_data_;
290 // The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but
291 // owned by this class.
292 uint8_t* app1_buffer_;
293 // The length of |app1_buffer_|.
294 unsigned int app1_length_;
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800295};
296
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700297#define SET_SHORT(ifd, tag, value) \
298 do { \
299 if (setShort(ifd, tag, value, #tag) == false) return false; \
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800300 } while (0);
301
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700302#define SET_LONG(ifd, tag, value) \
303 do { \
304 if (setLong(ifd, tag, value, #tag) == false) return false; \
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800305 } while (0);
306
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700307#define SET_RATIONAL(ifd, tag, numerator, denominator) \
308 do { \
309 if (setRational(ifd, tag, numerator, denominator, #tag) == false) return false; \
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800310 } while (0);
311
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700312#define SET_SRATIONAL(ifd, tag, numerator, denominator) \
313 do { \
314 if (setSRational(ifd, tag, numerator, denominator, #tag) == false) return false; \
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800315 } while (0);
316
317#define SET_STRING(ifd, tag, format, buffer) \
318 do { \
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700319 if (setString(ifd, tag, format, buffer, #tag) == false) return false; \
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800320 } while (0);
321
322// This comes from the Exif Version 2.2 standard table 6.
323const char gExifAsciiPrefix[] = {0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0};
324
325static void setLatitudeOrLongitudeData(unsigned char* data, double num) {
326 // Take the integer part of |num|.
327 ExifLong degrees = static_cast<ExifLong>(num);
328 ExifLong minutes = static_cast<ExifLong>(60 * (num - degrees));
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700329 ExifLong microseconds = static_cast<ExifLong>(3600000000u * (num - degrees - minutes / 60.0));
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800330 exif_set_rational(data, EXIF_BYTE_ORDER_INTEL, {degrees, 1});
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700331 exif_set_rational(data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL, {minutes, 1});
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800332 exif_set_rational(data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700333 {microseconds, 1000000});
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800334}
335
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700336ExifUtils* ExifUtils::create() {
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800337 return new ExifUtilsImpl();
338}
339
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700340ExifUtils::~ExifUtils() {}
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800341
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700342ExifUtilsImpl::ExifUtilsImpl() : exif_data_(nullptr), app1_buffer_(nullptr), app1_length_(0) {}
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800343
344ExifUtilsImpl::~ExifUtilsImpl() {
345 reset();
346}
347
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800348bool ExifUtilsImpl::initialize() {
349 reset();
350 exif_data_ = exif_data_new();
351 if (exif_data_ == nullptr) {
352 ALOGE("%s: allocate memory for exif_data_ failed", __FUNCTION__);
353 return false;
354 }
355 // set the image options.
356 exif_data_set_option(exif_data_, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
357 exif_data_set_data_type(exif_data_, EXIF_DATA_TYPE_COMPRESSED);
358 exif_data_set_byte_order(exif_data_, EXIF_BYTE_ORDER_INTEL);
359
360 // set exif version to 2.2.
361 if (!setExifVersion("0220")) {
362 return false;
363 }
364
365 return true;
366}
367
368bool ExifUtilsImpl::setAperture(uint32_t numerator, uint32_t denominator) {
369 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE, numerator, denominator);
370 return true;
371}
372
373bool ExifUtilsImpl::setBrightness(int32_t numerator, int32_t denominator) {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700374 SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_BRIGHTNESS_VALUE, numerator, denominator);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800375 return true;
376}
377
378bool ExifUtilsImpl::setColorSpace(uint16_t color_space) {
379 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE, color_space);
380 return true;
381}
382
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700383bool ExifUtilsImpl::setComponentsConfiguration(const std::string& components_configuration) {
384 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_COMPONENTS_CONFIGURATION, EXIF_FORMAT_UNDEFINED,
385 components_configuration);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800386 return true;
387}
388
389bool ExifUtilsImpl::setCompression(uint16_t compression) {
390 SET_SHORT(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);
391 return true;
392}
393
394bool ExifUtilsImpl::setContrast(uint16_t contrast) {
395 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_CONTRAST, contrast);
396 return true;
397}
398
399bool ExifUtilsImpl::setDateTime(const struct tm& t) {
400 // The length is 20 bytes including NULL for termination in Exif standard.
401 char str[20];
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700402 int result = snprintf(str, sizeof(str), "%04i:%02i:%02i %02i:%02i:%02i", t.tm_year + 1900,
403 t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800404 if (result != sizeof(str) - 1) {
405 ALOGW("%s: Input time is invalid", __FUNCTION__);
406 return false;
407 }
408 std::string buffer(str);
409 SET_STRING(EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, buffer);
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700410 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_FORMAT_ASCII, buffer);
411 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_FORMAT_ASCII, buffer);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800412 return true;
413}
414
415bool ExifUtilsImpl::setDescription(const std::string& description) {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700416 SET_STRING(EXIF_IFD_0, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_FORMAT_ASCII, description);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800417 return true;
418}
419
420bool ExifUtilsImpl::setDigitalZoomRatio(uint32_t numerator, uint32_t denominator) {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700421 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, numerator, denominator);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800422 return true;
423}
424
425bool ExifUtilsImpl::setExposureBias(int32_t numerator, int32_t denominator) {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700426 SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE, numerator, denominator);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800427 return true;
428}
429
430bool ExifUtilsImpl::setExposureMode(uint16_t exposure_mode) {
431 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposure_mode);
432 return true;
433}
434
435bool ExifUtilsImpl::setExposureProgram(uint16_t exposure_program) {
436 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_PROGRAM, exposure_program);
437 return true;
438}
439
440bool ExifUtilsImpl::setExposureTime(uint32_t numerator, uint32_t denominator) {
441 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME, numerator, denominator);
442 return true;
443}
444
445bool ExifUtilsImpl::setFlash(uint16_t flash) {
446 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
447 return true;
448}
449
450bool ExifUtilsImpl::setFNumber(uint32_t numerator, uint32_t denominator) {
451 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER, numerator, denominator);
452 return true;
453}
454
455bool ExifUtilsImpl::setFocalLength(uint32_t numerator, uint32_t denominator) {
456 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, denominator);
457 return true;
458}
459
460bool ExifUtilsImpl::setGainControl(uint16_t gain_control) {
461 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_GAIN_CONTROL, gain_control);
462 return true;
463}
464
465bool ExifUtilsImpl::setGpsAltitude(double altitude) {
466 ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF);
467 std::unique_ptr<ExifEntry> refEntry =
468 addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_BYTE, 1, 1);
469 if (!refEntry) {
470 ALOGE("%s: Adding GPSAltitudeRef exif entry failed", __FUNCTION__);
471 return false;
472 }
473 if (altitude >= 0) {
474 *refEntry->data = 0;
475 } else {
476 *refEntry->data = 1;
477 altitude *= -1;
478 }
479
480 ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE);
481 std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
482 EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 1, sizeof(ExifRational));
483 if (!entry) {
484 exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
485 ALOGE("%s: Adding GPSAltitude exif entry failed", __FUNCTION__);
486 return false;
487 }
488 exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700489 {static_cast<ExifLong>(altitude * 1000), 1000});
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800490
491 return true;
492}
493
494bool ExifUtilsImpl::setGpsLatitude(double latitude) {
495 const ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF);
496 std::unique_ptr<ExifEntry> refEntry =
497 addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
498 if (!refEntry) {
499 ALOGE("%s: Adding GPSLatitudeRef exif entry failed", __FUNCTION__);
500 return false;
501 }
502 if (latitude >= 0) {
503 memcpy(refEntry->data, "N", sizeof("N"));
504 } else {
505 memcpy(refEntry->data, "S", sizeof("S"));
506 latitude *= -1;
507 }
508
509 const ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE);
510 std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
511 EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
512 if (!entry) {
513 exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
514 ALOGE("%s: Adding GPSLatitude exif entry failed", __FUNCTION__);
515 return false;
516 }
517 setLatitudeOrLongitudeData(entry->data, latitude);
518
519 return true;
520}
521
522bool ExifUtilsImpl::setGpsLongitude(double longitude) {
523 ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF);
524 std::unique_ptr<ExifEntry> refEntry =
525 addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
526 if (!refEntry) {
527 ALOGE("%s: Adding GPSLongitudeRef exif entry failed", __FUNCTION__);
528 return false;
529 }
530 if (longitude >= 0) {
531 memcpy(refEntry->data, "E", sizeof("E"));
532 } else {
533 memcpy(refEntry->data, "W", sizeof("W"));
534 longitude *= -1;
535 }
536
537 ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE);
538 std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
539 EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
540 if (!entry) {
541 exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
542 ALOGE("%s: Adding GPSLongitude exif entry failed", __FUNCTION__);
543 return false;
544 }
545 setLatitudeOrLongitudeData(entry->data, longitude);
546
547 return true;
548}
549
550bool ExifUtilsImpl::setGpsProcessingMethod(const std::string& method) {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700551 std::string buffer = std::string(gExifAsciiPrefix, sizeof(gExifAsciiPrefix)) + method;
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800552 SET_STRING(EXIF_IFD_GPS, static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD),
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700553 EXIF_FORMAT_UNDEFINED, buffer);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800554 return true;
555}
556
557bool ExifUtilsImpl::setGpsTimestamp(const struct tm& t) {
558 const ExifTag dateTag = static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP);
559 const size_t kGpsDateStampSize = 11;
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700560 std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
561 EXIF_IFD_GPS, dateTag, EXIF_FORMAT_ASCII, kGpsDateStampSize, kGpsDateStampSize);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800562 if (!entry) {
563 ALOGE("%s: Adding GPSDateStamp exif entry failed", __FUNCTION__);
564 return false;
565 }
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700566 int result = snprintf(reinterpret_cast<char*>(entry->data), kGpsDateStampSize, "%04i:%02i:%02i",
567 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800568 if (result != kGpsDateStampSize - 1) {
569 ALOGW("%s: Input time is invalid", __FUNCTION__);
570 return false;
571 }
572
573 const ExifTag timeTag = static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP);
574 entry = addVariableLengthEntry(EXIF_IFD_GPS, timeTag, EXIF_FORMAT_RATIONAL, 3,
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700575 3 * sizeof(ExifRational));
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800576 if (!entry) {
577 ALOGE("%s: Adding GPSTimeStamp exif entry failed", __FUNCTION__);
578 return false;
579 }
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700580 exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, {static_cast<ExifLong>(t.tm_hour), 1});
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800581 exif_set_rational(entry->data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700582 {static_cast<ExifLong>(t.tm_min), 1});
583 exif_set_rational(entry->data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
584 {static_cast<ExifLong>(t.tm_sec), 1});
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800585
586 return true;
587}
588
589bool ExifUtilsImpl::setImageHeight(uint32_t length) {
Emilian Peevaa567332020-02-18 10:16:06 -0800590 SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800591 SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION, length);
592 return true;
593}
594
595bool ExifUtilsImpl::setImageWidth(uint32_t width) {
Emilian Peevaa567332020-02-18 10:16:06 -0800596 SET_SHORT(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800597 SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION, width);
598 return true;
599}
600
601bool ExifUtilsImpl::setIsoSpeedRating(uint16_t iso_speed_ratings) {
602 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, iso_speed_ratings);
603 return true;
604}
605
606bool ExifUtilsImpl::setLightSource(uint16_t light_source) {
607 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_LIGHT_SOURCE, light_source);
608 return true;
609}
610
611bool ExifUtilsImpl::setMaxAperture(uint32_t numerator, uint32_t denominator) {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700612 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE, numerator, denominator);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800613 return true;
614}
615
616bool ExifUtilsImpl::setMeteringMode(uint16_t metering_mode) {
617 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_METERING_MODE, metering_mode);
618 return true;
619}
620
621bool ExifUtilsImpl::setOrientation(uint16_t orientation) {
622 /*
623 * Orientation value:
624 * 1 2 3 4 5 6 7 8
625 *
626 * 888888 888888 88 88 8888888888 88 88 8888888888
627 * 88 88 88 88 88 88 88 88 88 88 88 88
628 * 8888 8888 8888 8888 88 8888888888 8888888888 88
629 * 88 88 88 88
630 * 88 88 888888 888888
631 */
632 int value = 1;
633 switch (orientation) {
634 case 90:
635 value = 6;
636 break;
637 case 180:
638 value = 3;
639 break;
640 case 270:
641 value = 8;
642 break;
643 default:
644 break;
645 }
646 SET_SHORT(EXIF_IFD_0, EXIF_TAG_ORIENTATION, value);
647 return true;
648}
649
650bool ExifUtilsImpl::setResolutionUnit(uint16_t resolution_unit) {
651 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_RESOLUTION_UNIT, resolution_unit);
652 return true;
653}
654
655bool ExifUtilsImpl::setSaturation(uint16_t saturation) {
656 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SATURATION, saturation);
657 return true;
658}
659
660bool ExifUtilsImpl::setSceneCaptureType(uint16_t type) {
661 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SCENE_CAPTURE_TYPE, type);
662 return true;
663}
664
665bool ExifUtilsImpl::setSharpness(uint16_t sharpness) {
666 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SHARPNESS, sharpness);
667 return true;
668}
669
670bool ExifUtilsImpl::setShutterSpeed(int32_t numerator, int32_t denominator) {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700671 SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE, numerator, denominator);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800672 return true;
673}
674
675bool ExifUtilsImpl::setSubjectDistance(uint32_t numerator, uint32_t denominator) {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700676 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator, denominator);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800677 return true;
678}
679
680bool ExifUtilsImpl::setSubsecTime(const std::string& subsec_time) {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700681 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME, EXIF_FORMAT_ASCII, subsec_time);
682 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_ORIGINAL, EXIF_FORMAT_ASCII, subsec_time);
683 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_DIGITIZED, EXIF_FORMAT_ASCII, subsec_time);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800684 return true;
685}
686
687bool ExifUtilsImpl::setWhiteBalance(uint16_t white_balance) {
688 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, white_balance);
689 return true;
690}
691
692bool ExifUtilsImpl::setXResolution(uint32_t numerator, uint32_t denominator) {
693 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_X_RESOLUTION, numerator, denominator);
694 return true;
695}
696
697bool ExifUtilsImpl::setYCbCrPositioning(uint16_t ycbcr_positioning) {
698 SET_SHORT(EXIF_IFD_0, EXIF_TAG_YCBCR_POSITIONING, ycbcr_positioning);
699 return true;
700}
701
702bool ExifUtilsImpl::setYResolution(uint32_t numerator, uint32_t denominator) {
703 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_Y_RESOLUTION, numerator, denominator);
704 return true;
705}
706
707bool ExifUtilsImpl::generateApp1(const void* thumbnail_buffer, uint32_t size) {
708 destroyApp1();
709 exif_data_->data = const_cast<uint8_t*>(static_cast<const uint8_t*>(thumbnail_buffer));
710 exif_data_->size = size;
711 // Save the result into |app1_buffer_|.
712 exif_data_save_data(exif_data_, &app1_buffer_, &app1_length_);
713 if (!app1_length_) {
714 ALOGE("%s: Allocate memory for app1_buffer_ failed", __FUNCTION__);
715 return false;
716 }
717 /*
718 * The JPEG segment size is 16 bits in spec. The size of APP1 segment should
719 * be smaller than 65533 because there are two bytes for segment size field.
720 */
721 if (app1_length_ > 65533) {
722 destroyApp1();
723 ALOGE("%s: The size of APP1 segment is too large", __FUNCTION__);
724 return false;
725 }
726 return true;
727}
728
729const uint8_t* ExifUtilsImpl::getApp1Buffer() {
730 return app1_buffer_;
731}
732
733unsigned int ExifUtilsImpl::getApp1Length() {
734 return app1_length_;
735}
736
737bool ExifUtilsImpl::setExifVersion(const std::string& exif_version) {
738 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_EXIF_VERSION, EXIF_FORMAT_UNDEFINED, exif_version);
739 return true;
740}
741
742bool ExifUtilsImpl::setMake(const std::string& make) {
743 SET_STRING(EXIF_IFD_0, EXIF_TAG_MAKE, EXIF_FORMAT_ASCII, make);
744 return true;
745}
746
747bool ExifUtilsImpl::setModel(const std::string& model) {
748 SET_STRING(EXIF_IFD_0, EXIF_TAG_MODEL, EXIF_FORMAT_ASCII, model);
749 return true;
750}
751
752void ExifUtilsImpl::reset() {
753 destroyApp1();
754 if (exif_data_) {
755 /*
756 * Since we decided to ignore the original APP1, we are sure that there is
757 * no thumbnail allocated by libexif. |exif_data_->data| is actually
758 * allocated by JpegCompressor. sets |exif_data_->data| to nullptr to
759 * prevent exif_data_unref() destroy it incorrectly.
760 */
761 exif_data_->data = nullptr;
762 exif_data_->size = 0;
763 exif_data_unref(exif_data_);
764 exif_data_ = nullptr;
765 }
766}
767
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700768std::unique_ptr<ExifEntry> ExifUtilsImpl::addVariableLengthEntry(ExifIfd ifd, ExifTag tag,
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800769 ExifFormat format,
770 uint64_t components,
771 unsigned int size) {
772 // Remove old entry if exists.
773 exif_content_remove_entry(exif_data_->ifd[ifd],
774 exif_content_get_entry(exif_data_->ifd[ifd], tag));
775 ExifMem* mem = exif_mem_new_default();
776 if (!mem) {
777 ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
778 return nullptr;
779 }
780 std::unique_ptr<ExifEntry> entry(exif_entry_new_mem(mem));
781 if (!entry) {
782 ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
783 exif_mem_unref(mem);
784 return nullptr;
785 }
786 void* tmpBuffer = exif_mem_alloc(mem, size);
787 if (!tmpBuffer) {
788 ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
789 exif_mem_unref(mem);
790 return nullptr;
791 }
792
793 entry->data = static_cast<unsigned char*>(tmpBuffer);
794 entry->tag = tag;
795 entry->format = format;
796 entry->components = components;
797 entry->size = size;
798
799 exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
800 exif_mem_unref(mem);
801
802 return entry;
803}
804
805std::unique_ptr<ExifEntry> ExifUtilsImpl::addEntry(ExifIfd ifd, ExifTag tag) {
806 std::unique_ptr<ExifEntry> entry(exif_content_get_entry(exif_data_->ifd[ifd], tag));
807 if (entry) {
808 // exif_content_get_entry() won't ref the entry, so we ref here.
809 exif_entry_ref(entry.get());
810 return entry;
811 }
812 entry.reset(exif_entry_new());
813 if (!entry) {
814 ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
815 return nullptr;
816 }
817 entry->tag = tag;
818 exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
819 exif_entry_initialize(entry.get(), tag);
820 return entry;
821}
822
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700823bool ExifUtilsImpl::setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg) {
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800824 std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
825 if (!entry) {
826 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
827 return false;
828 }
829 exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, value);
830 return true;
831}
832
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700833bool ExifUtilsImpl::setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg) {
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800834 std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
835 if (!entry) {
836 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
837 return false;
838 }
839 exif_set_long(entry->data, EXIF_BYTE_ORDER_INTEL, value);
840 return true;
841}
842
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700843bool ExifUtilsImpl::setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator, uint32_t denominator,
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800844 const std::string& msg) {
845 std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
846 if (!entry) {
847 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
848 return false;
849 }
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700850 exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800851 return true;
852}
853
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700854bool ExifUtilsImpl::setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator, int32_t denominator,
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800855 const std::string& msg) {
856 std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
857 if (!entry) {
858 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
859 return false;
860 }
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700861 exif_set_srational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800862 return true;
863}
864
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700865bool ExifUtilsImpl::setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
866 const std::string& buffer, const std::string& msg) {
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800867 size_t entry_size = buffer.length();
868 // Since the exif format is undefined, NULL termination is not necessary.
869 if (format == EXIF_FORMAT_ASCII) {
870 entry_size++;
871 }
872 std::unique_ptr<ExifEntry> entry =
873 addVariableLengthEntry(ifd, tag, format, entry_size, entry_size);
874 if (!entry) {
875 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
876 return false;
877 }
878 memcpy(entry->data, buffer.c_str(), entry_size);
879 return true;
880}
881
882void ExifUtilsImpl::destroyApp1() {
883 /*
884 * Since there is no API to access ExifMem in ExifData->priv, we use free
885 * here, which is the default free function in libexif. See
886 * exif_data_save_data() for detail.
887 */
888 free(app1_buffer_);
889 app1_buffer_ = nullptr;
890 app1_length_ = 0;
891}
892
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700893bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata, const size_t imageWidth,
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800894 const size_t imageHeight) {
895 // How precise the float-to-rational conversion for EXIF tags would be.
896 constexpr int kRationalPrecision = 10000;
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700897 if (!setImageWidth(imageWidth) || !setImageHeight(imageHeight)) {
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800898 ALOGE("%s: setting image resolution failed.", __FUNCTION__);
899 return false;
900 }
901
902 struct timespec tp;
903 struct tm time_info;
904 bool time_available = clock_gettime(CLOCK_REALTIME, &tp) != -1;
905 localtime_r(&tp.tv_sec, &time_info);
906 if (!setDateTime(time_info)) {
907 ALOGE("%s: setting data time failed.", __FUNCTION__);
908 return false;
909 }
910
911 float focal_length;
912 camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH);
913 if (entry.count) {
914 focal_length = entry.data.f[0];
Yin-Chia Yeh8b699aa2018-02-28 15:58:54 -0800915
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700916 if (!setFocalLength(static_cast<uint32_t>(focal_length * kRationalPrecision),
917 kRationalPrecision)) {
Yin-Chia Yeh8b699aa2018-02-28 15:58:54 -0800918 ALOGE("%s: setting focal length failed.", __FUNCTION__);
919 return false;
920 }
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800921 } else {
Yin-Chia Yeh8b699aa2018-02-28 15:58:54 -0800922 ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800923 }
924
925 if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
926 entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
927 if (entry.count < 3) {
928 ALOGE("%s: Gps coordinates in metadata is not complete.", __FUNCTION__);
929 return false;
930 }
931 if (!setGpsLatitude(entry.data.d[0])) {
932 ALOGE("%s: setting gps latitude failed.", __FUNCTION__);
933 return false;
934 }
935 if (!setGpsLongitude(entry.data.d[1])) {
936 ALOGE("%s: setting gps longitude failed.", __FUNCTION__);
937 return false;
938 }
939 if (!setGpsAltitude(entry.data.d[2])) {
940 ALOGE("%s: setting gps altitude failed.", __FUNCTION__);
941 return false;
942 }
943 }
944
945 if (metadata.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
946 entry = metadata.find(ANDROID_JPEG_GPS_PROCESSING_METHOD);
947 std::string method_str(reinterpret_cast<const char*>(entry.data.u8));
948 if (!setGpsProcessingMethod(method_str)) {
949 ALOGE("%s: setting gps processing method failed.", __FUNCTION__);
950 return false;
951 }
952 }
953
954 if (time_available && metadata.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
955 entry = metadata.find(ANDROID_JPEG_GPS_TIMESTAMP);
956 time_t timestamp = static_cast<time_t>(entry.data.i64[0]);
957 if (gmtime_r(&timestamp, &time_info)) {
958 if (!setGpsTimestamp(time_info)) {
959 ALOGE("%s: setting gps timestamp failed.", __FUNCTION__);
960 return false;
961 }
962 } else {
963 ALOGE("%s: Time tranformation failed.", __FUNCTION__);
964 return false;
965 }
966 }
967
968 if (metadata.exists(ANDROID_JPEG_ORIENTATION)) {
969 entry = metadata.find(ANDROID_JPEG_ORIENTATION);
970 if (!setOrientation(entry.data.i32[0])) {
971 ALOGE("%s: setting orientation failed.", __FUNCTION__);
972 return false;
973 }
974 }
975
976 if (metadata.exists(ANDROID_SENSOR_EXPOSURE_TIME)) {
977 entry = metadata.find(ANDROID_SENSOR_EXPOSURE_TIME);
978 // int64_t of nanoseconds
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700979 if (!setExposureTime(entry.data.i64[0], 1000000000u)) {
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800980 ALOGE("%s: setting exposure time failed.", __FUNCTION__);
981 return false;
982 }
983 }
984
985 if (metadata.exists(ANDROID_LENS_APERTURE)) {
986 const int kAperturePrecision = 10000;
987 entry = metadata.find(ANDROID_LENS_APERTURE);
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -0700988 if (!setFNumber(entry.data.f[0] * kAperturePrecision, kAperturePrecision)) {
Yuriy Romanenko33d5f662018-01-23 13:00:17 -0800989 ALOGE("%s: setting F number failed.", __FUNCTION__);
990 return false;
991 }
992 }
993
994 if (metadata.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
995 entry = metadata.find(ANDROID_FLASH_INFO_AVAILABLE);
996 if (entry.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_FALSE) {
997 const uint32_t kNoFlashFunction = 0x20;
998 if (!setFlash(kNoFlashFunction)) {
999 ALOGE("%s: setting flash failed.", __FUNCTION__);
1000 return false;
1001 }
1002 } else {
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -07001003 ALOGE("%s: Unsupported flash info: %d", __FUNCTION__, entry.data.u8[0]);
Yuriy Romanenko33d5f662018-01-23 13:00:17 -08001004 return false;
1005 }
1006 }
1007
1008 if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
1009 entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
1010 if (entry.data.u8[0] == ANDROID_CONTROL_AWB_MODE_AUTO) {
1011 const uint16_t kAutoWhiteBalance = 0;
1012 if (!setWhiteBalance(kAutoWhiteBalance)) {
1013 ALOGE("%s: setting white balance failed.", __FUNCTION__);
1014 return false;
1015 }
1016 } else {
1017 ALOGE("%s: Unsupported awb mode: %d", __FUNCTION__, entry.data.u8[0]);
1018 return false;
1019 }
1020 }
1021
1022 if (time_available) {
1023 char str[4];
1024 if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {
1025 ALOGE("%s: Subsec is invalid: %ld", __FUNCTION__, tp.tv_nsec);
1026 return false;
1027 }
1028 if (!setSubsecTime(std::string(str))) {
1029 ALOGE("%s: setting subsec time failed.", __FUNCTION__);
1030 return false;
1031 }
1032 }
1033
1034 return true;
1035}
1036
Avichal Rakesh0d2d8a42022-06-14 17:23:40 -07001037} // namespace helper
1038} // namespace common
1039} // namespace camera
1040} // namespace hardware
1041} // namespace android