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