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