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