From 8af3fe9d188bccf4fa92e5f4da2b09d8c3f73412 Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Wed, 23 Apr 2025 18:28:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=86=99=E5=85=A5Maker=20Not?= =?UTF-8?q?e=20Exif=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhaona45 --- .../accessor/src/exif_metadata.cpp | 73 ++++++++++++++++++- .../accessor/src/exif_metadata_formatter.cpp | 4 +- interfaces/innerkits/include/exif_metadata.h | 1 + 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/frameworks/innerkitsimpl/accessor/src/exif_metadata.cpp b/frameworks/innerkitsimpl/accessor/src/exif_metadata.cpp index eb77a2c9..6e5c66d4 100644 --- a/frameworks/innerkitsimpl/accessor/src/exif_metadata.cpp +++ b/frameworks/innerkitsimpl/accessor/src/exif_metadata.cpp @@ -69,6 +69,9 @@ const unsigned char INIT_HW_DATA[] = { 0x00 }; +const char HUAWEI_HEADER[] = { 'H', 'U', 'A', 'W', 'E', 'I', '\0', '\0'}; +static const int GET_SUPPORT_MAKERNOTE_COUNT = 1; +static const int INIT_HW_DATA_HEAD_LENGTH = 14; template std::istream &OutputRational(std::istream &is, T &r) { U nominator = 0; @@ -188,10 +191,20 @@ int ExifMetadata::HandleMakerNote(std::string &value) const bool cond = false; if (md == nullptr) { IMAGE_LOGD("Exif data mnote data md is a nullptr."); - return ERR_IMAGE_DECODE_EXIF_UNSUPPORT; } - cond = !is_huawei_md(md); - CHECK_DEBUG_RETURN_RET_LOG(cond, ERR_IMAGE_DECODE_EXIF_UNSUPPORT, "Exif data mnote data md is not ours md."); + if (!is_huawei_md(md)) { + int count = exif_data_get_maker_note_entry_count(exifData_); + cond = count != GET_SUPPORT_MAKERNOTE_COUNT; + CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + ExifEntry *entry = exif_data_get_entry(exifData_, EXIF_TAG_MAKER_NOTE); + cond = entry == nullptr; + CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + cond = entry->size >= TAG_VALUE_SIZE; + CHECK_ERROR_RETURN_RET(cond, ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + exif_entry_get_value(entry, tagValueChar.data(), tagValueChar.size()); + value.assign(tagValueChar.data(), entry->size); + return SUCCESS; + } MnoteHuaweiEntryCount *ec = nullptr; mnote_huawei_get_entry_count(reinterpret_cast(md), &ec); cond = ec == nullptr; @@ -608,10 +621,64 @@ bool ExifMetadata::SetValue(const std::string &key, const std::string &value) IMAGE_LOGD("Set HwMoteValue %{public}s", value.c_str()); return SetHwMoteValue(key, result.second); } + if (key == MAKER_NOTE_TAG) { + IMAGE_LOGD("Set MakerNote %{public}s", value.c_str()); + return SetMakerNoteValue(value); + } return SetCommonValue(key, result.second); } +bool ExifMetadata::SetMakerNoteValue(const std::string &value) +{ + bool cond = exifData_ == nullptr; + CHECK_ERROR_RETURN_RET_LOG(cond, false, "exifData_ is nullptr"); + cond = value.length() >= TAG_VALUE_SIZE; + CHECK_ERROR_RETURN_RET_LOG(cond, false, "value length is too long. length: %{public}zu", value.length()); + //clear all makernote data. + ExifEntry *entry = nullptr; + do { + entry = exif_data_get_entry(exifData_, EXIF_TAG_MAKER_NOTE); + if (entry != nullptr) { + exif_content_remove_entry(entry->parent, entry); + } + } while (entry != nullptr); + + auto md = exif_data_get_mnote_data(exifData_); + if (md != nullptr) { + exif_mnote_data_unref(md); + exif_data_set_priv_md(exifData_, nullptr); + } + + size_t valueLen = value.length(); + entry = CreateEntry(MAKER_NOTE_TAG, EXIF_TAG_MAKER_NOTE, valueLen); + cond = entry == nullptr; + CHECK_ERROR_RETURN_RET_LOG(cond, false, "Create entry is nullptr"); + if (memcpy_s(entry->data, entry->size, value.c_str(), valueLen) != 0) { + IMAGE_LOGE("Failed to copy memory for ExifEntry. Requested size: %{public}zu", valueLen); + return false; + } + + // parse huawei makernote + auto headLength = sizeof(HUAWEI_HEADER); + bool isHuaWeiHead = entry->size > headLength && + (memcmp(entry->data, HUAWEI_HEADER, headLength) == 0 || + memcmp(entry->data, INIT_HW_DATA, INIT_HW_DATA_HEAD_LENGTH) == 0); + if (isHuaWeiHead) { + auto mem = exif_data_get_priv_mem(exifData_); + auto hwMd = exif_mnote_data_huawei_new(mem); + if (hwMd != nullptr) { + exif_data_set_priv_md(exifData_, hwMd); + auto order = exif_data_get_byte_order(exifData_); + exif_mnote_data_set_byte_order(hwMd, order); + exif_mnote_data_set_offset(hwMd, 0); + exif_mnote_data_load(hwMd, entry->data, entry->size); + IMAGE_LOGD("value is huawei makernote data. load finished"); + } + } + return true; +} + bool ExifMetadata::SetHwMoteValue(const std::string &key, const std::string &value) { bool isNewMaker = false; diff --git a/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp b/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp index de430748..afbec5d3 100644 --- a/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp +++ b/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp @@ -206,6 +206,7 @@ const static std::set READ_WRITE_KEYS = { "MovingPhotoVersion", "MicroVideoPresentationTimestampUS", "HwMnoteAiEdit", + "MakerNote", }; const static std::set READ_ONLY_KEYS = { @@ -224,8 +225,7 @@ const static std::set READ_ONLY_KEYS = { "HwMnoteFaceRect", "HwMnoteFaceLeyeCenter", "HwMnoteFaceReyeCenter", "HwMnoteFaceMouthCenter", "JPEGInterchangeFormat", "JPEGInterchangeFormatLength", - "MakerNote", "HwMnoteWindSnapshotMode", - "HwMnoteFocusModeExif", + "HwMnoteWindSnapshotMode", "HwMnoteFocusModeExif", }; // Orientation, tag 0x0112 diff --git a/interfaces/innerkits/include/exif_metadata.h b/interfaces/innerkits/include/exif_metadata.h index b069531c..219a97bb 100644 --- a/interfaces/innerkits/include/exif_metadata.h +++ b/interfaces/innerkits/include/exif_metadata.h @@ -68,6 +68,7 @@ private: bool SetByte(ExifEntry *ptrEntry, const std::string &value); bool SetMem(ExifEntry *ptrEntry, const std::string &value, const size_t len); bool SetHwMoteValue(const std::string &key, const std::string &value); + bool SetMakerNoteValue(const std::string &value); bool RemoveHwEntry(const std::string &key); bool SetCommonValue(const std::string &key, const std::string &value); bool IsSpecialHwKey(const std::string &key) const; -- Gitee