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 IMAGE_LOGI("need parser mnote.");
390
391 if (ParserMakerNote(ee->data, ee->size) == Media::SUCCESS) {
392 IMAGE_LOGD("ParserMakerNote leave");
393 return Media::SUCCESS;
394 }
395
396 moreCheck = true;
397
398 IMAGE_LOGD("ParserMakerNote leave");
399 return Media::ERROR;
400 }
401
ParserMakerNote(const unsigned char * data,uint32_t size)402 uint32_t ExifMakerNote::ParserMakerNote(const unsigned char *data, uint32_t size)
403 {
404 IMAGE_LOGD("ParserMakerNote enter");
405
406 if (!IsHwMakerNote(data, size)) {
407 IMAGE_LOGD("ParserMakerNote leave");
408 return Media::ERROR;
409 }
410
411 makerNote_.resize(size);
412 if (memcpy_s(makerNote_.data(), makerNote_.size(), data, size) != 0) {
413 IMAGE_LOGE("memcpy error");
414 return Media::ERROR;
415 }
416
417 ParserHwMakerNote();
418
419 IMAGE_LOGD("ParserMakerNote leave");
420 return Media::SUCCESS;
421 }
422
IsParsed() const423 bool ExifMakerNote::IsParsed() const
424 {
425 return (tiff_offset_ > 0) && (ifd0_offset_ > 0);
426 }
427
IsHwMakerNote(const unsigned char * data,uint32_t size)428 bool ExifMakerNote::IsHwMakerNote(const unsigned char *data, uint32_t size)
429 {
430 IMAGE_LOGD("IsHwMakerNote enter");
431
432 tiff_offset_ = 0;
433 ifd0_offset_ = 0;
434
435 if (sizeof(HW_MNOTE_TIFF_II) != sizeof(HW_MNOTE_TIFF_MM)) {
436 IMAGE_LOGF("IsHwMakerNote leave, same");
437 return false;
438 }
439 if (size < (sizeof(HW_MNOTE_HEADER) + sizeof(HW_MNOTE_TIFF_II))) {
440 IMAGE_LOGD("IsHwMakerNote leave, size");
441 return false;
442 }
443
444 if (memcmp(data, HW_MNOTE_HEADER, sizeof(HW_MNOTE_HEADER)) != 0) {
445 IMAGE_LOGD("IsHwMakerNote leave, hd");
446 return false;
447 }
448
449 tiff_offset_ = sizeof(HW_MNOTE_HEADER);
450
451 if (memcmp((data + tiff_offset_), HW_MNOTE_TIFF_II, sizeof(HW_MNOTE_TIFF_II)) == 0) {
452 order_ = ExifByteOrder::EXIF_BYTE_ORDER_INTEL;
453 ifd0_offset_ = tiff_offset_ + sizeof(HW_MNOTE_TIFF_II);
454 IMAGE_LOGD("IsHwMakerNote leave, ii, tiff=%{public}u, ifd0=%{public}u", tiff_offset_, ifd0_offset_);
455 return true;
456 }
457
458 if (memcmp((data+ tiff_offset_), HW_MNOTE_TIFF_MM, sizeof(HW_MNOTE_TIFF_MM)) == 0) {
459 order_ = ExifByteOrder::EXIF_BYTE_ORDER_MOTOROLA;
460 ifd0_offset_ = tiff_offset_ + sizeof(HW_MNOTE_TIFF_MM);
461 IMAGE_LOGD("IsHwMakerNote leave, mm, tiff=%{public}u, ifd0=%{public}u", tiff_offset_, ifd0_offset_);
462 return true;
463 }
464
465 IMAGE_LOGE("byte order error");
466
467 IMAGE_LOGD("IsHwMakerNote leave, order");
468 return false;
469 }
470
ParserHwMakerNote()471 bool ExifMakerNote::ParserHwMakerNote()
472 {
473 IMAGE_LOGD("ParserHwMakerNote enter");
474
475 bool ret = ParserIFD(ifd0_offset_, HW_MNOTE_IFD_DEFAULT);
476
477 for (auto &entry : items_) {
478 entry.Dump("ParserHwMakerNote", order_);
479
480 std::string value;
481 auto res = entry.GetValue(value, order_, true);
482 if (!res) {
483 continue;
484 }
485
486 SetValue(entry, value);
487 }
488
489 IMAGE_LOGD("ParserHwMakerNote leave, ret=%{public}u", ret);
490 return ret;
491 }
492
ParserIFD(uint32_t offset,uint32_t ifd,uint32_t deep)493 bool ExifMakerNote::ParserIFD(uint32_t offset, uint32_t ifd, uint32_t deep)
494 {
495 IMAGE_LOGD("ParserIFD enter, offset=%{public}u, ifd=%{public}u, deep=%{public}u", offset, ifd, deep);
496
497 uint16_t count = 0;
498 if (!GetUInt16AndMove(offset, count)) {
499 IMAGE_LOGE("ParserIFD leave, count, false");
500 return false;
501 }
502 IMAGE_LOGD("ParserIFD, count=%{public}u", count);
503
504 for (uint16_t i = 0; i < count; i++) {
505 if (ParserItem(offset, ifd, deep)) {
506 offset += (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t));
507 continue;
508 }
509
510 IMAGE_LOGE("ParserIFD leave, entry, false");
511 return false;
512 }
513
514 if (memcmp(makerNote_.data() + offset, HW_MNOTE_IFD_TAIL, sizeof(HW_MNOTE_IFD_TAIL)) != 0) {
515 IMAGE_LOGE("ParserIFD leave, tail, false");
516 return false;
517 }
518
519 IMAGE_LOGD("ParserIFD leave, true");
520 return true;
521 }
522
ParserItem(uint32_t offset,uint32_t ifd,uint32_t deep)523 bool ExifMakerNote::ParserItem(uint32_t offset, uint32_t ifd, uint32_t deep)
524 {
525 IMAGE_LOGD("ParserItem enter, offset=%{public}u, deep=%{public}u", offset, deep);
526
527 uint16_t tag = 0;
528 uint16_t format = 0;
529 uint32_t components = 0;
530 uint32_t dataOrOffset = 0;
531 if (!GetUInt16AndMove(offset, tag)) {
532 IMAGE_LOGE("ParserItem leave, tag, false");
533 return false;
534 }
535 if (!GetUInt16AndMove(offset, format)) {
536 IMAGE_LOGE("ParserItem leave, format, false");
537 return false;
538 }
539 if (!GetUInt32AndMove(offset, components)) {
540 IMAGE_LOGE("ParserItem leave, components, false");
541 return false;
542 }
543 bool cond = !GetUInt32(offset, dataOrOffset);
544 CHECK_ERROR_RETURN_RET_LOG(cond, false, "ParserItem leave, data, false");
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 cond = deep > 0;
556 CHECK_DEBUG_RETURN_RET_LOG(cond, true, "ParserItem leave, deep=%{public}u", deep);
557
558 if ((back.tag == HW_MNOTE_TAG_SCENE_INFO_OFFSET) || (back.tag == HW_MNOTE_TAG_FACE_INFO_OFFSET)) {
559 cond = !ParserIFD((tiff_offset_ + dataOrOffset), back.tag, (deep + 1));
560 CHECK_ERROR_RETURN_RET_LOG(cond, false, "ParserItem leave, ifd, false");
561 }
562
563 IMAGE_LOGD("ParserItem leave");
564 return true;
565 }
566
SetValue(const ExifItem & entry,const std::string & value)567 bool ExifMakerNote::SetValue(const ExifItem &entry, const std::string &value)
568 {
569 uint16_t tag = entry.tag;
570 if (MAKER_TAG_KEY_MAP.find(tag) != MAKER_TAG_KEY_MAP.end()) {
571 std::string tagName = MAKER_TAG_KEY_MAP.at(tag);
572 makerTagValueMap[tagName] = value;
573 return true;
574 }
575 return false;
576 }
577
GetUInt16AndMove(uint32_t & offset,uint16_t & value)578 bool ExifMakerNote::GetUInt16AndMove(uint32_t &offset, uint16_t &value)
579 {
580 if (GetUInt16(offset, value)) {
581 offset += sizeof(uint16_t);
582 return true;
583 }
584 return false;
585 }
586
GetUInt32AndMove(uint32_t & offset,uint32_t & value)587 bool ExifMakerNote::GetUInt32AndMove(uint32_t &offset, uint32_t &value)
588 {
589 if (GetUInt32(offset, value)) {
590 offset += sizeof(uint32_t);
591 return true;
592 }
593 return false;
594 }
595
GetDataAndMove(size_t & offset,size_t count,std::vector<unsigned char> & value)596 bool ExifMakerNote::GetDataAndMove(size_t &offset, size_t count, std::vector<unsigned char> &value)
597 {
598 if (GetData(offset, count, value)) {
599 offset += count;
600 return true;
601 }
602 return false;
603 }
604
GetUInt16(uint32_t offset,uint16_t & value)605 bool ExifMakerNote::GetUInt16(uint32_t offset, uint16_t &value)
606 {
607 return ExifMakerNote::GetUInt16(makerNote_, order_, offset, value);
608 }
609
GetUInt32(uint32_t offset,uint32_t & value)610 bool ExifMakerNote::GetUInt32(uint32_t offset, uint32_t &value)
611 {
612 return ExifMakerNote::GetUInt32(makerNote_, order_, offset, value);
613 }
614
GetData(size_t offset,size_t count,std::vector<unsigned char> & value)615 bool ExifMakerNote::GetData(size_t offset, size_t count, std::vector<unsigned char> &value)
616 {
617 return ExifMakerNote::GetData(makerNote_, offset, count, value);
618 }
619
GetUInt16(const std::vector<unsigned char> & buffer,ExifByteOrder order,size_t offset,uint16_t & value)620 bool ExifMakerNote::GetUInt16(const std::vector<unsigned char> &buffer, ExifByteOrder order,
621 size_t offset, uint16_t &value)
622 {
623 if ((offset + sizeof(uint16_t)) > buffer.size()) {
624 IMAGE_LOGE("GetUInt16 check error.");
625 return false;
626 }
627 value = exif_get_short(buffer.data() + offset, order);
628 return true;
629 }
630
GetUInt32(const std::vector<unsigned char> & buffer,ExifByteOrder order,size_t offset,uint32_t & value)631 bool ExifMakerNote::GetUInt32(const std::vector<unsigned char> &buffer, ExifByteOrder order,
632 size_t offset, uint32_t &value)
633 {
634 if ((offset + sizeof(uint32_t)) > buffer.size()) {
635 IMAGE_LOGE("GetUInt32 check error.");
636 return false;
637 }
638 value = exif_get_long(buffer.data() + offset, order);
639 return true;
640 }
641
GetData(const std::vector<unsigned char> & buffer,size_t offset,size_t count,std::vector<unsigned char> & value)642 bool ExifMakerNote::GetData(const std::vector<unsigned char> &buffer, size_t offset, size_t count,
643 std::vector<unsigned char> &value)
644 {
645 if ((offset + count) > buffer.size()) {
646 IMAGE_LOGE("GetData check error.");
647 return false;
648 }
649
650 value.resize(count);
651 if (memcpy_s(value.data(), count, buffer.data() + offset, count) != 0) {
652 IMAGE_LOGE("GetData memcpy error.");
653 return false;
654 }
655
656 return true;
657 }
658
Dump(const std::vector<unsigned char> & data,uint32_t offset,uint32_t sum)659 std::string ExifMakerNote::Dump(const std::vector<unsigned char> &data, uint32_t offset, uint32_t sum)
660 {
661 std::string ret;
662 char buffer[BUFFER_SIZE] = {0};
663
664 auto size = data.size();
665 for (size_t loc = 0, cur = offset; ((loc < sum) && (cur < size)); loc++, cur++) {
666 if (loc == 0) {
667 if (sprintf_s(buffer, sizeof(buffer), "%02X", data[cur]) == -1) {
668 IMAGE_LOGE("Dump sprintf error.");
669 break;
670 }
671 } else {
672 if (sprintf_s(buffer, sizeof(buffer), " %02X", data[cur]) == -1) {
673 IMAGE_LOGE("Dump sprintf error.");
674 break;
675 }
676 }
677 ret.append(buffer);
678 }
679
680 return ret;
681 }
682 } // namespace ImagePlugin
683 } // namespace OHOS