1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "exif_maker_note.h"
16 #include <memory>
17 #include "exif_info.h"
18 #include "image_log.h"
19 #include "media_errors.h"
20 #include "securec.h"
21 #include "string_ex.h"
22
23 #undef LOG_DOMAIN
24 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_PLUGIN
25
26 #undef LOG_TAG
27 #define LOG_TAG "ExifMakerNote"
28
29 namespace OHOS {
30 namespace ImagePlugin {
31 using namespace Media;
32 namespace {
33 constexpr unsigned char EXIF_HEADER[] = {'E', 'x', 'i', 'f', '\0', '\0'};
34 constexpr unsigned char HW_MNOTE_HEADER[] = { 'H', 'U', 'A', 'W', 'E', 'I', '\0', '\0' };
35 constexpr unsigned char HW_MNOTE_TIFF_II[] = { 'I', 'I', 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00 };
36 constexpr unsigned char HW_MNOTE_TIFF_MM[] = { 'M', 'M', 0x00, 0x2A, 0x00, 0x00, 0x00, 0x80 };
37 constexpr unsigned char HW_MNOTE_IFD_TAIL[] = { 0x00, 0x00, 0x00, 0x00 };
38 constexpr unsigned char JPEG_MARKER_SOI = 0xd8;
39 constexpr unsigned char JPEG_MARKER_APP0 = 0xe0;
40 constexpr unsigned char JPEG_MARKER_APP1 = 0xe1;
41 constexpr unsigned char JPEG_MARKER_APP15 = 0xef;
42 constexpr uint16_t TAG_MOCK = 0xffff;
43 constexpr uint32_t ENTRY_SIZE = 12;
44 constexpr uint32_t BUFFER_SIZE = 16;
45 constexpr uint32_t TEMP_BUFFER_SIZE = 1024;
46 constexpr uint32_t BACK_TO_EXIF_BEFORE = 6;
47 constexpr uint32_t JPEG_TAG_SIZE = 2;
48 constexpr uint32_t JPEG_CHECK_MIN_SIZE = 3;
49 constexpr uint32_t EXIF_MIN_SIZE = 14;
50 const static std::map<uint16_t, std::string> MAKER_TAG_KEY_MAP = {
51 {ExifMakerNote::HW_MNOTE_TAG_CAPTURE_MODE, "HwMnoteCaptureMode"},
52 {ExifMakerNote::HW_MNOTE_TAG_PHYSICAL_APERTURE, "HwMnotePhysicalAperture"},
53 {ExifMakerNote::HW_MNOTE_TAG_ROLL_ANGLE, "HwMnoteRollAngle"},
54 {ExifMakerNote::HW_MNOTE_TAG_PITCH_ANGLE, "HwMnotePitchAngle"},
55 {ExifMakerNote::HW_MNOTE_TAG_SCENE_FOOD_CONF, "HwMnoteSceneFoodConf"},
56 {ExifMakerNote::HW_MNOTE_TAG_SCENE_STAGE_CONF, "HwMnoteSceneStageConf"},
57 {ExifMakerNote::HW_MNOTE_TAG_SCENE_BLUE_SKY_CONF, "HwMnoteSceneBlueSkyConf"},
58 {ExifMakerNote::HW_MNOTE_TAG_SCENE_GREEN_PLANT_CONF, "HwMnoteSceneGreenPlantConf"},
59 {ExifMakerNote::HW_MNOTE_TAG_SCENE_BEACH_CONF, "HwMnoteSceneBeachConf"},
60 {ExifMakerNote::HW_MNOTE_TAG_SCENE_SNOW_CONF, "HwMnoteSceneSnowConf"},
61 {ExifMakerNote::HW_MNOTE_TAG_SCENE_SUNSET_CONF, "HwMnoteSceneSunsetConf"},
62 {ExifMakerNote::HW_MNOTE_TAG_SCENE_FLOWERS_CONF, "HwMnoteSceneFlowersConf"},
63 {ExifMakerNote::HW_MNOTE_TAG_SCENE_NIGHT_CONF, "HwMnoteSceneNightConf"},
64 {ExifMakerNote::HW_MNOTE_TAG_SCENE_TEXT_CONF, "HwMnoteSceneTextConf"},
65 {ExifMakerNote::HW_MNOTE_TAG_FACE_COUNT, "HwMnoteFaceCount"},
66 {ExifMakerNote::HW_MNOTE_TAG_FOCUS_MODE, "HwMnoteFocusMode"},
67 };
68 }
69
ExifItem()70 ExifMakerNote::ExifItem::ExifItem()
71 {
72 }
73
ExifItem(const ExifMakerNote::ExifItem & item)74 ExifMakerNote::ExifItem::ExifItem(const ExifMakerNote::ExifItem& item)
75 {
76 CopyItem(item);
77 }
78
~ExifItem()79 ExifMakerNote::ExifItem::~ExifItem()
80 {
81 data.clear();
82 }
83
operator =(const ExifMakerNote::ExifItem & item)84 ExifMakerNote::ExifItem& ExifMakerNote::ExifItem::operator=(const ExifMakerNote::ExifItem& item)
85 {
86 CopyItem(item);
87
88 return *this;
89 }
90
CopyItem(const ExifMakerNote::ExifItem & item)91 void ExifMakerNote::ExifItem::CopyItem(const ExifMakerNote::ExifItem& item)
92 {
93 ifd = item.ifd;
94 tag = item.tag;
95 format = item.format;
96 count = item.count;
97 data.assign(item.data.begin(), item.data.end());
98 }
99
GetValue(std::string & value,const ExifByteOrder & order,bool mock)100 bool ExifMakerNote::ExifItem::GetValue(std::string &value, const ExifByteOrder &order,
101 bool mock)
102 {
103 return GetValue(value, order, *this, mock);
104 }
105
GetValue(std::string & value,ExifData * exifData,bool mock)106 bool ExifMakerNote::ExifItem::GetValue(std::string &value, ExifData *exifData, bool mock)
107 {
108 return GetValue(value, exifData, *this, mock);
109 }
110
Dump(const std::string & info,const ExifByteOrder & order)111 void ExifMakerNote::ExifItem::Dump(const std::string &info, const ExifByteOrder &order)
112 {
113 Dump(info, *this, order);
114 }
115
GetValue(std::string & value,const ExifByteOrder & order,ExifMakerNote::ExifItem & item,bool mock)116 bool ExifMakerNote::ExifItem::GetValue(std::string &value, const ExifByteOrder &order,
117 ExifMakerNote::ExifItem &item, bool mock)
118 {
119 auto *exifData = exif_data_new();
120 if (exifData == nullptr) {
121 IMAGE_LOGE("GetValue, data is null.");
122 return false;
123 }
124 exif_data_set_byte_order(exifData, order);
125
126 auto ret = GetValue(value, exifData, item, mock);
127
128 exif_data_unref(exifData);
129
130 return ret;
131 }
132
GetValue(std::string & value,ExifData * exifData,ExifMakerNote::ExifItem & item,bool mock)133 bool ExifMakerNote::ExifItem::GetValue(std::string &value, ExifData *exifData,
134 ExifMakerNote::ExifItem &item, bool mock)
135 {
136 auto *exifContent = exif_content_new();
137 if (exifContent == nullptr) {
138 IMAGE_LOGE("GetValue, content is null.");
139 return false;
140 }
141
142 auto *keepParent = exifContent->parent;
143
144 exifContent->parent = exifData;
145
146 auto ret = GetValue(value, exifContent, item, mock);
147
148 exifContent->parent = keepParent;
149
150 exif_content_unref(exifContent);
151
152 return ret;
153 }
154
GetValue(std::string & value,ExifContent * exifContent,ExifMakerNote::ExifItem & item,bool & mock)155 bool ExifMakerNote::ExifItem::GetValue(std::string &value, ExifContent *exifContent,
156 ExifMakerNote::ExifItem &item, bool &mock)
157 {
158 auto *exifEntry = exif_entry_new();
159 if (exifEntry == nullptr) {
160 IMAGE_LOGE("GetValue, item is null.");
161 return false;
162 }
163
164 auto *keepParent = exifEntry->parent;
165 auto keepTag = exifEntry->tag;
166 auto keepFormat = exifEntry->format;
167 auto keepComponents = exifEntry->components;
168 auto *keepData = exifEntry->data;
169 auto keepSize = exifEntry->size;
170
171 exifEntry->parent = exifContent;
172
173 auto ret = GetValue(value, exifEntry, item, mock);
174
175 exifEntry->size = keepSize;
176 exifEntry->data = keepData;
177 exifEntry->components = keepComponents;
178 exifEntry->format = keepFormat;
179 exifEntry->tag = keepTag;
180 exifEntry->parent = keepParent;
181
182 exif_entry_unref(exifEntry);
183
184 return ret;
185 }
186
GetValue(std::string & value,ExifEntry * exifEntry,ExifMakerNote::ExifItem & item,bool & mock)187 bool ExifMakerNote::ExifItem::GetValue(std::string &value, ExifEntry *exifEntry,
188 ExifMakerNote::ExifItem &item, bool &mock)
189 {
190 exifEntry->tag = static_cast<ExifTag>(mock ? TAG_MOCK : item.tag);
191 exifEntry->format = static_cast<ExifFormat>(item.format);
192 exifEntry->components = item.count;
193 exifEntry->data = item.data.data();
194 exifEntry->size = item.data.size();
195
196 auto tmpbuf = std::make_unique<char[]>(TEMP_BUFFER_SIZE);
197
198 exif_entry_get_value(exifEntry, tmpbuf.get(), TEMP_BUFFER_SIZE);
199 value.assign(tmpbuf.get());
200
201 return true;
202 }
203
Dump(const std::string & info,const ExifMakerNote::ExifItem & item,const ExifByteOrder & order)204 void ExifMakerNote::ExifItem::Dump(const std::string &info, const ExifMakerNote::ExifItem &item,
205 const ExifByteOrder &order)
206 {
207 uint32_t dataOrOffset = 0;
208 if (!ExifMakerNote::GetUInt32(item.data, order, 0, dataOrOffset)) {
209 IMAGE_LOGE("ExifMakerNote::ExifItem::Dump, GetUInt32 failed");
210 return;
211 }
212
213 IMAGE_LOGD("%{public}s, "
214 "ifd=0x%{public}x, tag=0x%{public}04x, fmt=%{public}u, cnt=%{public}u, "
215 "dataOrOffset=%{public}u(0x%{public}08x), data=[%{public}s]",
216 info.c_str(),
217 item.ifd, item.tag, item.format, item.count, dataOrOffset, dataOrOffset,
218 ExifMakerNote::Dump(item.data).c_str());
219 }
220
ExifMakerNote()221 ExifMakerNote::ExifMakerNote()
222 {
223 hwCaptureMode = EXIFInfo::DEFAULT_EXIF_VALUE;
224 hwPhysicalAperture = EXIFInfo::DEFAULT_EXIF_VALUE;
225 }
226
~ExifMakerNote()227 ExifMakerNote::~ExifMakerNote()
228 {
229 }
230
Parser(ExifData * exif,const unsigned char * data,uint32_t size)231 uint32_t ExifMakerNote::Parser(ExifData *exif, const unsigned char *data, uint32_t size)
232 {
233 IMAGE_LOGD("Parser enter");
234
235 bool moreCheck = false;
236 uint32_t res = ParserMakerNote(exif, moreCheck);
237 if ((res == Media::SUCCESS) || (!moreCheck)) {
238 IMAGE_LOGD("Parser leave");
239 return Media::SUCCESS;
240 }
241
242 if ((data == nullptr) || (size < sizeof(EXIF_HEADER))) {
243 IMAGE_LOGE("Parser leave. param invalid");
244 return Media::ERROR;
245 }
246
247 const unsigned char *newData = nullptr;
248 uint32_t newSize = 0;
249 if (!FindExifLocation(data, size, newData, newSize)) {
250 IMAGE_LOGE("Parser leave. findExifLocation failed");
251 return Media::ERROR;
252 }
253
254 data = newData - BACK_TO_EXIF_BEFORE;
255 size = newSize + BACK_TO_EXIF_BEFORE;
256
257 ByteOrderedBuffer boBuffer(data, size);
258 boBuffer.GenerateDEArray();
259
260 for (auto &de : boBuffer.directoryEntryArray_) {
261 if (de.tag != EXIF_TAG_MAKER_NOTE) {
262 continue;
263 }
264
265 IMAGE_LOGD("Parser, find, ifd=%{public}u, tag=0x%{public}04x, fmt=%{public}u, "
266 "num=%{public}u, valueOffset=%{public}u, valueLength=%{public}u",
267 de.ifd, de.tag, de.format, de.dataCounts, de.valueOffset, de.valueLength);
268
269 if (ParserMakerNote(data + de.valueOffset, de.valueLength) == Media::SUCCESS) {
270 IMAGE_LOGD("Parser leave");
271 return Media::SUCCESS;
272 }
273 }
274
275 IMAGE_LOGD("Parser leave");
276 return Media::ERROR;
277 }
278
FindExifLocation(const unsigned char * data,uint32_t size,const unsigned char * & newData,uint32_t & newSize)279 bool ExifMakerNote::FindExifLocation(const unsigned char *data, uint32_t size,
280 const unsigned char *&newData, uint32_t &newSize)
281 {
282 IMAGE_LOGD("FindExifLocation enter");
283
284 if (size < sizeof(EXIF_HEADER)) {
285 IMAGE_LOGE("FindExifLocation, small. size=%{public}u", size);
286 return false;
287 }
288
289 const unsigned char *d = data;
290 if (memcmp(d, EXIF_HEADER, sizeof(EXIF_HEADER)) != 0) {
291 if (!FindJpegAPP1(d, size, d, size)) {
292 IMAGE_LOGE("FindExifLocation leave, findJpegAPP1.");
293 return false;
294 }
295
296 d++;
297 size--;
298 unsigned int len = (d[0] << 8) | d[1];
299 IMAGE_LOGD("FindExifLocation, len=%{public}u", len);
300
301 d += JPEG_TAG_SIZE;
302 size -= JPEG_TAG_SIZE;
303 }
304
305 if (size < EXIF_MIN_SIZE) {
306 IMAGE_LOGE("FindExifLocation, small.");
307 return false;
308 }
309
310 if (memcmp(d, EXIF_HEADER, sizeof(EXIF_HEADER)) != 0) {
311 IMAGE_LOGE("FindExifLocation, no found EXIF header");
312 return false;
313 }
314
315 IMAGE_LOGD("FindExifLocation, Found EXIF header");
316
317 newData = d;
318 newSize = size;
319
320 IMAGE_LOGD("FindExifLocation leave");
321 return true;
322 }
323
FindJpegAPP1(const unsigned char * data,uint32_t size,const unsigned char * & newData,uint32_t & newSize)324 bool ExifMakerNote::FindJpegAPP1(const unsigned char *data, uint32_t size,
325 const unsigned char *&newData, uint32_t &newSize)
326 {
327 IMAGE_LOGD("FindJpegAPP1 enter");
328
329 while (size >= JPEG_CHECK_MIN_SIZE) {
330 while (size && (data[0] == 0xff)) {
331 data++;
332 size--;
333 }
334
335 if (size && data[0] == JPEG_MARKER_SOI) {
336 data++;
337 size--;
338 continue;
339 }
340
341 if (size && data[0] == JPEG_MARKER_APP1) {
342 break;
343 }
344
345 if (size >= JPEG_CHECK_MIN_SIZE && data[0] >= JPEG_MARKER_APP0 && data[0] <= JPEG_MARKER_APP15) {
346 data++;
347 size--;
348 unsigned int l = (data[0] << 8) | data[1];
349 if (l > size) {
350 IMAGE_LOGE("FindJpegAPP1, small.");
351 return false;
352 }
353 data += l;
354 size -= l;
355 continue;
356 }
357
358 IMAGE_LOGE("FindJpegAPP1, Unknown.");
359 return false;
360 }
361
362 if (size < JPEG_CHECK_MIN_SIZE) {
363 IMAGE_LOGE("FindJpegAPP1, small2.");
364 return false;
365 }
366
367 newData = data;
368 newSize = size;
369
370 IMAGE_LOGD("FindJpegAPP1 leave");
371 return true;
372 }
373
ParserMakerNote(ExifData * exif,bool & moreCheck)374 uint32_t ExifMakerNote::ParserMakerNote(ExifData* exif, bool &moreCheck)
375 {
376 IMAGE_LOGD("ParserMakerNote enter");
377
378 moreCheck = false;
379
380 if (exif == nullptr) {
381 IMAGE_LOGF("ParserMakerNote, exif is null.");
382 return Media::ERROR;
383 }
384
385 auto *ee = exif_data_get_entry (exif, EXIF_TAG_MAKER_NOTE);
386 auto *md = exif_data_get_mnote_data(exif);
387 if ((ee == nullptr) || (md != nullptr)) {
388 IMAGE_LOGD("ParserMakerNote leave");
389 return Media::ERROR;
390 }
391
392 IMAGE_LOGI("need parser mnote.");
393
394 if (ParserMakerNote(ee->data, ee->size) == Media::SUCCESS) {
395 IMAGE_LOGD("ParserMakerNote leave");
396 return Media::SUCCESS;
397 }
398
399 moreCheck = true;
400
401 IMAGE_LOGD("ParserMakerNote leave");
402 return Media::ERROR;
403 }
404
ParserMakerNote(const unsigned char * data,uint32_t size)405 uint32_t ExifMakerNote::ParserMakerNote(const unsigned char *data, uint32_t size)
406 {
407 IMAGE_LOGD("ParserMakerNote enter");
408
409 if (!IsHwMakerNote(data, size)) {
410 IMAGE_LOGD("ParserMakerNote leave");
411 return Media::ERROR;
412 }
413
414 makerNote_.resize(size);
415 if (memcpy_s(makerNote_.data(), makerNote_.size(), data, size) != 0) {
416 IMAGE_LOGE("memcpy error");
417 return Media::ERROR;
418 }
419
420 ParserHwMakerNote();
421
422 IMAGE_LOGD("ParserMakerNote leave");
423 return Media::SUCCESS;
424 }
425
IsParsed() const426 bool ExifMakerNote::IsParsed() const
427 {
428 return (tiff_offset_ > 0) && (ifd0_offset_ > 0);
429 }
430
IsHwMakerNote(const unsigned char * data,uint32_t size)431 bool ExifMakerNote::IsHwMakerNote(const unsigned char *data, uint32_t size)
432 {
433 IMAGE_LOGD("IsHwMakerNote enter");
434
435 tiff_offset_ = 0;
436 ifd0_offset_ = 0;
437
438 if (sizeof(HW_MNOTE_TIFF_II) != sizeof(HW_MNOTE_TIFF_MM)) {
439 IMAGE_LOGF("IsHwMakerNote leave, same");
440 return false;
441 }
442 if (size < (sizeof(HW_MNOTE_HEADER) + sizeof(HW_MNOTE_TIFF_II))) {
443 IMAGE_LOGD("IsHwMakerNote leave, size");
444 return false;
445 }
446
447 if (memcmp(data, HW_MNOTE_HEADER, sizeof(HW_MNOTE_HEADER)) != 0) {
448 IMAGE_LOGD("IsHwMakerNote leave, hd");
449 return false;
450 }
451
452 tiff_offset_ = sizeof(HW_MNOTE_HEADER);
453
454 if (memcmp((data + tiff_offset_), HW_MNOTE_TIFF_II, sizeof(HW_MNOTE_TIFF_II)) == 0) {
455 order_ = ExifByteOrder::EXIF_BYTE_ORDER_INTEL;
456 ifd0_offset_ = tiff_offset_ + sizeof(HW_MNOTE_TIFF_II);
457 IMAGE_LOGD("IsHwMakerNote leave, ii, tiff=%{public}u, ifd0=%{public}u", tiff_offset_, ifd0_offset_);
458 return true;
459 }
460
461 if (memcmp((data+ tiff_offset_), HW_MNOTE_TIFF_MM, sizeof(HW_MNOTE_TIFF_MM)) == 0) {
462 order_ = ExifByteOrder::EXIF_BYTE_ORDER_MOTOROLA;
463 ifd0_offset_ = tiff_offset_ + sizeof(HW_MNOTE_TIFF_MM);
464 IMAGE_LOGD("IsHwMakerNote leave, mm, tiff=%{public}u, ifd0=%{public}u", tiff_offset_, ifd0_offset_);
465 return true;
466 }
467
468 IMAGE_LOGE("byte order error");
469
470 IMAGE_LOGD("IsHwMakerNote leave, order");
471 return false;
472 }
473
ParserHwMakerNote()474 bool ExifMakerNote::ParserHwMakerNote()
475 {
476 IMAGE_LOGD("ParserHwMakerNote enter");
477
478 bool ret = ParserIFD(ifd0_offset_, HW_MNOTE_IFD_DEFAULT);
479
480 for (auto &entry : items_) {
481 entry.Dump("ParserHwMakerNote", order_);
482
483 std::string value;
484 auto res = entry.GetValue(value, order_, true);
485 if (!res) {
486 continue;
487 }
488
489 SetValue(entry, value);
490 }
491
492 IMAGE_LOGD("ParserHwMakerNote leave, ret=%{public}u", ret);
493 return ret;
494 }
495
ParserIFD(uint32_t offset,uint32_t ifd,uint32_t deep)496 bool ExifMakerNote::ParserIFD(uint32_t offset, uint32_t ifd, uint32_t deep)
497 {
498 IMAGE_LOGD("ParserIFD enter, offset=%{public}u, ifd=%{public}u, deep=%{public}u", offset, ifd, deep);
499
500 uint16_t count = 0;
501 if (!GetUInt16AndMove(offset, count)) {
502 IMAGE_LOGE("ParserIFD leave, count, false");
503 return false;
504 }
505 IMAGE_LOGD("ParserIFD, count=%{public}u", count);
506
507 for (uint16_t i = 0; i < count; i++) {
508 if (ParserItem(offset, ifd, deep)) {
509 offset += (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t));
510 continue;
511 }
512
513 IMAGE_LOGE("ParserIFD leave, entry, false");
514 return false;
515 }
516
517 if (memcmp(makerNote_.data() + offset, HW_MNOTE_IFD_TAIL, sizeof(HW_MNOTE_IFD_TAIL)) != 0) {
518 IMAGE_LOGE("ParserIFD leave, tail, false");
519 return false;
520 }
521
522 IMAGE_LOGD("ParserIFD leave, true");
523 return true;
524 }
525
ParserItem(uint32_t offset,uint32_t ifd,uint32_t deep)526 bool ExifMakerNote::ParserItem(uint32_t offset, uint32_t ifd, uint32_t deep)
527 {
528 IMAGE_LOGD("ParserItem enter, offset=%{public}u, deep=%{public}u, data=[%{public}s]",
529 offset, deep, ExifMakerNote::Dump(makerNote_, offset, ENTRY_SIZE).c_str());
530
531 uint16_t tag = 0;
532 uint16_t format = 0;
533 uint32_t components = 0;
534 uint32_t dataOrOffset = 0;
535 if (!GetUInt16AndMove(offset, tag)) {
536 IMAGE_LOGE("ParserItem leave, tag, false");
537 return false;
538 }
539 if (!GetUInt16AndMove(offset, format)) {
540 IMAGE_LOGE("ParserItem leave, format, false");
541 return false;
542 }
543 if (!GetUInt32AndMove(offset, components)) {
544 IMAGE_LOGE("ParserItem leave, components, false");
545 return false;
546 }
547 if (!GetUInt32(offset, dataOrOffset)) {
548 IMAGE_LOGE("ParserItem leave, data, false");
549 return false;
550 }
551
552 items_.emplace_back(ExifItem());
553 ExifItem &back = items_.back();
554 back.ifd = ifd;
555 back.tag = tag;
556 back.format = format;
557 back.count = components;
558 GetData(offset, sizeof(uint32_t), back.data);
559 back.Dump("ParserItem", order_);
560
561 if (deep > 0) {
562 IMAGE_LOGD("ParserItem leave, deep=%{public}u", deep);
563 return true;
564 }
565
566 if ((back.tag == HW_MNOTE_TAG_SCENE_INFO_OFFSET) || (back.tag == HW_MNOTE_TAG_FACE_INFO_OFFSET)) {
567 if (!ParserIFD((tiff_offset_ + dataOrOffset), back.tag, (deep + 1))) {
568 IMAGE_LOGE("ParserItem leave, ifd, false");
569 return false;
570 }
571 }
572
573 IMAGE_LOGD("ParserItem leave");
574 return true;
575 }
576
SetValue(const ExifItem & entry,const std::string & value)577 bool ExifMakerNote::SetValue(const ExifItem &entry, const std::string &value)
578 {
579 uint16_t tag = entry.tag;
580 if (MAKER_TAG_KEY_MAP.find(tag) != MAKER_TAG_KEY_MAP.end()) {
581 std::string tagName = MAKER_TAG_KEY_MAP.at(tag);
582 makerTagValueMap[tagName] = value;
583 return true;
584 }
585 return false;
586 }
587
GetUInt16AndMove(uint32_t & offset,uint16_t & value)588 bool ExifMakerNote::GetUInt16AndMove(uint32_t &offset, uint16_t &value)
589 {
590 if (GetUInt16(offset, value)) {
591 offset += sizeof(uint16_t);
592 return true;
593 }
594 return false;
595 }
596
GetUInt32AndMove(uint32_t & offset,uint32_t & value)597 bool ExifMakerNote::GetUInt32AndMove(uint32_t &offset, uint32_t &value)
598 {
599 if (GetUInt32(offset, value)) {
600 offset += sizeof(uint32_t);
601 return true;
602 }
603 return false;
604 }
605
GetDataAndMove(size_t & offset,size_t count,std::vector<unsigned char> & value)606 bool ExifMakerNote::GetDataAndMove(size_t &offset, size_t count, std::vector<unsigned char> &value)
607 {
608 if (GetData(offset, count, value)) {
609 offset += count;
610 return true;
611 }
612 return false;
613 }
614
GetUInt16(uint32_t offset,uint16_t & value)615 bool ExifMakerNote::GetUInt16(uint32_t offset, uint16_t &value)
616 {
617 return ExifMakerNote::GetUInt16(makerNote_, order_, offset, value);
618 }
619
GetUInt32(uint32_t offset,uint32_t & value)620 bool ExifMakerNote::GetUInt32(uint32_t offset, uint32_t &value)
621 {
622 return ExifMakerNote::GetUInt32(makerNote_, order_, offset, value);
623 }
624
GetData(size_t offset,size_t count,std::vector<unsigned char> & value)625 bool ExifMakerNote::GetData(size_t offset, size_t count, std::vector<unsigned char> &value)
626 {
627 return ExifMakerNote::GetData(makerNote_, offset, count, value);
628 }
629
GetUInt16(const std::vector<unsigned char> & buffer,ExifByteOrder order,size_t offset,uint16_t & value)630 bool ExifMakerNote::GetUInt16(const std::vector<unsigned char> &buffer, ExifByteOrder order,
631 size_t offset, uint16_t &value)
632 {
633 if ((offset + sizeof(uint16_t)) > buffer.size()) {
634 IMAGE_LOGE("GetUInt16 check error.");
635 return false;
636 }
637 value = exif_get_short(buffer.data() + offset, order);
638 return true;
639 }
640
GetUInt32(const std::vector<unsigned char> & buffer,ExifByteOrder order,size_t offset,uint32_t & value)641 bool ExifMakerNote::GetUInt32(const std::vector<unsigned char> &buffer, ExifByteOrder order,
642 size_t offset, uint32_t &value)
643 {
644 if ((offset + sizeof(uint32_t)) > buffer.size()) {
645 IMAGE_LOGE("GetUInt32 check error.");
646 return false;
647 }
648 value = exif_get_long(buffer.data() + offset, order);
649 return true;
650 }
651
GetData(const std::vector<unsigned char> & buffer,size_t offset,size_t count,std::vector<unsigned char> & value)652 bool ExifMakerNote::GetData(const std::vector<unsigned char> &buffer, size_t offset, size_t count,
653 std::vector<unsigned char> &value)
654 {
655 if ((offset + count) > buffer.size()) {
656 IMAGE_LOGE("GetData check error.");
657 return false;
658 }
659
660 value.resize(count);
661 if (memcpy_s(value.data(), count, buffer.data() + offset, count) != 0) {
662 IMAGE_LOGE("GetData memcpy error.");
663 return false;
664 }
665
666 return true;
667 }
668
Dump(const std::vector<unsigned char> & data,uint32_t offset,uint32_t sum)669 std::string ExifMakerNote::Dump(const std::vector<unsigned char> &data, uint32_t offset, uint32_t sum)
670 {
671 std::string ret;
672 char buffer[BUFFER_SIZE] = {0};
673
674 auto size = data.size();
675 for (size_t loc = 0, cur = offset; ((loc < sum) && (cur < size)); loc++, cur++) {
676 if (loc == 0) {
677 if (sprintf_s(buffer, sizeof(buffer), "%02X", data[cur]) == -1) {
678 IMAGE_LOGE("Dump sprintf error.");
679 break;
680 }
681 } else {
682 if (sprintf_s(buffer, sizeof(buffer), " %02X", data[cur]) == -1) {
683 IMAGE_LOGE("Dump sprintf error.");
684 break;
685 }
686 }
687 ret.append(buffer);
688 }
689
690 return ret;
691 }
692 } // namespace ImagePlugin
693 } // namespace OHOS