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