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