From 1b688048edb3fbf318aa4dac50918c47ef3a1f38 Mon Sep 17 00:00:00 2001 From: zhang-xiaobo1997 Date: Mon, 7 Mar 2022 17:01:56 +0800 Subject: [PATCH 1/6] Modify for exif Signed-off-by: zhang-xiaobo1997 --- .../common/libs/image/libjpegplugin/BUILD.gn | 15 +- .../image/libjpegplugin/include/exif_info.h | 15 +- .../libjpegplugin/include/jpeg_decoder.h | 2 +- .../image/libjpegplugin/src/exif_info.cpp | 394 +++++++++++++++++- .../image/libjpegplugin/src/jpeg_decoder.cpp | 40 +- 5 files changed, 434 insertions(+), 32 deletions(-) diff --git a/plugins/common/libs/image/libjpegplugin/BUILD.gn b/plugins/common/libs/image/libjpegplugin/BUILD.gn index 3b7ad3057..510739232 100644 --- a/plugins/common/libs/image/libjpegplugin/BUILD.gn +++ b/plugins/common/libs/image/libjpegplugin/BUILD.gn @@ -16,10 +16,10 @@ import("//foundation/multimedia/image_standard/ide/image_decode_config.gni") ohos_shared_library("jpegplugin") { sources = [ - "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp", "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp", "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/jpeg_utils.cpp", "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/plugin_export.cpp", + "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp", ] include_dirs = [ @@ -35,6 +35,7 @@ ohos_shared_library("jpegplugin") { "//third_party/flutter/skia", "//third_party/flutter/skia/include/core", "//third_party/flutter/skia/third_party/libjpeg-turbo", + "//third_party/libexif", ] if (use_mingw_win) { @@ -49,6 +50,7 @@ ohos_shared_library("jpegplugin") { "//foundation/multimedia/image_standard/interfaces/innerkits:image_static", "//foundation/multimedia/image_standard/mock/native:utils_mock_static", "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static", + "//third_party/libexif:libexif", ] } else if (use_clang_mac) { defines = image_decode_mac_defines @@ -61,6 +63,7 @@ ohos_shared_library("jpegplugin") { "//foundation/multimedia/image_standard/interfaces/innerkits:image_static", "//foundation/multimedia/image_standard/mock/native:utils_mock_static", "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static", + "//third_party/libexif:libexif", ] } else { defines = [ "DUAL_ADAPTER" ] @@ -73,12 +76,18 @@ ohos_shared_library("jpegplugin") { "//foundation/multimedia/image_standard/interfaces/innerkits:image_native", "//foundation/multimedia/image_standard/plugins/manager:pluginmanager", "//utils/native/base:utils", + "//third_party/libexif:libexif", ] if (DUAL_ADAPTER) { } else { - deps += [ "//foundation/ace/ace_engine/build/external_config/flutter/libjpeg:ace_libjpeg" ] - include_dirs += [ "//third_party/flutter/skia/third_party/libjpeg-turbo" ] + deps += [ + "//foundation/ace/ace_engine/build/external_config/flutter/libjpeg:ace_libjpeg", + "//third_party/libexif:libexif", + ] + include_dirs += [ + "//third_party/flutter/skia/third_party/libjpeg-turbo", + ] } external_deps = [ "hiviewdfx_hilog_native:libhilog" ] diff --git a/plugins/common/libs/image/libjpegplugin/include/exif_info.h b/plugins/common/libs/image/libjpegplugin/include/exif_info.h index 7b33539bd..8ca9cca35 100644 --- a/plugins/common/libs/image/libjpegplugin/include/exif_info.h +++ b/plugins/common/libs/image/libjpegplugin/include/exif_info.h @@ -14,6 +14,7 @@ */ #ifndef EXIF_INFO_H #define EXIF_INFO_H +#include #include #include "hilog/log.h" #include "log_tags.h" @@ -35,7 +36,7 @@ public: */ int ParseExifData(const unsigned char *buf, unsigned len); int ParseExifData(const std::string &data); - bool ModifyExifData(const std::string &tag, const std::string &value, const std::string &path); + bool ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path); public: std::string bitsPerSample_; // Number of bits in each pixel of an image. @@ -49,16 +50,16 @@ public: std::string dateTimeOriginal_; // Original date and time. private: - void SetExifTagValues(const std::string &tag, const std::string &value); - int GetImageFileDirectory(const std::string &tag); - void* InitExifTag(std::string *exif, int ifd, std::string tag); - void* CreateExifTag(std::string *exif, int ifd, std::string tag, size_t len, std::string format); + void SetExifTagValues(const ExifTag &tag, const std::string &value); + ExifIfd GetImageFileDirectory(const ExifTag &tag); + ExifEntry* InitExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag); + ExifEntry* CreateExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len, ExifFormat format); long GetFileSize(FILE *fp); void ReleaseSource(unsigned char *buf, FILE *file); private: - int imageFileDirectory_; - std::string* exifData_; + ExifIfd imageFileDirectory_; + ExifData* exifData_; }; } // namespace ImagePlugin } // namespace OHOS diff --git a/plugins/common/libs/image/libjpegplugin/include/jpeg_decoder.h b/plugins/common/libs/image/libjpegplugin/include/jpeg_decoder.h index 902f86cdf..cd1c56a60 100644 --- a/plugins/common/libs/image/libjpegplugin/include/jpeg_decoder.h +++ b/plugins/common/libs/image/libjpegplugin/include/jpeg_decoder.h @@ -68,7 +68,7 @@ private: void CreateDecoder(); bool IsMarker(uint8_t rawPrefix, uint8_t rawMarkderCode, uint8_t markerCode); bool FindMarker(InputDataStream &stream, uint8_t marker); - int getExifTagFromKey(const std::string &key, const std::string &value); + ExifTag getExifTagFromKey(const std::string &key, const std::string &value); static MultimediaPlugin::PluginServer &pluginServer_; jpeg_decompress_struct decodeInfo_; diff --git a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp index 28e067a39..0b3ab28e8 100644 --- a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp +++ b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp @@ -16,6 +16,7 @@ #include #include #include "string_ex.h" +#include "securec.h" namespace OHOS { namespace ImagePlugin { @@ -23,21 +24,68 @@ namespace { using namespace OHOS::HiviewDFX; constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "Exif" }; static const int PARSE_EXIF_SUCCESS = 0; + static const int PARSE_EXIF_DATA_ERROR = 10001; + static const int PARSE_EXIF_IFD_ERROR = 10002; + static const int BUFFER_POSITION_4 = 4; + static const int BUFFER_POSITION_5 = 5; + static const int BUFFER_POSITION_6 = 6; + static const int BUFFER_POSITION_7 = 7; + static const int BUFFER_POSITION_8 = 8; + static const int BUFFER_POSITION_9 = 9; + static const int BUFFER_POSITION_12 = 12; + static const int BUFFER_POSITION_13 = 13; + static const int LENGTH_OFFSET_2 = 2; + static const int MOVE_OFFSET_8 = 8; + static const int LENGTH_ARRAY_SIZE = 2; + static const int CONSTANT_2 = 2; + + /* raw EXIF header data */ + static const unsigned char exifHeader[] = { + 0xff, 0xd8, 0xff, 0xe1 + }; } -EXIFInfo::EXIFInfo() : imageFileDirectory_(0), exifData_(nullptr) +EXIFInfo::EXIFInfo() : imageFileDirectory_(EXIF_IFD_COUNT), exifData_(nullptr) { } EXIFInfo::~EXIFInfo() { if (exifData_ != nullptr) { + exif_data_unref(exifData_); exifData_ = nullptr; } } int EXIFInfo::ParseExifData(const unsigned char *buf, unsigned len) { + HiLog::Debug(LABEL, "ParseExifData ENTER"); + exifData_ = exif_data_new_from_data(buf, len); + if (!exifData_) { + return PARSE_EXIF_DATA_ERROR; + } + exif_data_foreach_content(exifData_, + [](ExifContent *ec, void *userData) + { + ExifIfd ifd = exif_content_get_ifd(ec); + ((EXIFInfo*)userData)->imageFileDirectory_ = ifd; + if (ifd == EXIF_IFD_COUNT) { + HiLog::Debug(LABEL, "GetIfd ERROR"); + return; + } + exif_content_foreach_entry(ec, + [](ExifEntry *ee, void* userData) + { + char tagValueChar[1024]; + exif_entry_get_value(ee, tagValueChar, sizeof(tagValueChar)); + std::string tagValueStr(&tagValueChar[0], &tagValueChar[strlen(tagValueChar)]); + ((EXIFInfo*)userData)->SetExifTagValues(ee->tag, tagValueStr); + }, userData); + }, this); + + if (imageFileDirectory_ == EXIF_IFD_COUNT) { + return PARSE_EXIF_IFD_ERROR; + } return PARSE_EXIF_SUCCESS; } @@ -46,33 +94,342 @@ int EXIFInfo::ParseExifData(const std::string &data) return ParseExifData((const unsigned char *)data.data(), data.length()); } -void EXIFInfo::SetExifTagValues(const std::string &tag, const std::string &value) +void EXIFInfo::SetExifTagValues(const ExifTag &tag, const std::string &value) { - HiLog::Error(LABEL, "No match tag name!"); + if (tag == EXIF_TAG_BITS_PER_SAMPLE) { + bitsPerSample_ = value; + } else if (tag == EXIF_TAG_ORIENTATION) { + orientation_ = value; + } else if (tag == EXIF_TAG_IMAGE_LENGTH) { + imageLength_ = value; + } else if (tag == EXIF_TAG_IMAGE_WIDTH) { + imageWidth_ = value; + } else if (tag == EXIF_TAG_GPS_LATITUDE) { + gpsLatitude_ = value; + } else if (tag == EXIF_TAG_GPS_LONGITUDE) { + gpsLongitude_ = value; + } else if (tag == EXIF_TAG_GPS_LATITUDE_REF) { + gpsLatitudeRef_ = value; + } else if (tag == EXIF_TAG_GPS_LONGITUDE_REF) { + gpsLongitudeRef_ = value; + } else if (tag == EXIF_TAG_DATE_TIME_ORIGINAL) { + dateTimeOriginal_ = value; + } else { + HiLog::Error(LABEL, "No match tag name!"); + } } -bool EXIFInfo::ModifyExifData(const std::string &tag, const std::string &value, const std::string &path) +bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path) { - if (imageFileDirectory_ == 0) { + FILE *file = fopen(path.c_str(), "rb"); + if (file == nullptr) { + HiLog::Error(LABEL, "Error creating file %{public}s", path.c_str()); + return false; + } + + // read jpeg file to buff + unsigned long fileLength = GetFileSize(file); + if (fileLength == 0) { + HiLog::Error(LABEL, "Get file size failed."); + fclose(file); + return false; + } + unsigned char *fileBuf = (unsigned char *)malloc(fileLength); + if (fileBuf == nullptr) { + HiLog::Error(LABEL, "Allocate buf for %{public}s failed.", path.c_str()); + fclose(file); + return false; + } + + if (fread(fileBuf, fileLength, 1, file) != 1) { + HiLog::Error(LABEL, "Read %{public}s failed.", path.c_str()); + ReleaseSource(fileBuf, file); + return false; + } + + if (!(fileBuf[0] == 0xFF && fileBuf[1] == 0xD8)) { + HiLog::Error(LABEL, "%{public}s is not jpeg file.", path.c_str()); + ReleaseSource(fileBuf, file); + return false; + } + + unsigned char lenthArray[LENGTH_ARRAY_SIZE] = { + fileBuf[BUFFER_POSITION_5], fileBuf[BUFFER_POSITION_4] + }; + unsigned int orginExifiDataLength = *(unsigned int)lenthArray; + + ExifData *ptrExifData = nullptr; + if ((fileBuf[BUFFER_POSITION_6] == 'E' && fileBuf[BUFFER_POSITION_7] == 'x' && + fileBuf[BUFFER_POSITION_8] == 'i' && fileBuf[BUFFER_POSITION_9] == 'f')) { + ptrExifData = exif_data_new_from_file(path.c_str()); + if (!ptrExifData) { + HiLog::Error(LABEL, "Create exif data from file failed."); + ReleaseSource(fileBuf, file); + return false; + } + } else { + ptrExifData = exif_data_new(); + if (!ptrExifData) { + HiLog::Error(LABEL, "Create exif data failed."); + ReleaseSource(fileBuf, file); + return false; + } + /* Set the image options */ + exif_data_set_option(ptrExifData, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION); + exif_data_set_data_type(ptrExifData, EXIF_DATA_TYPE_COMPRESSED); + exif_data_set_byte_order(ptrExifData, EXIF_BYTE_ORDER_INTEL); + + /* Create the mandatory EXIF fields with default data */ + exif_data_fix(ptrExifData); + } + (void)fclose(file); + file = nullptr; + + ExifByteOrder order = EXIF_BYTE_ORDER_MOTOROLA; + if (fileBuf[BUFFER_POSITION_12]) == 'M' && fileBuf[BUFFER_POSITION_13] == 'M') { + order = EXIF_BYTE_ORDER_MOTOROLA; + } else { + order = EXIF_BYTE_ORDER_INTEL; + } + + FILE *newFile = fopen(path.c_str(), "wb"); + if (newFile == nullptr) { + HiLog::Error(LABEL, "Error create new file %{public}s", path.c_str()); + ReleaseSource(fileBuf, newFile); + return false; + } + + ExifEntry *entry = nullptr; + switch (tag) { + case EXIF_TAG_BITS_PER_SAMPLE: { + entry = InitExifTag(ptrExifData, EXIF_IFD_1, EXIF_TAG_BITS_PER_SAMPLE); + std::vector bitsVec; + SplitStr(value, ",", bitsVec); + if (bitsVec.size() > CONSTANT_2) { + HiLog::Error(LABEL, "BITS_PER_SAMPLE Invalid value %{public}s", value.c_str()); + ReleaseSource(fileBuf, newFile); + return false; + } + if (bitsVec.size() != 0) { + for (size_t i = 0; i < bitsVec.size(); i++) { + exif_set_short(entry->data + i * CONSTANT_2, order, (ExifShort)atoi(bitsVec[i].c_str())); + } + } + break; + } + case EXIF_TAG_ORIENTATION: { + entry = InitExifTag(ptrExifData, EXIF_IFD_0, EXIF_TAG_ORIENTATION); + exif_set_short(entry->data, order, (ExifShort)atoi(value.c_str())); + break; + } + case EXIF_TAG_IMAGE_LENGTH: { + entry = InitExifTag(ptrExifData, EXIF_IFD_1, EXIF_TAG_IMAGE_LENGTH); + exif_set_short(entry->data, order, (ExifShort)atoi(value.c_str())); + break; + } + case EXIF_TAG_IMAGE_WIDTH: { + entry = InitExifTag(ptrExifData, EXIF_IFD_1, EXIF_TAG_IMAGE_WIDTH); + exif_set_short(entry->data, order, (ExifShort)atoi(value.c_str())); + break; + } + case EXIF_TAG_GPS_LATITUDE: { + std::vector latVec; + SplitStr(value, ",", latVec); + if (latVec.size() != CONSTANT_2) { + HiLog::Error(LABEL, "GPS_LATITUDE Invalid value %{public}s", value.c_str()); + ReleaseSource(fileBuf, newFile); + return false; + } + + ExifRational latRational; + latRational.numerator = atoi(latVec[0].c_str()); + latRational.denominator = atoi(latVec[1].c_str()); + entry = CreateExifTag(ptrExifData, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, + sizeof(latRational), EXIF_FORMAT_RATIONAL); + exif_set_rational(entry->data, order, latRational); + break; + } + case EXIF_TAG_GPS_LONGITUDE: { + std::vector longVec; + SplitStr(value, ",", longVec); + if (longVec.size() != CONSTANT_2) { + HiLog::Error(LABEL, "GPS_LONGITUDE Invalid value %{public}s", value.c_str()); + ReleaseSource(fileBuf, newFile); + return false; + } + + ExifRational longRational; + longRational.numerator = atoi(longVec[0].c_str()); + longRational.denominator = atoi(longVec[1].c_str()); + entry = CreateExifTag(ptrExifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, + sizeof(longRational), EXIF_FORMAT_RATIONAL); + exif_set_rational(entry->data, order, longRational); + break; + } + case EXIF_TAG_GPS_LATITUDE_REF: { + entry = CreateExifTag(ptrExifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF, + value.length(), EXIF_FORMAT_ASCII); + if (memcpy_s(entry->data, value.length(), value.c_str(), value.length()) != 0) { + HiLog::Error(LABEL, "LATITUDE ref memcpy error"); + } + break; + } + case EXIF_TAG_GPS_LONGITUDE_REF: { + entry = CreateExifTag(ptrExifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF, + value.length(), EXIF_FORMAT_ASCII); + if (memcpy_s(entry->data, value.length(), value.c_str(), value.length()) != 0) { + HiLog::Error(LABEL, "LONGITUDE ref memcpy error"); + } + break; + } + default: + break; + } + + unsigned char* exifDataBuf = nullptr; + unsigned int exifDataBufLength = 0; + exif_data_save_data(ptrExifData_, &exifDataBuf, &exifDataBufLength); + if (exifDataBuf == nullptr) { + HiLog::Error(LABEL, "Get Exif Data Buf failed!"); + return false; + } + + /* Write EXIF header */ + if (fwrite(exifHeader, sizeof(exifHeader), 1, newFile) != 1) { + HiLog::Error(LABEL, "Error writing EXIF header to file!"); + ReleaseSource(fileBuf, newFile); + return false; + } + + /* Write EXIF block length in big-endian order */ + if (fputc((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8, newFile) < 0) { + HiLog::Error(LABEL, "Error writing EXIF block length to file!"); + ReleaseSource(fileBuf, newFile); + return false; + } + if (fputc((exifDataBufLength + LENGTH_OFFSET_2) & 0xff, newFile) < 0) { + HiLog::Error(LABEL, "Error writing EXIF block length to file!"); + ReleaseSource(fileBuf, newFile); + return false; + } + + /* Write EXIF data block */ + if (fwrite(exifDataBuf, exifDataBufLength, 1, newFile) != 1) { + HiLog::Error(LABEL, "Error writing EXIF data block to file!"); + ReleaseSource(fileBuf, newFile); return false; } + /* Write JPEG image data, skipping the non-EXIF header */ + unsigned int dataOffset = orginExifDataLength + sizeof(exifHeader); + if (fwrite(fileBuf + dataOffset, fileLength - dataOffset, 1, newFile) != 1) { + HiLog::Error(LABEL, "Error writing JPEG image data to file!"); + ReleaseSource(fileBuf, newFile); + return false; + } + + ReleaseSource(fileBuf, newFile); return true; } -int EXIFInfo::GetImageFileDirectory(const std::string &tag) +ExifIfd EXIFInfo::GetImageFileDirectory(const ExifTag &tag) { - return 0; + switch (tag) { + case EXIF_TAG_BITS_PER_SAMPLE: + case EXIF_TAG_ORIENTATION: + case EXIF_TAG_IMAGE_LENGTH: + case EXIF_TAG_IMAGE_WIDTH: { + return EXIF_IFD_0; + } + case EXIF_TAG_DATE_TIME_ORIGINAL: { + return EXIF_IFD_EXIF; + } + case EXIF_TAG_GPS_LATITUDE: + case EXIF_TAG_GPS_LONGITUDE: + case EXIF_TAG_GPS_LATITUDE_REF: + case EXIF_TAG_GPS_LONGITUDE_REF: { + return EXIF_IFD_GPS; + } + default: + break; + } + return EXIF_IFD_COUNT; } -void* EXIFInfo::InitExifTag(std::string *exif, int ifd, std::string tag) +ExifEntry* EXIFInfo::InitExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag) { - return nullptr; + ExifEntry *entry; + /* Return an existing tag if one exists */ + if (!(entry = exif_content_get_entry(exif->ifd[ifd], tag))) { + /* Allocate a new entry */ + entry = exif_entry_new(); + if (entry == nullptr) { + HiLog::Error(LABEL, "Create new entry failed!"); + return nullptr; + } + entry->tag = tag; // tag must be set before calling exif_content_add_entry + /* Attach the ExifEntry to an IFD */ + exif_content_add_entry (exif->ifd[ifd], entry); + + /* Allocate memory for the entry and fill with default data */ + exif_entry_initialize (entry, tag); + + /* Ownership of the ExifEntry has now been passed to the IFD. + * One must be very careful in accessing a structure after + * unref'ing it; in this case, we know "entry" won't be freed + * because the reference count was bumped when it was added to + * the IFD. + */ + exif_entry_unref(entry); + } + return entry; } -void* EXIFInfo::CreateExifTag(std::string *exif, int ifd, std::string tag, - size_t len, std::string format) +ExifEntry* EXIFInfo::CreateExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag, + size_t len, ExifFormat format) { - return nullptr; + void *buf; + ExifEntry *entry; + + if (entry = exif_content_get_entry(exif->ifd[ifd], tag)) { + return entry; + } + + /* Create a memory allocator to manage this ExifEntry */ + ExifMem *mem = exif_mem_new_default(); + if (mem == nullptr) { + HiLog::Error(LABEL, "Create mem failed!"); + return nullptr; + } + + /* Create a new ExifEntry using our allocator */ + entry = exif_entry_new_mem (mem); + if (entry == nullptr) { + HiLog::Error(LABEL, "Create entry by mem failed!"); + return nullptr; + } + + /* Allocate memory to use for holding the tag data */ + buf = exif_mem_alloc(mem, len); + if (buf == nullptr) { + HiLog::Error(LABEL, "Allocate memory failed!"); + return nullptr; + } + + /* Fill in the entry */ + entry->data = static_cast(buf); + entry->size = len; + entry->tag = tag; + entry->components = len; + entry->format = format; + + /* Attach the ExifEntry to an IFD */ + exif_content_add_entry (exif->ifd[ifd], entry); + + /* The ExifMem and ExifEntry are now owned elsewhere */ + exif_mem_unref(mem); + exif_entry_unref(entry); + + return entry; } long EXIFInfo::GetFileSize(FILE *fp) @@ -85,10 +442,10 @@ long EXIFInfo::GetFileSize(FILE *fp) /* Jump to the end of the file. */ fseek(fp, 0L, SEEK_END); - + /* Get the end position. */ size = ftell(fp); - + /* Jump back to the original position. */ fseek(fp, position, SEEK_SET); @@ -99,10 +456,13 @@ void EXIFInfo::ReleaseSource(unsigned char *buf, FILE *file) { if (buf) { free(buf); + buf = nullptr; + } + + if (file != nullptr) { + fclose(file); + file = nullptr; } - buf = nullptr; - fclose(file); - file = nullptr; } } // namespace ImagePlugin } // namespace OHOS diff --git a/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp b/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp index f74dbd5ec..59ffe5f09 100644 --- a/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp +++ b/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp @@ -599,9 +599,38 @@ uint32_t JpegDecoder::GetImagePropertyString(uint32_t index, const std::string & return Media::SUCCESS; } -int JpegDecoder::getExifTagFromKey(const std::string &key, const std::string &value) +ExifTag JpegDecoder::getExifTagFromKey(const std::string &key, const std::string &value) { - return 0; + if (IsSameTextStr(key, BITS_PER_SAMPLE)) { + exifInfo_.bitsPerSample_ = value; + return EXIF_TAG_BITS_PER_SAMPLE; + } else if (IsSameTextStr(key, ORIENTATION)) { + exifInfo_.orientation_ = value; + return EXIF_TAG_ORIENTATION; + } else if (IsSameTextStr(key, IMAGE_LENGTH)) { + exifInfo_.imageLength_ = value; + return EXIF_TAG_IMAGE_LENGTH; + } else if (IsSameTextStr(key, IMAGE_WIDTH)) { + exifInfo_.imageWidth_ = value; + return EXIF_TAG_IMAGE_WIDTH; + } else if (IsSameTextStr(key, GPS_LATITUDE)) { + exifInfo_.gpsLatitude_ = value; + return EXIF_TAG_GPS_LATITUDE; + } else if (IsSameTextStr(key, GPS_LONGITUDE)) { + exifInfo_.gpsLongitude_ = value; + return EXIF_TAG_GPS_LONGITUDE; + } else if (IsSameTextStr(key, GPS_LATITUDE_REF)) { + exifInfo_.gpsLatitudeRef_ = value; + return EXIF_TAG_GPS_LATITUDE_REF; + } else if (IsSameTextStr(key, GPS_LONGITUDE_REF)) { + exifInfo_.gpsLongitudeRef_ = value; + return EXIF_TAG_GPS_LONGITUDE_REF; + } else if (IsSameTextStr(key, DATE_TIME_ORIGINAL)) { + exifInfo_.dateTimeOriginal_ = value; + return EXIF_TAG_DATE_TIME_ORIGINAL; + } else { + return EXIF_TAG_PRINT_IMAGE_MATCHING; + } } uint32_t JpegDecoder::ModifyImageProperty(uint32_t index, const std::string &key, @@ -609,11 +638,14 @@ uint32_t JpegDecoder::ModifyImageProperty(uint32_t index, const std::string &key { HiLog::Error(LABEL, "[ModifyImageProperty] enter jped plugin, key:%{public}s, value:%{public}s", key.c_str(), value.c_str()); - int tag = getExifTagFromKey(key, value); - if (tag == 0) { + ExifTag tag = getExifTagFromKey(key, value); + if (tag == EXIF_TAG_PRINT_IMAGE_MATCHING) { return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT; } + if (!exifInfo_.ModifyExifData(tag, value, path)) { + return ERR_IMAGE_DECODE_EXIF_UNSUPPORT; + } return Media::SUCCESS; } } // namespace ImagePlugin -- Gitee From 4a077e2e301e1f1345d596be85c3646e1a3aed20 Mon Sep 17 00:00:00 2001 From: zhang-xiaobo1997 Date: Tue, 8 Mar 2022 22:59:20 +0800 Subject: [PATCH 2/6] modify for code check Signed-off-by: zhang-xiaobo1997 --- plugins/common/libs/image/libjpegplugin/BUILD.gn | 12 +++++------- .../libs/image/libjpegplugin/src/exif_info.cpp | 6 ++---- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/plugins/common/libs/image/libjpegplugin/BUILD.gn b/plugins/common/libs/image/libjpegplugin/BUILD.gn index 510739232..520cdab29 100644 --- a/plugins/common/libs/image/libjpegplugin/BUILD.gn +++ b/plugins/common/libs/image/libjpegplugin/BUILD.gn @@ -16,10 +16,10 @@ import("//foundation/multimedia/image_standard/ide/image_decode_config.gni") ohos_shared_library("jpegplugin") { sources = [ + "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp", "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp", "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/jpeg_utils.cpp", "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/plugin_export.cpp", - "//foundation/multimedia/image_standard/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp", ] include_dirs = [ @@ -75,19 +75,17 @@ ohos_shared_library("jpegplugin") { "//foundation/ace/ace_engine/build/external_config/flutter/libjpeg:ace_libjpeg", "//foundation/multimedia/image_standard/interfaces/innerkits:image_native", "//foundation/multimedia/image_standard/plugins/manager:pluginmanager", - "//utils/native/base:utils", "//third_party/libexif:libexif", + "//utils/native/base:utils", ] if (DUAL_ADAPTER) { } else { deps += [ - "//foundation/ace/ace_engine/build/external_config/flutter/libjpeg:ace_libjpeg", - "//third_party/libexif:libexif", - ] - include_dirs += [ - "//third_party/flutter/skia/third_party/libjpeg-turbo", + "//foundation/ace/ace_engine/build/external_config/flutter/libjpeg:ace_libjpeg", + "//third_party/libexif:libexif", ] + include_dirs += [ "//third_party/flutter/skia/third_party/libjpeg-turbo" ] } external_deps = [ "hiviewdfx_hilog_native:libhilog" ] diff --git a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp index 0b3ab28e8..6ec7d901d 100644 --- a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp +++ b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp @@ -65,8 +65,7 @@ int EXIFInfo::ParseExifData(const unsigned char *buf, unsigned len) return PARSE_EXIF_DATA_ERROR; } exif_data_foreach_content(exifData_, - [](ExifContent *ec, void *userData) - { + [](ExifContent *ec, void *userData) { ExifIfd ifd = exif_content_get_ifd(ec); ((EXIFInfo*)userData)->imageFileDirectory_ = ifd; if (ifd == EXIF_IFD_COUNT) { @@ -74,8 +73,7 @@ int EXIFInfo::ParseExifData(const unsigned char *buf, unsigned len) return; } exif_content_foreach_entry(ec, - [](ExifEntry *ee, void* userData) - { + [](ExifEntry *ee, void* userData) { char tagValueChar[1024]; exif_entry_get_value(ee, tagValueChar, sizeof(tagValueChar)); std::string tagValueStr(&tagValueChar[0], &tagValueChar[strlen(tagValueChar)]); -- Gitee From fa764ef060518f273531a6cb65a5c531cec62c36 Mon Sep 17 00:00:00 2001 From: zhang-xiaobo1997 Date: Wed, 9 Mar 2022 16:04:08 +0800 Subject: [PATCH 3/6] modify error code Signed-off-by: zhang-xiaobo1997 --- plugins/common/libs/image/libjpegplugin/src/exif_info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp index 6ec7d901d..f0f772b49 100644 --- a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp +++ b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp @@ -154,7 +154,7 @@ bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, cons unsigned char lenthArray[LENGTH_ARRAY_SIZE] = { fileBuf[BUFFER_POSITION_5], fileBuf[BUFFER_POSITION_4] }; - unsigned int orginExifiDataLength = *(unsigned int)lenthArray; + unsigned int orginExifiDataLength = *(unsigned int*)lenthArray; ExifData *ptrExifData = nullptr; if ((fileBuf[BUFFER_POSITION_6] == 'E' && fileBuf[BUFFER_POSITION_7] == 'x' && -- Gitee From ca6c739b550359a58d299ef2f2463614cca49737 Mon Sep 17 00:00:00 2001 From: zhang-xiaobo1997 Date: Wed, 9 Mar 2022 16:57:26 +0800 Subject: [PATCH 4/6] modify for build error Signed-off-by: zhang-xiaobo1997 --- .../common/libs/image/libjpegplugin/src/exif_info.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp index f0f772b49..e5cd6f176 100644 --- a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp +++ b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp @@ -154,7 +154,7 @@ bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, cons unsigned char lenthArray[LENGTH_ARRAY_SIZE] = { fileBuf[BUFFER_POSITION_5], fileBuf[BUFFER_POSITION_4] }; - unsigned int orginExifiDataLength = *(unsigned int*)lenthArray; + unsigned int orginExifDataLength = *(unsigned int*)lenthArray; ExifData *ptrExifData = nullptr; if ((fileBuf[BUFFER_POSITION_6] == 'E' && fileBuf[BUFFER_POSITION_7] == 'x' && @@ -184,7 +184,7 @@ bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, cons file = nullptr; ExifByteOrder order = EXIF_BYTE_ORDER_MOTOROLA; - if (fileBuf[BUFFER_POSITION_12]) == 'M' && fileBuf[BUFFER_POSITION_13] == 'M') { + if (fileBuf[BUFFER_POSITION_12] == 'M' && fileBuf[BUFFER_POSITION_13] == 'M') { order = EXIF_BYTE_ORDER_MOTOROLA; } else { order = EXIF_BYTE_ORDER_INTEL; @@ -242,7 +242,7 @@ bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, cons ExifRational latRational; latRational.numerator = atoi(latVec[0].c_str()); latRational.denominator = atoi(latVec[1].c_str()); - entry = CreateExifTag(ptrExifData, EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, + entry = CreateExifTag(ptrExifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, sizeof(latRational), EXIF_FORMAT_RATIONAL); exif_set_rational(entry->data, order, latRational); break; @@ -259,7 +259,7 @@ bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, cons ExifRational longRational; longRational.numerator = atoi(longVec[0].c_str()); longRational.denominator = atoi(longVec[1].c_str()); - entry = CreateExifTag(ptrExifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE, + entry = CreateExifTag(ptrExifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGTITUDE, sizeof(longRational), EXIF_FORMAT_RATIONAL); exif_set_rational(entry->data, order, longRational); break; @@ -286,7 +286,7 @@ bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, cons unsigned char* exifDataBuf = nullptr; unsigned int exifDataBufLength = 0; - exif_data_save_data(ptrExifData_, &exifDataBuf, &exifDataBufLength); + exif_data_save_data(ptrExifData, &exifDataBuf, &exifDataBufLength); if (exifDataBuf == nullptr) { HiLog::Error(LABEL, "Get Exif Data Buf failed!"); return false; -- Gitee From b089d641c9ca9dbd741e835d85c686de758fa3b2 Mon Sep 17 00:00:00 2001 From: zhang-xiaobo1997 Date: Wed, 9 Mar 2022 17:29:46 +0800 Subject: [PATCH 5/6] modify for tag of GPS Signed-off-by: zhang-xiaobo1997 --- plugins/common/libs/image/libjpegplugin/src/exif_info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp index e5cd6f176..ff156ef7b 100644 --- a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp +++ b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp @@ -259,7 +259,7 @@ bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, cons ExifRational longRational; longRational.numerator = atoi(longVec[0].c_str()); longRational.denominator = atoi(longVec[1].c_str()); - entry = CreateExifTag(ptrExifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGTITUDE, + entry = CreateExifTag(ptrExifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE, sizeof(longRational), EXIF_FORMAT_RATIONAL); exif_set_rational(entry->data, order, longRational); break; -- Gitee From 45ce6633e4178c5b018dc7cde58cecf72e7b4221 Mon Sep 17 00:00:00 2001 From: zhang-xiaobo1997 Date: Wed, 9 Mar 2022 19:29:44 +0800 Subject: [PATCH 6/6] modify for entry debug Signed-off-by: zhang-xiaobo1997 --- plugins/common/libs/image/libjpegplugin/src/exif_info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp index ff156ef7b..49f254002 100644 --- a/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp +++ b/plugins/common/libs/image/libjpegplugin/src/exif_info.cpp @@ -388,7 +388,7 @@ ExifEntry* EXIFInfo::CreateExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag, void *buf; ExifEntry *entry; - if (entry = exif_content_get_entry(exif->ifd[ifd], tag)) { + if ((entry = exif_content_get_entry(exif->ifd[ifd], tag)) != nullptr) { return entry; } -- Gitee