blob: 4dea8b5d3b97cd2ab9136f63b3ad41dd26494501 [file] [log] [blame]
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001/*
2 * Copyright (C) 2019 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 "CameraServerExifUtils"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
19//#define LOG_NDEBUG 0
20
21#include <cutils/log.h>
22
23#include <inttypes.h>
24#include <math.h>
25#include <stdint.h>
26#include <string>
27#include <vector>
28
29#include "ExifUtils.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
44
45namespace android {
46namespace camera3 {
47
48
49class ExifUtilsImpl : public ExifUtils {
50public:
51 ExifUtilsImpl();
52
53 virtual ~ExifUtilsImpl();
54
55 // Initialize() can be called multiple times. The setting of Exif tags will be
56 // cleared.
57 virtual bool initialize(const unsigned char *app1Segment, size_t app1SegmentSize);
58
59 // set all known fields from a metadata structure
60 virtual bool setFromMetadata(const CameraMetadata& metadata,
Shuzhen Wange7f4b462019-02-12 08:43:07 -080061 const CameraMetadata& staticInfo,
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080062 const size_t imageWidth,
63 const size_t imageHeight);
64
65 // sets the len aperture.
66 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -080067 virtual bool setAperture(float aperture);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080068
69 // sets the color space.
70 // Returns false if memory allocation fails.
71 virtual bool setColorSpace(uint16_t color_space);
72
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080073 // sets the date and time of image last modified. It takes local time. The
74 // name of the tag is DateTime in IFD0.
75 // Returns false if memory allocation fails.
76 virtual bool setDateTime(const struct tm& t);
77
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080078 // sets the digital zoom ratio. If the numerator is 0, it means digital zoom
79 // was not used.
80 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -080081 virtual bool setDigitalZoomRatio(
82 uint32_t crop_width, uint32_t crop_height,
83 uint32_t sensor_width, uint32_t sensor_height);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080084
Shuzhen Wange7f4b462019-02-12 08:43:07 -080085 // Sets the exposure bias.
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080086 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -080087 virtual bool setExposureBias(int32_t ev,
88 uint32_t ev_step_numerator, uint32_t ev_step_denominator);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080089
90 // sets the exposure mode set when the image was shot.
91 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -080092 virtual bool setExposureMode(uint8_t exposure_mode);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080093
94 // sets the exposure time, given in seconds.
95 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -080096 virtual bool setExposureTime(float exposure_time);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080097
98 // sets the status of flash.
99 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800100 virtual bool setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800101
102 // sets the F number.
103 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800104 virtual bool setFNumber(float f_number);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800105
106 // sets the focal length of lens used to take the image in millimeters.
107 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800108 virtual bool setFocalLength(float focal_length);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800109
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800110 // sets the focal length of lens for 35mm film used to take the image in millimeters.
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800111 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800112 virtual bool setFocalLengthIn35mmFilm(float focal_length,
113 float sensor_size_x, float sensor_size_y);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800114
115 // sets the altitude in meters.
116 // Returns false if memory allocation fails.
117 virtual bool setGpsAltitude(double altitude);
118
119 // sets the latitude with degrees minutes seconds format.
120 // Returns false if memory allocation fails.
121 virtual bool setGpsLatitude(double latitude);
122
123 // sets the longitude with degrees minutes seconds format.
124 // Returns false if memory allocation fails.
125 virtual bool setGpsLongitude(double longitude);
126
127 // sets GPS processing method.
128 // Returns false if memory allocation fails.
129 virtual bool setGpsProcessingMethod(const std::string& method);
130
131 // sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
132 // Returns false if memory allocation fails.
133 virtual bool setGpsTimestamp(const struct tm& t);
134
135 // sets the length (number of rows) of main image.
136 // Returns false if memory allocation fails.
137 virtual bool setImageHeight(uint32_t length);
138
139 // sets the width (number of columes) of main image.
140 // Returns false if memory allocation fails.
141 virtual bool setImageWidth(uint32_t width);
142
143 // sets the ISO speed.
144 // Returns false if memory allocation fails.
145 virtual bool setIsoSpeedRating(uint16_t iso_speed_ratings);
146
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800147 // sets the smallest F number of the lens.
148 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800149 virtual bool setMaxAperture(float aperture);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800150
151 // sets image orientation.
152 // Returns false if memory allocation fails.
153 virtual bool setOrientation(uint16_t orientation);
154
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800155 // sets the shutter speed.
156 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800157 virtual bool setShutterSpeed(float exposure_time);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800158
159 // sets the distance to the subject, given in meters.
160 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800161 virtual bool setSubjectDistance(float diopters);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800162
163 // sets the fractions of seconds for the <DateTime> tag.
164 // Returns false if memory allocation fails.
165 virtual bool setSubsecTime(const std::string& subsec_time);
166
167 // sets the white balance mode set when the image was shot.
168 // Returns false if memory allocation fails.
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800169 virtual bool setWhiteBalance(uint8_t white_balance);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800170
171 // Generates APP1 segment.
172 // Returns false if generating APP1 segment fails.
173 virtual bool generateApp1();
174
175 // Gets buffer of APP1 segment. This method must be called only after calling
176 // GenerateAPP1().
177 virtual const uint8_t* getApp1Buffer();
178
179 // Gets length of APP1 segment. This method must be called only after calling
180 // GenerateAPP1().
181 virtual unsigned int getApp1Length();
182
183 protected:
184 // sets the version of this standard supported.
185 // Returns false if memory allocation fails.
186 virtual bool setExifVersion(const std::string& exif_version);
187
188 // Resets the pointers and memories.
189 virtual void reset();
190
191 // Adds a variable length tag to |exif_data_|. It will remove the original one
192 // if the tag exists.
193 // Returns the entry of the tag. The reference count of returned ExifEntry is
194 // two.
195 virtual std::unique_ptr<ExifEntry> addVariableLengthEntry(ExifIfd ifd,
196 ExifTag tag, ExifFormat format, uint64_t components, unsigned int size);
197
198 // Adds a entry of |tag| in |exif_data_|. It won't remove the original one if
199 // the tag exists.
200 // Returns the entry of the tag. It adds one reference count to returned
201 // ExifEntry.
202 virtual std::unique_ptr<ExifEntry> addEntry(ExifIfd ifd, ExifTag tag);
203
204 // Helpe functions to add exif data with different types.
205 virtual bool setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg);
206
207 virtual bool setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg);
208
209 virtual bool setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator,
210 uint32_t denominator, const std::string& msg);
211
212 virtual bool setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator,
213 int32_t denominator, const std::string& msg);
214
215 virtual bool setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
216 const std::string& buffer, const std::string& msg);
217
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800218 float convertToApex(float val) {
219 return 2.0f * log2f(val);
220 }
221
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800222 // Destroys the buffer of APP1 segment if exists.
223 virtual void destroyApp1();
224
225 // The Exif data (APP1). Owned by this class.
226 ExifData* exif_data_;
227 // The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but
228 // owned by this class.
229 uint8_t* app1_buffer_;
230 // The length of |app1_buffer_|.
231 unsigned int app1_length_;
232
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800233 // How precise the float-to-rational conversion for EXIF tags would be.
234 const static int kRationalPrecision = 10000;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800235};
236
237#define SET_SHORT(ifd, tag, value) \
238 do { \
239 if (setShort(ifd, tag, value, #tag) == false) \
240 return false; \
241 } while (0);
242
243#define SET_LONG(ifd, tag, value) \
244 do { \
245 if (setLong(ifd, tag, value, #tag) == false) \
246 return false; \
247 } while (0);
248
249#define SET_RATIONAL(ifd, tag, numerator, denominator) \
250 do { \
251 if (setRational(ifd, tag, numerator, denominator, #tag) == false) \
252 return false; \
253 } while (0);
254
255#define SET_SRATIONAL(ifd, tag, numerator, denominator) \
256 do { \
257 if (setSRational(ifd, tag, numerator, denominator, #tag) == false) \
258 return false; \
259 } while (0);
260
261#define SET_STRING(ifd, tag, format, buffer) \
262 do { \
263 if (setString(ifd, tag, format, buffer, #tag) == false) \
264 return false; \
265 } while (0);
266
267// This comes from the Exif Version 2.2 standard table 6.
268const char gExifAsciiPrefix[] = {0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0};
269
270static void setLatitudeOrLongitudeData(unsigned char* data, double num) {
271 // Take the integer part of |num|.
272 ExifLong degrees = static_cast<ExifLong>(num);
273 ExifLong minutes = static_cast<ExifLong>(60 * (num - degrees));
274 ExifLong microseconds =
275 static_cast<ExifLong>(3600000000u * (num - degrees - minutes / 60.0));
276 exif_set_rational(data, EXIF_BYTE_ORDER_INTEL, {degrees, 1});
277 exif_set_rational(data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL, {minutes, 1});
278 exif_set_rational(data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
279 {microseconds, 1000000});
280}
281
282ExifUtils *ExifUtils::create() {
283 return new ExifUtilsImpl();
284}
285
286ExifUtils::~ExifUtils() {
287}
288
289ExifUtilsImpl::ExifUtilsImpl()
290 : exif_data_(nullptr), app1_buffer_(nullptr), app1_length_(0) {}
291
292ExifUtilsImpl::~ExifUtilsImpl() {
293 reset();
294}
295
296
297bool ExifUtilsImpl::initialize(const unsigned char *app1Segment, size_t app1SegmentSize) {
298 reset();
299 exif_data_ = exif_data_new_from_data(app1Segment, app1SegmentSize);
300 if (exif_data_ == nullptr) {
301 ALOGE("%s: allocate memory for exif_data_ failed", __FUNCTION__);
302 return false;
303 }
304 // set the image options.
305 exif_data_set_option(exif_data_, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
306 exif_data_set_data_type(exif_data_, EXIF_DATA_TYPE_COMPRESSED);
307 exif_data_set_byte_order(exif_data_, EXIF_BYTE_ORDER_INTEL);
308
309 // set exif version to 2.2.
310 if (!setExifVersion("0220")) {
311 return false;
312 }
313
314 return true;
315}
316
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800317bool ExifUtilsImpl::setAperture(float aperture) {
318 float apexValue = convertToApex(aperture);
319 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_APERTURE_VALUE,
320 static_cast<uint32_t>(std::round(apexValue * kRationalPrecision)),
321 kRationalPrecision);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800322 return true;
323}
324
325bool ExifUtilsImpl::setColorSpace(uint16_t color_space) {
326 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_COLOR_SPACE, color_space);
327 return true;
328}
329
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800330bool ExifUtilsImpl::setDateTime(const struct tm& t) {
331 // The length is 20 bytes including NULL for termination in Exif standard.
332 char str[20];
333 int result = snprintf(str, sizeof(str), "%04i:%02i:%02i %02i:%02i:%02i",
334 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
335 if (result != sizeof(str) - 1) {
336 ALOGW("%s: Input time is invalid", __FUNCTION__);
337 return false;
338 }
339 std::string buffer(str);
340 SET_STRING(EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, buffer);
341 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_FORMAT_ASCII, buffer);
342 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_FORMAT_ASCII, buffer);
343 return true;
344}
345
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800346bool ExifUtilsImpl::setDigitalZoomRatio(
347 uint32_t crop_width, uint32_t crop_height,
348 uint32_t sensor_width, uint32_t sensor_height) {
349 float zoomRatioX = (crop_width == 0) ? 1.0 : 1.0 * sensor_width / crop_width;
350 float zoomRatioY = (crop_height == 0) ? 1.0 : 1.0 * sensor_height / crop_height;
351 float zoomRatio = std::max(zoomRatioX, zoomRatioY);
352 const static float noZoomThreshold = 1.02f;
353
354 if (zoomRatio <= noZoomThreshold) {
355 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO, 0, 1);
356 } else {
357 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_DIGITAL_ZOOM_RATIO,
358 static_cast<uint32_t>(std::round(zoomRatio * kRationalPrecision)),
359 kRationalPrecision);
360 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800361 return true;
362}
363
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800364bool ExifUtilsImpl::setExposureMode(uint8_t exposure_mode) {
365 uint16_t exposureMode = (exposure_mode == ANDROID_CONTROL_AE_MODE_OFF) ? 1 : 0;
366 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_MODE, exposureMode);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800367 return true;
368}
369
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800370bool ExifUtilsImpl::setExposureTime(float exposure_time) {
371 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_TIME,
372 static_cast<uint32_t>(std::round(exposure_time * kRationalPrecision)),
373 kRationalPrecision);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800374 return true;
375}
376
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800377bool ExifUtilsImpl::setFlash(uint8_t flash_available, uint8_t flash_state, uint8_t ae_mode) {
378 // EXIF_TAG_FLASH bits layout per EXIF standard:
379 // Bit 0: 0 - did not fire
380 // 1 - fired
381 // Bit 1-2: status of return light
382 // Bit 3-4: 0 - unknown
383 // 1 - compulsory flash firing
384 // 2 - compulsory flash suppression
385 // 3 - auto mode
386 // Bit 5: 0 - flash function present
387 // 1 - no flash function
388 // Bit 6: 0 - no red-eye reduction mode or unknown
389 // 1 - red-eye reduction supported
390 uint16_t flash = 0x20;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800391
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800392 if (flash_available == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
393 flash = 0x00;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800394
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800395 if (flash_state == ANDROID_FLASH_STATE_FIRED) {
396 flash |= 0x1;
397 }
398 if (ae_mode == ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE) {
399 flash |= 0x40;
400 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800401
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800402 uint16_t flashMode = 0;
403 switch (ae_mode) {
404 case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH:
405 case ANDROID_CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
406 flashMode = 3; // AUTO
407 break;
408 case ANDROID_CONTROL_AE_MODE_ON_ALWAYS_FLASH:
409 case ANDROID_CONTROL_AE_MODE_ON_EXTERNAL_FLASH:
410 flashMode = 1; // ON
411 break;
412 case ANDROID_CONTROL_AE_MODE_OFF:
413 case ANDROID_CONTROL_AE_MODE_ON:
414 flashMode = 2; // OFF
415 break;
416 default:
417 flashMode = 0; // UNKNOWN
418 break;
419 }
420 flash |= (flashMode << 3);
421 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800422 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FLASH, flash);
423 return true;
424}
425
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800426bool ExifUtilsImpl::setFNumber(float f_number) {
427 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FNUMBER,
428 static_cast<uint32_t>(std::round(f_number * kRationalPrecision)),
429 kRationalPrecision);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800430 return true;
431}
432
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800433bool ExifUtilsImpl::setFocalLength(float focal_length) {
434 uint32_t numerator = static_cast<uint32_t>(std::round(focal_length * kRationalPrecision));
435 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH, numerator, kRationalPrecision);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800436 return true;
437}
438
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800439bool ExifUtilsImpl::setFocalLengthIn35mmFilm(
440 float focal_length, float sensor_size_x, float sensor_size_y) {
441 static const float filmDiagonal = 43.27; // diagonal of 35mm film
442 static const float minSensorDiagonal = 0.01;
443 float sensorDiagonal = std::sqrt(
444 sensor_size_x * sensor_size_x + sensor_size_y * sensor_size_y);
445 sensorDiagonal = std::max(sensorDiagonal, minSensorDiagonal);
446 float focalLength35mmFilm = std::round(focal_length * filmDiagonal / sensorDiagonal);
447 focalLength35mmFilm = std::min(1.0f * 65535, focalLength35mmFilm);
448
449 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM,
450 static_cast<uint16_t>(focalLength35mmFilm));
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800451 return true;
452}
453
454bool ExifUtilsImpl::setGpsAltitude(double altitude) {
455 ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE_REF);
456 std::unique_ptr<ExifEntry> refEntry =
457 addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_BYTE, 1, 1);
458 if (!refEntry) {
459 ALOGE("%s: Adding GPSAltitudeRef exif entry failed", __FUNCTION__);
460 return false;
461 }
462 if (altitude >= 0) {
463 *refEntry->data = 0;
464 } else {
465 *refEntry->data = 1;
466 altitude *= -1;
467 }
468
469 ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_ALTITUDE);
470 std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
471 EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 1, sizeof(ExifRational));
472 if (!entry) {
473 exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
474 ALOGE("%s: Adding GPSAltitude exif entry failed", __FUNCTION__);
475 return false;
476 }
477 exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
478 {static_cast<ExifLong>(altitude * 1000), 1000});
479
480 return true;
481}
482
483bool ExifUtilsImpl::setGpsLatitude(double latitude) {
484 const ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE_REF);
485 std::unique_ptr<ExifEntry> refEntry =
486 addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
487 if (!refEntry) {
488 ALOGE("%s: Adding GPSLatitudeRef exif entry failed", __FUNCTION__);
489 return false;
490 }
491 if (latitude >= 0) {
492 memcpy(refEntry->data, "N", sizeof("N"));
493 } else {
494 memcpy(refEntry->data, "S", sizeof("S"));
495 latitude *= -1;
496 }
497
498 const ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LATITUDE);
499 std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
500 EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
501 if (!entry) {
502 exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
503 ALOGE("%s: Adding GPSLatitude exif entry failed", __FUNCTION__);
504 return false;
505 }
506 setLatitudeOrLongitudeData(entry->data, latitude);
507
508 return true;
509}
510
511bool ExifUtilsImpl::setGpsLongitude(double longitude) {
512 ExifTag refTag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE_REF);
513 std::unique_ptr<ExifEntry> refEntry =
514 addVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2);
515 if (!refEntry) {
516 ALOGE("%s: Adding GPSLongitudeRef exif entry failed", __FUNCTION__);
517 return false;
518 }
519 if (longitude >= 0) {
520 memcpy(refEntry->data, "E", sizeof("E"));
521 } else {
522 memcpy(refEntry->data, "W", sizeof("W"));
523 longitude *= -1;
524 }
525
526 ExifTag tag = static_cast<ExifTag>(EXIF_TAG_GPS_LONGITUDE);
527 std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(
528 EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational));
529 if (!entry) {
530 exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get());
531 ALOGE("%s: Adding GPSLongitude exif entry failed", __FUNCTION__);
532 return false;
533 }
534 setLatitudeOrLongitudeData(entry->data, longitude);
535
536 return true;
537}
538
539bool ExifUtilsImpl::setGpsProcessingMethod(const std::string& method) {
540 std::string buffer =
541 std::string(gExifAsciiPrefix, sizeof(gExifAsciiPrefix)) + method;
542 SET_STRING(EXIF_IFD_GPS, static_cast<ExifTag>(EXIF_TAG_GPS_PROCESSING_METHOD),
543 EXIF_FORMAT_UNDEFINED, buffer);
544 return true;
545}
546
547bool ExifUtilsImpl::setGpsTimestamp(const struct tm& t) {
548 const ExifTag dateTag = static_cast<ExifTag>(EXIF_TAG_GPS_DATE_STAMP);
549 const size_t kGpsDateStampSize = 11;
550 std::unique_ptr<ExifEntry> entry = addVariableLengthEntry(EXIF_IFD_GPS,
551 dateTag, EXIF_FORMAT_ASCII, kGpsDateStampSize, kGpsDateStampSize);
552 if (!entry) {
553 ALOGE("%s: Adding GPSDateStamp exif entry failed", __FUNCTION__);
554 return false;
555 }
556 int result = snprintf(reinterpret_cast<char*>(entry->data), kGpsDateStampSize,
557 "%04i:%02i:%02i", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday);
558 if (result != kGpsDateStampSize - 1) {
559 ALOGW("%s: Input time is invalid", __FUNCTION__);
560 return false;
561 }
562
563 const ExifTag timeTag = static_cast<ExifTag>(EXIF_TAG_GPS_TIME_STAMP);
564 entry = addVariableLengthEntry(EXIF_IFD_GPS, timeTag, EXIF_FORMAT_RATIONAL, 3,
565 3 * sizeof(ExifRational));
566 if (!entry) {
567 ALOGE("%s: Adding GPSTimeStamp exif entry failed", __FUNCTION__);
568 return false;
569 }
570 exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL,
571 {static_cast<ExifLong>(t.tm_hour), 1});
572 exif_set_rational(entry->data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
573 {static_cast<ExifLong>(t.tm_min), 1});
574 exif_set_rational(entry->data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL,
575 {static_cast<ExifLong>(t.tm_sec), 1});
576
577 return true;
578}
579
580bool ExifUtilsImpl::setImageHeight(uint32_t length) {
581 SET_LONG(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH, length);
582 SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_Y_DIMENSION, length);
583 return true;
584}
585
586bool ExifUtilsImpl::setImageWidth(uint32_t width) {
587 SET_LONG(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH, width);
588 SET_LONG(EXIF_IFD_EXIF, EXIF_TAG_PIXEL_X_DIMENSION, width);
589 return true;
590}
591
592bool ExifUtilsImpl::setIsoSpeedRating(uint16_t iso_speed_ratings) {
593 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_ISO_SPEED_RATINGS, iso_speed_ratings);
594 return true;
595}
596
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800597bool ExifUtilsImpl::setMaxAperture(float aperture) {
598 float maxAperture = convertToApex(aperture);
599 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_MAX_APERTURE_VALUE,
600 static_cast<uint32_t>(std::round(maxAperture * kRationalPrecision)),
601 kRationalPrecision);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800602 return true;
603}
604
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800605bool ExifUtilsImpl::setExposureBias(int32_t ev,
606 uint32_t ev_step_numerator, uint32_t ev_step_denominator) {
607 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_EXPOSURE_BIAS_VALUE,
608 ev * ev_step_numerator, ev_step_denominator);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800609 return true;
610}
611
612bool ExifUtilsImpl::setOrientation(uint16_t orientation) {
613 /*
614 * Orientation value:
615 * 1 2 3 4 5 6 7 8
616 *
617 * 888888 888888 88 88 8888888888 88 88 8888888888
618 * 88 88 88 88 88 88 88 88 88 88 88 88
619 * 8888 8888 8888 8888 88 8888888888 8888888888 88
620 * 88 88 88 88
621 * 88 88 888888 888888
622 */
623 int value = 1;
624 switch (orientation) {
625 case 90:
626 value = 6;
627 break;
628 case 180:
629 value = 3;
630 break;
631 case 270:
632 value = 8;
633 break;
634 default:
635 break;
636 }
637 SET_SHORT(EXIF_IFD_0, EXIF_TAG_ORIENTATION, value);
638 return true;
639}
640
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800641bool ExifUtilsImpl::setShutterSpeed(float exposure_time) {
642 float shutterSpeed = -log2f(exposure_time);
643 SET_SRATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SHUTTER_SPEED_VALUE,
644 static_cast<uint32_t>(shutterSpeed * kRationalPrecision), kRationalPrecision);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800645 return true;
646}
647
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800648bool ExifUtilsImpl::setSubjectDistance(float diopters) {
649 const static float kInfinityDiopters = 1.0e-6;
650 uint32_t numerator, denominator;
651 uint16_t distanceRange;
652 if (diopters > kInfinityDiopters) {
653 float focusDistance = 1.0f / diopters;
654 numerator = static_cast<uint32_t>(std::round(focusDistance * kRationalPrecision));
655 denominator = kRationalPrecision;
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800656
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800657 if (focusDistance < 1.0f) {
658 distanceRange = 1; // Macro
659 } else if (focusDistance < 3.0f) {
660 distanceRange = 2; // Close
661 } else {
662 distanceRange = 3; // Distant
663 }
664 } else {
665 numerator = 0xFFFFFFFF;
666 denominator = 1;
667 distanceRange = 3; // Distant
668 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800669 SET_RATIONAL(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE, numerator, denominator);
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800670 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_SUBJECT_DISTANCE_RANGE, distanceRange);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800671 return true;
672}
673
674bool ExifUtilsImpl::setSubsecTime(const std::string& subsec_time) {
675 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME, EXIF_FORMAT_ASCII, subsec_time);
676 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_ORIGINAL, EXIF_FORMAT_ASCII, subsec_time);
677 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_SUB_SEC_TIME_DIGITIZED, EXIF_FORMAT_ASCII, subsec_time);
678 return true;
679}
680
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800681bool ExifUtilsImpl::setWhiteBalance(uint8_t white_balance) {
682 uint16_t whiteBalance = (white_balance == ANDROID_CONTROL_AWB_MODE_AUTO) ? 0 : 1;
683 SET_SHORT(EXIF_IFD_EXIF, EXIF_TAG_WHITE_BALANCE, whiteBalance);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800684 return true;
685}
686
687bool ExifUtilsImpl::generateApp1() {
688 destroyApp1();
689 // Save the result into |app1_buffer_|.
690 exif_data_save_data(exif_data_, &app1_buffer_, &app1_length_);
691 if (!app1_length_) {
692 ALOGE("%s: Allocate memory for app1_buffer_ failed", __FUNCTION__);
693 return false;
694 }
695 /*
696 * The JPEG segment size is 16 bits in spec. The size of APP1 segment should
697 * be smaller than 65533 because there are two bytes for segment size field.
698 */
699 if (app1_length_ > 65533) {
700 destroyApp1();
701 ALOGE("%s: The size of APP1 segment is too large", __FUNCTION__);
702 return false;
703 }
704 return true;
705}
706
707const uint8_t* ExifUtilsImpl::getApp1Buffer() {
708 return app1_buffer_;
709}
710
711unsigned int ExifUtilsImpl::getApp1Length() {
712 return app1_length_;
713}
714
715bool ExifUtilsImpl::setExifVersion(const std::string& exif_version) {
716 SET_STRING(EXIF_IFD_EXIF, EXIF_TAG_EXIF_VERSION, EXIF_FORMAT_UNDEFINED, exif_version);
717 return true;
718}
719
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800720void ExifUtilsImpl::reset() {
721 destroyApp1();
722 if (exif_data_) {
723 /*
724 * Since we decided to ignore the original APP1, we are sure that there is
725 * no thumbnail allocated by libexif. |exif_data_->data| is actually
726 * allocated by JpegCompressor. sets |exif_data_->data| to nullptr to
727 * prevent exif_data_unref() destroy it incorrectly.
728 */
729 exif_data_->data = nullptr;
730 exif_data_->size = 0;
731 exif_data_unref(exif_data_);
732 exif_data_ = nullptr;
733 }
734}
735
736std::unique_ptr<ExifEntry> ExifUtilsImpl::addVariableLengthEntry(ExifIfd ifd,
737 ExifTag tag, ExifFormat format, uint64_t components, unsigned int size) {
738 // Remove old entry if exists.
739 exif_content_remove_entry(exif_data_->ifd[ifd],
740 exif_content_get_entry(exif_data_->ifd[ifd], tag));
741 ExifMem* mem = exif_mem_new_default();
742 if (!mem) {
743 ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
744 return nullptr;
745 }
746 std::unique_ptr<ExifEntry> entry(exif_entry_new_mem(mem));
747 if (!entry) {
748 ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
749 exif_mem_unref(mem);
750 return nullptr;
751 }
752 void* tmpBuffer = exif_mem_alloc(mem, size);
753 if (!tmpBuffer) {
754 ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
755 exif_mem_unref(mem);
756 return nullptr;
757 }
758
759 entry->data = static_cast<unsigned char*>(tmpBuffer);
760 entry->tag = tag;
761 entry->format = format;
762 entry->components = components;
763 entry->size = size;
764
765 exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
766 exif_mem_unref(mem);
767
768 return entry;
769}
770
771std::unique_ptr<ExifEntry> ExifUtilsImpl::addEntry(ExifIfd ifd, ExifTag tag) {
772 std::unique_ptr<ExifEntry> entry(exif_content_get_entry(exif_data_->ifd[ifd], tag));
773 if (entry) {
774 // exif_content_get_entry() won't ref the entry, so we ref here.
775 exif_entry_ref(entry.get());
776 return entry;
777 }
778 entry.reset(exif_entry_new());
779 if (!entry) {
780 ALOGE("%s: Allocate memory for exif entry failed", __FUNCTION__);
781 return nullptr;
782 }
783 entry->tag = tag;
784 exif_content_add_entry(exif_data_->ifd[ifd], entry.get());
785 exif_entry_initialize(entry.get(), tag);
786 return entry;
787}
788
789bool ExifUtilsImpl::setShort(ExifIfd ifd, ExifTag tag, uint16_t value, const std::string& msg) {
790 std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
791 if (!entry) {
792 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
793 return false;
794 }
795 exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, value);
796 return true;
797}
798
799bool ExifUtilsImpl::setLong(ExifIfd ifd, ExifTag tag, uint32_t value, const std::string& msg) {
800 std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
801 if (!entry) {
802 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
803 return false;
804 }
805 exif_set_long(entry->data, EXIF_BYTE_ORDER_INTEL, value);
806 return true;
807}
808
809bool ExifUtilsImpl::setRational(ExifIfd ifd, ExifTag tag, uint32_t numerator,
810 uint32_t denominator, const std::string& msg) {
811 std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
812 if (!entry) {
813 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
814 return false;
815 }
816 exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
817 return true;
818}
819
820bool ExifUtilsImpl::setSRational(ExifIfd ifd, ExifTag tag, int32_t numerator,
821 int32_t denominator, const std::string& msg) {
822 std::unique_ptr<ExifEntry> entry = addEntry(ifd, tag);
823 if (!entry) {
824 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
825 return false;
826 }
827 exif_set_srational(entry->data, EXIF_BYTE_ORDER_INTEL, {numerator, denominator});
828 return true;
829}
830
831bool ExifUtilsImpl::setString(ExifIfd ifd, ExifTag tag, ExifFormat format,
832 const std::string& buffer, const std::string& msg) {
833 size_t entry_size = buffer.length();
834 // Since the exif format is undefined, NULL termination is not necessary.
835 if (format == EXIF_FORMAT_ASCII) {
836 entry_size++;
837 }
838 std::unique_ptr<ExifEntry> entry =
839 addVariableLengthEntry(ifd, tag, format, entry_size, entry_size);
840 if (!entry) {
841 ALOGE("%s: Adding '%s' entry failed", __FUNCTION__, msg.c_str());
842 return false;
843 }
844 memcpy(entry->data, buffer.c_str(), entry_size);
845 return true;
846}
847
848void ExifUtilsImpl::destroyApp1() {
849 /*
850 * Since there is no API to access ExifMem in ExifData->priv, we use free
851 * here, which is the default free function in libexif. See
852 * exif_data_save_data() for detail.
853 */
854 free(app1_buffer_);
855 app1_buffer_ = nullptr;
856 app1_length_ = 0;
857}
858
859bool ExifUtilsImpl::setFromMetadata(const CameraMetadata& metadata,
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800860 const CameraMetadata& staticInfo,
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800861 const size_t imageWidth, const size_t imageHeight) {
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800862 if (!setImageWidth(imageWidth) ||
863 !setImageHeight(imageHeight)) {
864 ALOGE("%s: setting image resolution failed.", __FUNCTION__);
865 return false;
866 }
867
868 struct timespec tp;
869 struct tm time_info;
870 bool time_available = clock_gettime(CLOCK_REALTIME, &tp) != -1;
871 localtime_r(&tp.tv_sec, &time_info);
872 if (!setDateTime(time_info)) {
873 ALOGE("%s: setting data time failed.", __FUNCTION__);
874 return false;
875 }
876
877 float focal_length;
878 camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH);
879 if (entry.count) {
880 focal_length = entry.data.f[0];
881
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800882 if (!setFocalLength(focal_length)) {
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800883 ALOGE("%s: setting focal length failed.", __FUNCTION__);
884 return false;
885 }
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800886
887 camera_metadata_ro_entry sensorSizeEntry =
888 staticInfo.find(ANDROID_SENSOR_INFO_PHYSICAL_SIZE);
889 if (sensorSizeEntry.count == 2) {
890 if (!setFocalLengthIn35mmFilm(
891 focal_length, sensorSizeEntry.data.f[0], sensorSizeEntry.data.f[1])) {
892 ALOGE("%s: setting focal length in 35mm failed.", __FUNCTION__);
893 return false;
894 }
895 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800896 } else {
897 ALOGV("%s: Cannot find focal length in metadata.", __FUNCTION__);
898 }
899
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800900 if (metadata.exists(ANDROID_SCALER_CROP_REGION) &&
901 staticInfo.exists(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE)) {
902 entry = metadata.find(ANDROID_SCALER_CROP_REGION);
903 camera_metadata_ro_entry activeArrayEntry =
904 staticInfo.find(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE);
905
906 if (!setDigitalZoomRatio(entry.data.i32[2], entry.data.i32[3],
907 activeArrayEntry.data.i32[2], activeArrayEntry.data.i32[3])) {
908 ALOGE("%s: setting digital zoom ratio failed.", __FUNCTION__);
909 return false;
910 }
911 }
912
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800913 if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) {
914 entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES);
915 if (entry.count < 3) {
916 ALOGE("%s: Gps coordinates in metadata is not complete.", __FUNCTION__);
917 return false;
918 }
919 if (!setGpsLatitude(entry.data.d[0])) {
920 ALOGE("%s: setting gps latitude failed.", __FUNCTION__);
921 return false;
922 }
923 if (!setGpsLongitude(entry.data.d[1])) {
924 ALOGE("%s: setting gps longitude failed.", __FUNCTION__);
925 return false;
926 }
927 if (!setGpsAltitude(entry.data.d[2])) {
928 ALOGE("%s: setting gps altitude failed.", __FUNCTION__);
929 return false;
930 }
931 }
932
933 if (metadata.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) {
934 entry = metadata.find(ANDROID_JPEG_GPS_PROCESSING_METHOD);
935 std::string method_str(reinterpret_cast<const char*>(entry.data.u8));
936 if (!setGpsProcessingMethod(method_str)) {
937 ALOGE("%s: setting gps processing method failed.", __FUNCTION__);
938 return false;
939 }
940 }
941
942 if (time_available && metadata.exists(ANDROID_JPEG_GPS_TIMESTAMP)) {
943 entry = metadata.find(ANDROID_JPEG_GPS_TIMESTAMP);
944 time_t timestamp = static_cast<time_t>(entry.data.i64[0]);
945 if (gmtime_r(&timestamp, &time_info)) {
946 if (!setGpsTimestamp(time_info)) {
947 ALOGE("%s: setting gps timestamp failed.", __FUNCTION__);
948 return false;
949 }
950 } else {
951 ALOGE("%s: Time tranformation failed.", __FUNCTION__);
952 return false;
953 }
954 }
955
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800956 if (staticInfo.exists(ANDROID_CONTROL_AE_COMPENSATION_STEP) &&
957 metadata.exists(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION)) {
958 entry = metadata.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION);
959 camera_metadata_ro_entry stepEntry =
960 staticInfo.find(ANDROID_CONTROL_AE_COMPENSATION_STEP);
961 if (!setExposureBias(entry.data.i32[0], stepEntry.data.r[0].numerator,
962 stepEntry.data.r[0].denominator)) {
963 ALOGE("%s: setting exposure bias failed.", __FUNCTION__);
964 return false;
965 }
966 }
967
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800968 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);
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800978 float exposure_time = 1.0f * entry.data.i64[0] / 1e9;
979 if (!setExposureTime(exposure_time)) {
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800980 ALOGE("%s: setting exposure time failed.", __FUNCTION__);
981 return false;
982 }
Shuzhen Wange7f4b462019-02-12 08:43:07 -0800983
984 if (!setShutterSpeed(exposure_time)) {
985 ALOGE("%s: setting shutter speed failed.", __FUNCTION__);
986 return false;
987 }
988 }
989
990 if (metadata.exists(ANDROID_LENS_FOCUS_DISTANCE)) {
991 entry = metadata.find(ANDROID_LENS_FOCUS_DISTANCE);
992 if (!setSubjectDistance(entry.data.f[0])) {
993 ALOGE("%s: setting subject distance failed.", __FUNCTION__);
994 return false;
995 }
996 }
997
998 if (metadata.exists(ANDROID_SENSOR_SENSITIVITY)) {
999 entry = metadata.find(ANDROID_SENSOR_SENSITIVITY);
1000 int32_t iso = entry.data.i32[0];
1001 camera_metadata_ro_entry postRawSensEntry =
1002 metadata.find(ANDROID_CONTROL_POST_RAW_SENSITIVITY_BOOST);
1003 if (postRawSensEntry.count > 0) {
1004 iso = iso * postRawSensEntry.data.i32[0] / 100;
1005 }
1006
1007 if (!setIsoSpeedRating(static_cast<uint16_t>(iso))) {
1008 ALOGE("%s: setting iso rating failed.", __FUNCTION__);
1009 return false;
1010 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001011 }
1012
1013 if (metadata.exists(ANDROID_LENS_APERTURE)) {
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001014 entry = metadata.find(ANDROID_LENS_APERTURE);
Shuzhen Wange7f4b462019-02-12 08:43:07 -08001015 if (!setFNumber(entry.data.f[0])) {
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001016 ALOGE("%s: setting F number failed.", __FUNCTION__);
1017 return false;
1018 }
Shuzhen Wange7f4b462019-02-12 08:43:07 -08001019 if (!setAperture(entry.data.f[0])) {
1020 ALOGE("%s: setting aperture failed.", __FUNCTION__);
1021 return false;
1022 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001023 }
1024
Shuzhen Wange7f4b462019-02-12 08:43:07 -08001025 static const uint16_t kSRGBColorSpace = 1;
1026 if (!setColorSpace(kSRGBColorSpace)) {
1027 ALOGE("%s: setting color space failed.", __FUNCTION__);
1028 return false;
1029 }
1030
1031 if (staticInfo.exists(ANDROID_LENS_INFO_AVAILABLE_APERTURES)) {
1032 entry = staticInfo.find(ANDROID_LENS_INFO_AVAILABLE_APERTURES);
1033 if (!setMaxAperture(entry.data.f[0])) {
1034 ALOGE("%s: setting max aperture failed.", __FUNCTION__);
1035 return false;
1036 }
1037 }
1038
1039 if (staticInfo.exists(ANDROID_FLASH_INFO_AVAILABLE)) {
1040 entry = staticInfo.find(ANDROID_FLASH_INFO_AVAILABLE);
1041 camera_metadata_ro_entry flashStateEntry = metadata.find(ANDROID_FLASH_STATE);
1042 camera_metadata_ro_entry aeModeEntry = metadata.find(ANDROID_CONTROL_AE_MODE);
1043 uint8_t flashState = flashStateEntry.count > 0 ?
1044 flashStateEntry.data.u8[0] : ANDROID_FLASH_STATE_UNAVAILABLE;
1045 uint8_t aeMode = aeModeEntry.count > 0 ?
1046 aeModeEntry.data.u8[0] : ANDROID_CONTROL_AE_MODE_OFF;
1047
1048 if (!setFlash(entry.data.u8[0], flashState, aeMode)) {
1049 ALOGE("%s: setting flash failed.", __FUNCTION__);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001050 return false;
1051 }
1052 }
1053
1054 if (metadata.exists(ANDROID_CONTROL_AWB_MODE)) {
1055 entry = metadata.find(ANDROID_CONTROL_AWB_MODE);
Shuzhen Wange7f4b462019-02-12 08:43:07 -08001056 if (!setWhiteBalance(entry.data.u8[0])) {
1057 ALOGE("%s: setting white balance failed.", __FUNCTION__);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001058 return false;
1059 }
1060 }
1061
Shuzhen Wange7f4b462019-02-12 08:43:07 -08001062 if (metadata.exists(ANDROID_CONTROL_AE_MODE)) {
1063 entry = metadata.find(ANDROID_CONTROL_AE_MODE);
1064 if (!setExposureMode(entry.data.u8[0])) {
1065 ALOGE("%s: setting exposure mode failed.", __FUNCTION__);
1066 return false;
1067 }
1068 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001069 if (time_available) {
1070 char str[4];
1071 if (snprintf(str, sizeof(str), "%03ld", tp.tv_nsec / 1000000) < 0) {
1072 ALOGE("%s: Subsec is invalid: %ld", __FUNCTION__, tp.tv_nsec);
1073 return false;
1074 }
1075 if (!setSubsecTime(std::string(str))) {
1076 ALOGE("%s: setting subsec time failed.", __FUNCTION__);
1077 return false;
1078 }
1079 }
1080
1081 return true;
1082}
1083
1084} // namespace camera3
1085} // namespace android