• 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 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