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