!125 image 的Issue问题整改

Merge pull request !125 from 张晓波/master
This commit is contained in:
openharmony_ci 2022-04-12 02:50:07 +00:00 committed by Gitee
commit 67af4b1c96
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 704 additions and 243 deletions

View File

@ -545,7 +545,43 @@ uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key
}
ret = mainDecoder_->ModifyImageProperty(index, key, value, path);
if (ret != SUCCESS) {
IMAGE_LOGE("[ImageSource] GetImagePropertyInt fail, ret:%{public}u", ret);
IMAGE_LOGE("[ImageSource] ModifyImageProperty fail, ret:%{public}u", ret);
return ret;
}
return SUCCESS;
}
uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key,
const std::string &value, const int fd)
{
std::unique_lock<std::mutex> guard(decodingMutex_);
uint32_t ret;
auto iter = GetValidImageStatus(0, ret);
if (iter == imageStatusMap_.end()) {
IMAGE_LOGE("[ImageSource]get valid image status fail on modify image property, ret:%{public}u.", ret);
return ret;
}
ret = mainDecoder_->ModifyImageProperty(index, key, value, fd);
if (ret != SUCCESS) {
IMAGE_LOGE("[ImageSource] ModifyImageProperty fail, ret:%{public}u", ret);
return ret;
}
return SUCCESS;
}
uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key,
const std::string &value, uint8_t *data, uint32_t size)
{
std::unique_lock<std::mutex> guard(decodingMutex_);
uint32_t ret;
auto iter = GetValidImageStatus(0, ret);
if (iter == imageStatusMap_.end()) {
IMAGE_LOGE("[ImageSource]get valid image status fail on modify image property, ret:%{public}u.", ret);
return ret;
}
ret = mainDecoder_->ModifyImageProperty(index, key, value, data, size);
if (ret != SUCCESS) {
IMAGE_LOGE("[ImageSource] ModifyImageProperty fail, ret:%{public}u", ret);
return ret;
}
return SUCCESS;

View File

@ -18,6 +18,7 @@
#include "hilog/log.h"
#include "image_napi_utils.h"
#include "media_errors.h"
#include "string_ex.h"
using OHOS::HiviewDFX::HiLog;
namespace {
@ -28,6 +29,7 @@ namespace {
constexpr uint32_t NUM_3 = 3;
constexpr uint32_t NUM_4 = 4;
constexpr uint32_t NUM_5 = 5;
constexpr uint32_t NUM_8 = 8;
}
namespace OHOS {
@ -38,6 +40,9 @@ std::shared_ptr<IncrementalPixelMap> ImageSourceNapi::sIncPixelMap_ = nullptr;
static const std::string CLASS_NAME = "ImageSource";
static const std::string FILE_URL_PREFIX = "file://";
std::string ImageSourceNapi::filePath_ = "";
int ImageSourceNapi::fileDescriptor_ = -1;
void* ImageSourceNapi::fileBuffer_ = nullptr;
size_t ImageSourceNapi::fileBufferSize_ = 0;
struct ImageSourceAsyncContext {
napi_env env;
@ -69,6 +74,7 @@ struct ImageSourceAsyncContext {
std::shared_ptr<ImageSource> rImageSource;
std::shared_ptr<PixelMap> rPixelMap;
napi_value error = nullptr;
std::string errMsg;
};
static std::string GetStringArgument(napi_env env, napi_value value)
@ -473,6 +479,11 @@ napi_value ImageSourceNapi::CreateImageSource(napi_env env, napi_callback_info i
IMG_JS_ARGS(env, info, status, argCount, argValue, thisVar);
IMG_NAPI_CHECK_RET_D(IMG_IS_OK(status), nullptr, HiLog::Error(LABEL, "fail to napi_get_cb_info"));
filePath_ = "";
fileDescriptor_ = -1;
fileBuffer_ = nullptr;
fileBufferSize_ = 0;
std::unique_ptr<ImageSourceAsyncContext> asyncContext = std::make_unique<ImageSourceAsyncContext>();
uint32_t errorCode = ERR_MEDIA_INVALID_VALUE;
SourceOptions opts;
@ -501,10 +512,13 @@ napi_value ImageSourceNapi::CreateImageSource(napi_env env, napi_callback_info i
} else if (argCount == NUM_1 && ImageNapiUtils::getType(env, argValue[NUM_0]) == napi_number) {
napi_get_value_int32(env, argValue[NUM_0], &asyncContext->fdIndex);
HiLog::Debug(LABEL, "CreateImageSource fdIndex is [%{public}d]", asyncContext->fdIndex);
fileDescriptor_ = asyncContext->fdIndex;
imageSource = ImageSource::CreateImageSource(asyncContext->fdIndex, opts, errorCode);
} else if (argCount == NUM_1) {
status = napi_get_arraybuffer_info(env, argValue[NUM_0],
&(asyncContext->sourceBuffer), &(asyncContext->sourceBufferSize));
fileBuffer_ = asyncContext->sourceBuffer;
fileBufferSize_ = asyncContext->sourceBufferSize;
imageSource = ImageSource::CreateImageSource(static_cast<uint8_t *>(asyncContext->sourceBuffer),
asyncContext->sourceBufferSize, opts, errorCode);
}
@ -791,11 +805,44 @@ static void ModifyImagePropertyComplete(napi_env env, napi_status status, ImageS
HiLog::Error(LABEL, "context is nullptr");
return;
}
napi_value result = nullptr;
napi_get_undefined(env, &result);
napi_value result[NUM_2] = {0};
napi_get_undefined(env, &result[NUM_0]);
napi_get_undefined(env, &result[NUM_1]);
napi_value retVal;
napi_value callback = nullptr;
if (context->status == ERR_MEDIA_WRITE_PARCEL_FAIL) {
if (context->fdIndex != -1) {
napi_create_string_utf8(env, "Create Fd without write permission!", NAPI_AUTO_LENGTH, &result[NUM_0]);
}
} else if (context->status == ERR_MEDIA_OUT_OF_RANGE) {
napi_create_string_utf8(env, "The given buffer size is too small to add new exif data!",
NAPI_AUTO_LENGTH, &result[NUM_0]);
} else if (context->status == ERR_IMAGE_DECODE_EXIF_UNSUPPORT) {
napi_create_string_utf8(env, "The exif data format is not standard, so modify it failed!",
NAPI_AUTO_LENGTH, &result[NUM_0]);
} else if (context->status == ERR_MEDIA_VALUE_INVALID) {
napi_create_string_utf8(env, (context->errMsg).c_str(), NAPI_AUTO_LENGTH, &result[NUM_0]);
}
if (context->deferred) {
if (context->status == SUCCESS) {
napi_resolve_deferred(env, context->deferred, result[NUM_1]);
} else {
napi_reject_deferred(env, context->deferred, result[NUM_0]);
}
} else {
HiLog::Debug(LABEL, "call callback function");
napi_get_reference_value(env, context->callbackRef, &callback);
napi_call_function(env, nullptr, callback, NUM_2, result, &retVal);
napi_delete_reference(env, context->callbackRef);
}
napi_delete_async_work(env, context->work);
delete context;
context = nullptr;
HiLog::Debug(LABEL, "ModifyPropertyComplete OUT");
ImageSourceCallbackRoutine(env, context, result);
}
static void GetImagePropertyComplete(napi_env env, napi_status status, ImageSourceAsyncContext *context)
@ -865,6 +912,67 @@ static std::unique_ptr<ImageSourceAsyncContext> UnwrapContext(napi_env env, napi
return context;
}
static bool CheckExifDataValue(const std::string &key, const std::string &value, std::string &errorInfo)
{
if (IsSameTextStr(key, "BitsPerSample")) {
std::vector<std::string> bitsVec;
SplitStr(value, ",", bitsVec);
if (bitsVec.size() > NUM_2) {
errorInfo = "BitsPerSample has invalid exif value: ";
errorInfo.append(value);
return false;
}
for (size_t i = 0; i < bitsVec.size(); i++) {
if (!IsNumericStr(bitsVec[i])) {
errorInfo = "BitsPerSample has invalid exif value: ";
errorInfo.append(bitsVec[i]);
return false;
}
}
} else if (IsSameTextStr(key, "Orientation")) {
if (!IsNumericStr(value) || atoi(value.c_str()) < 1 || atoi(value.c_str()) > NUM_8) {
errorInfo = "Orientation has invalid exif value: ";
errorInfo.append(value);
return false;
}
} else if (IsSameTextStr(key, "ImageLength") || IsSameTextStr(key, "ImageWidth")) {
if (!IsNumericStr(value)) {
errorInfo = "ImageLength or ImageWidth has invalid exif value: ";
errorInfo.append(value);
return false;
}
} else if (IsSameTextStr(key, "GPSLatitude") || IsSameTextStr(key, "GPSLongitude")) {
std::vector<std::string> gpsVec;
SplitStr(value, ",", gpsVec);
if (gpsVec.size() != NUM_2) {
errorInfo = "GPSLatitude or GPSLongitude has invalid exif value: ";
errorInfo.append(value);
return false;
}
for (size_t i = 0; i < gpsVec.size(); i++) {
if (!IsNumericStr(gpsVec[i])) {
errorInfo = "GPSLatitude or GPSLongitude has invalid exif value: ";
errorInfo.append(gpsVec[i]);
return false;
}
}
} else if (IsSameTextStr(key, "GPSLatitudeRef")) {
if (!IsSameTextStr(value, "N") && !IsSameTextStr(value, "S")) {
errorInfo = "GPSLatitudeRef has invalid exif value: ";
errorInfo.append(value);
return false;
}
} else if (IsSameTextStr(key, "GPSLongitudeRef")) {
if (!IsSameTextStr(value, "W") && !IsSameTextStr(value, "E")) {
errorInfo = "GPSLongitudeRef has invalid exif value: ";
errorInfo.append(value);
return false;
}
}
return true;
}
static std::unique_ptr<ImageSourceAsyncContext> UnwrapContextForModify(napi_env env,
napi_callback_info info)
{
@ -914,6 +1022,9 @@ static std::unique_ptr<ImageSourceAsyncContext> UnwrapContextForModify(napi_env
}
}
context->pathName = ImageSourceNapi::filePath_;
context->fdIndex = ImageSourceNapi::fileDescriptor_;
context->sourceBuffer = ImageSourceNapi::fileBuffer_;
context->sourceBufferSize = ImageSourceNapi::fileBufferSize_;
return context;
}
@ -940,8 +1051,25 @@ napi_value ImageSourceNapi::ModifyImageProperty(napi_env env, napi_callback_info
[](napi_env env, void *data)
{
auto context = static_cast<ImageSourceAsyncContext*>(data);
context->status = context->rImageSource->ModifyImageProperty(context->index,
context->keyStr, context->valueStr, context->pathName);
if (!CheckExifDataValue(context->keyStr, context->valueStr, context->errMsg)) {
HiLog::Error(LABEL, "There is invalid exif data parameter");
context->status = ERR_MEDIA_VALUE_INVALID;
return;
}
if (!IsSameTextStr(context->pathName, "")) {
context->status = context->rImageSource->ModifyImageProperty(context->index,
context->keyStr, context->valueStr, context->pathName);
} else if (context->fdIndex != -1) {
context->status = context->rImageSource->ModifyImageProperty(context->index,
context->keyStr, context->valueStr, context->fdIndex);
} else if (context->sourceBuffer != nullptr) {
context->status = context->rImageSource->ModifyImageProperty(context->index,
context->keyStr, context->valueStr, static_cast<uint8_t *>(context->sourceBuffer),
context->sourceBufferSize);
} else {
HiLog::Error(LABEL, "There is no image source!");
}
},
reinterpret_cast<napi_async_complete_callback>(ModifyImagePropertyComplete),
asyncContext,

View File

@ -164,6 +164,10 @@ public:
NATIVEEXPORT uint32_t GetImagePropertyString(uint32_t index, const std::string &key, std::string &value);
NATIVEEXPORT uint32_t ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value,
const std::string &path);
NATIVEEXPORT uint32_t ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value,
const int fd);
NATIVEEXPORT uint32_t ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value,
uint8_t *data, uint32_t size);
NATIVEEXPORT const NinePatchInfo &GetNinePatchInfo() const;
NATIVEEXPORT void SetMemoryUsagePreference(const MemoryUsagePreference preference);
NATIVEEXPORT MemoryUsagePreference GetMemoryUsagePreference();

View File

@ -39,6 +39,9 @@ public:
}
static std::string filePath_;
static int fileDescriptor_;
static void* fileBuffer_;
static size_t fileBufferSize_;
private:
static napi_value Constructor(napi_env env, napi_callback_info info);

View File

@ -36,7 +36,9 @@ public:
*/
int ParseExifData(const unsigned char *buf, unsigned len);
int ParseExifData(const std::string &data);
bool ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path);
uint32_t ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path);
uint32_t ModifyExifData(const ExifTag &tag, const std::string &value, const int fd);
uint32_t ModifyExifData(const ExifTag &tag, const std::string &value, unsigned char *data, uint32_t size);
public:
std::string bitsPerSample_; // Number of bits in each pixel of an image.
@ -51,11 +53,18 @@ public:
private:
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);
void ReleaseSource(unsigned char **ptrBuf, FILE **ptrFile);
bool CreateExifData(unsigned char *buf, unsigned long length, ExifData **data, bool &isNewExifData);
unsigned int GetOrginExifDataLength(const bool &isNewExifData, unsigned char *buf);
ExifByteOrder GetExifByteOrder(const bool &isNewExifData, unsigned char *buf);
bool CreateExifEntry(const ExifTag &tag, ExifData *data, const std::string &value,
ExifByteOrder order, ExifEntry **ptrEntry);
bool WriteExifDataToFile(ExifData *data, unsigned int orginExifDataLength, unsigned long fileLength,
unsigned char *buf, FILE *fp);
void UpdateCacheExifData(FILE *fp);
private:
ExifIfd imageFileDirectory_;

View File

@ -55,7 +55,10 @@ public:
uint32_t GetImagePropertyString(uint32_t index, const std::string &key, std::string &value) override;
uint32_t ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value,
const std::string &path) override;
uint32_t ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value,
const int fd) override;
uint32_t ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value,
uint8_t *data, uint32_t size) override;
private:
DISALLOW_COPY_AND_MOVE(JpegDecoder);
int ExifPrintMethod();
@ -69,7 +72,7 @@ private:
void CreateDecoder();
bool IsMarker(uint8_t rawPrefix, uint8_t rawMarkderCode, uint8_t markerCode);
bool FindMarker(InputDataStream &stream, uint8_t marker);
ExifTag getExifTagFromKey(const std::string &key, const std::string &value);
ExifTag getExifTagFromKey(const std::string &key);
static MultimediaPlugin::PluginServer &pluginServer_;
jpeg_decompress_struct decodeInfo_;

View File

@ -15,6 +15,8 @@
#include "exif_info.h"
#include <algorithm>
#include <cstdio>
#include <unistd.h>
#include "media_errors.h"
#include "string_ex.h"
#include "securec.h"
@ -38,6 +40,7 @@ namespace {
static const int MOVE_OFFSET_8 = 8;
static const int LENGTH_ARRAY_SIZE = 2;
static const int CONSTANT_2 = 2;
static const unsigned long MAX_FILE_SIZE = 1000 * 1000 * 1000;
/* raw EXIF header data */
static const unsigned char exifHeader[] = {
@ -117,195 +120,188 @@ void EXIFInfo::SetExifTagValues(const ExifTag &tag, const std::string &value)
}
}
bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path)
uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path)
{
FILE *file = fopen(path.c_str(), "rb");
if (file == nullptr) {
HiLog::Error(LABEL, "Error creating file %{public}s", path.c_str());
return false;
return Media::ERR_MEDIA_IO_ABNORMAL;
}
// read jpeg file to buff
unsigned long fileLength = GetFileSize(file);
if (fileLength == 0) {
if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
HiLog::Error(LABEL, "Get file size failed.");
fclose(file);
return false;
return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
}
unsigned char *fileBuf = (unsigned char *)malloc(fileLength);
unsigned char *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
if (fileBuf == nullptr) {
HiLog::Error(LABEL, "Allocate buf for %{public}s failed.", path.c_str());
fclose(file);
return false;
return Media::ERR_IMAGE_MALLOC_ABNORMAL;
}
if (fread(fileBuf, fileLength, 1, file) != 1) {
HiLog::Error(LABEL, "Read %{public}s failed.", path.c_str());
ReleaseSource(fileBuf, file);
return false;
ReleaseSource(&fileBuf, &file);
return Media::ERR_MEDIA_READ_PARCEL_FAIL;
}
if (!(fileBuf[0] == 0xFF && fileBuf[1] == 0xD8)) {
HiLog::Error(LABEL, "%{public}s is not jpeg file.", path.c_str());
ReleaseSource(fileBuf, file);
return false;
ReleaseSource(&fileBuf, &file);
return Media::ERR_IMAGE_MISMATCHED_FORMAT;
}
unsigned char lenthArray[LENGTH_ARRAY_SIZE] = {
fileBuf[BUFFER_POSITION_5], fileBuf[BUFFER_POSITION_4]
};
unsigned int orginExifDataLength = *(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);
bool isNewExifData = false;
if (!CreateExifData(fileBuf, fileLength, &ptrExifData, isNewExifData)) {
ReleaseSource(&fileBuf, &file);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
(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;
unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, fileBuf);
if (!isNewExifData && orginExifDataLength == 0) {
HiLog::Error(LABEL, "There is no orginExifDataLength node in %{public}s.", path.c_str());
exif_data_unref(ptrExifData);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
FILE *newFile = fopen(path.c_str(), "wb");
ExifByteOrder order = GetExifByteOrder(isNewExifData, fileBuf);
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;
ReleaseSource(&fileBuf, &newFile);
return Media::ERR_MEDIA_IO_ABNORMAL;
}
ExifEntry *entry = nullptr;
if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
ReleaseSource(&fileBuf, &newFile);
exif_data_unref(ptrExifData);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
if (!WriteExifDataToFile(ptrExifData, orginExifDataLength, fileLength, fileBuf, newFile)) {
ReleaseSource(&fileBuf, &newFile);
exif_data_unref(ptrExifData);
return Media::ERR_MEDIA_WRITE_PARCEL_FAIL;
}
ReleaseSource(&fileBuf, &newFile);
exif_data_unref(ptrExifData);
return Media::SUCCESS;
}
uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const int fd)
{
const int localFd = dup(fd);
FILE *file = fdopen(localFd, "wb+");
if (file == nullptr) {
HiLog::Error(LABEL, "Error creating file %{public}d", localFd);
return Media::ERR_MEDIA_IO_ABNORMAL;
}
// read jpeg file to buff
unsigned long fileLength = GetFileSize(file);
if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
HiLog::Error(LABEL, "Get file size failed.");
fclose(file);
return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
}
unsigned char *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
if (fileBuf == nullptr) {
HiLog::Error(LABEL, "Allocate buf for %{public}d failed.", localFd);
fclose(file);
return Media::ERR_IMAGE_MALLOC_ABNORMAL;
}
// Set current position to begin of file.
(void)fseek(file, 0L, 0);
if (fread(fileBuf, fileLength, 1, file) != 1) {
HiLog::Error(LABEL, "Read %{public}d failed.", localFd);
ReleaseSource(&fileBuf, &file);
return Media::ERR_MEDIA_READ_PARCEL_FAIL;
}
if (!(fileBuf[0] == 0xFF && fileBuf[1] == 0xD8)) {
HiLog::Error(LABEL, "%{public}d is not jpeg file.", localFd);
ReleaseSource(&fileBuf, &file);
return Media::ERR_IMAGE_MISMATCHED_FORMAT;
}
ExifData *ptrExifData = nullptr;
bool isNewExifData = false;
if (!CreateExifData(fileBuf, fileLength, &ptrExifData, isNewExifData)) {
ReleaseSource(&fileBuf, &file);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, fileBuf);
if (!isNewExifData && orginExifDataLength == 0) {
HiLog::Error(LABEL, "There is no orginExifDataLength node in %{public}d.", localFd);
exif_data_unref(ptrExifData);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
ExifByteOrder order = GetExifByteOrder(isNewExifData, fileBuf);
// Set current position to begin of new file.
(void)fseek(file, 0L, 0);
ExifEntry *entry = nullptr;
switch (tag) {
case EXIF_TAG_BITS_PER_SAMPLE: {
entry = InitExifTag(ptrExifData, EXIF_IFD_1, EXIF_TAG_BITS_PER_SAMPLE);
std::vector<std::string> 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 (entry == nullptr) {
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);
if (entry == nullptr) {
return false;
}
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);
if (entry == nullptr) {
return false;
}
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);
if (entry == nullptr) {
return false;
}
exif_set_short(entry->data, order, (ExifShort)atoi(value.c_str()));
break;
}
case EXIF_TAG_GPS_LATITUDE: {
std::vector<std::string> 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;
}
if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
ReleaseSource(&fileBuf, &file);
exif_data_unref(ptrExifData);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
ExifRational latRational;
latRational.numerator = atoi(latVec[0].c_str());
latRational.denominator = atoi(latVec[1].c_str());
entry = CreateExifTag(ptrExifData, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE,
sizeof(latRational), EXIF_FORMAT_RATIONAL);
if (entry == nullptr) {
return false;
}
exif_set_rational(entry->data, order, latRational);
break;
}
case EXIF_TAG_GPS_LONGITUDE: {
std::vector<std::string> 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;
}
if (!WriteExifDataToFile(ptrExifData, orginExifDataLength, fileLength, fileBuf, file)) {
ReleaseSource(&fileBuf, &file);
exif_data_unref(ptrExifData);
return Media::ERR_MEDIA_WRITE_PARCEL_FAIL;
}
ReleaseSource(&fileBuf, &file);
exif_data_unref(ptrExifData);
return Media::SUCCESS;
}
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_LONGITUDE,
sizeof(longRational), EXIF_FORMAT_RATIONAL);
if (entry == nullptr) {
return false;
}
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 (entry == nullptr) {
return false;
}
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 (entry == nullptr) {
return false;
}
if (memcpy_s(entry->data, value.length(), value.c_str(), value.length()) != 0) {
HiLog::Error(LABEL, "LONGITUDE ref memcpy error");
}
break;
}
default:
break;
uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value,
unsigned char *data, uint32_t size)
{
if (data == nullptr) {
HiLog::Error(LABEL, "buffer is nullptr.");
return Media::ERR_IMAGE_SOURCE_DATA;
}
if (size == 0) {
HiLog::Error(LABEL, "buffer size is 0.");
return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
}
if (!(data[0] == 0xFF && data[1] == 0xD8)) {
HiLog::Error(LABEL, "This is not jpeg file.");
return Media::ERR_IMAGE_MISMATCHED_FORMAT;
}
ExifData *ptrExifData = nullptr;
bool isNewExifData = false;
if (!CreateExifData(data, size, &ptrExifData, isNewExifData)) {
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, data);
if (!isNewExifData && orginExifDataLength == 0) {
HiLog::Error(LABEL, "There is no orginExifDataLength node in buffer.");
exif_data_unref(ptrExifData);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
ExifByteOrder order = GetExifByteOrder(isNewExifData, data);
ExifEntry *entry = nullptr;
if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
exif_data_unref(ptrExifData);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
unsigned char* exifDataBuf = nullptr;
@ -313,68 +309,95 @@ bool EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, cons
exif_data_save_data(ptrExifData, &exifDataBuf, &exifDataBufLength);
if (exifDataBuf == nullptr) {
HiLog::Error(LABEL, "Get Exif Data Buf failed!");
return false;
exif_data_unref(ptrExifData);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
/* 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;
if (size == 0 || size > MAX_FILE_SIZE) {
HiLog::Error(LABEL, "Buffer size is out of range.");
exif_data_unref(ptrExifData);
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
unsigned char *tempBuf = static_cast<unsigned char *>(malloc(size));
if (tempBuf == nullptr) {
HiLog::Error(LABEL, "Allocate temp buffer ailed.");
exif_data_unref(ptrExifData);
return Media::ERR_IMAGE_MALLOC_ABNORMAL;
}
/* 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 header to buffer
uint32_t index = 0;
if (sizeof(exifHeader) >= size) {
HiLog::Error(LABEL, "There is not enough space for EXIF header!");
free(tempBuf);
tempBuf = nullptr;
exif_data_unref(ptrExifData);
return Media::ERR_MEDIA_OUT_OF_RANGE;
}
/* 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;
for (size_t i = 0; i < sizeof(exifHeader); i++) {
tempBuf[index] = exifHeader[i];
index += 1;
}
ReleaseSource(fileBuf, newFile);
return true;
}
ExifIfd EXIFInfo::GetImageFileDirectory(const ExifTag &tag)
{
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;
// Write EXIF block length in big-endian order
unsigned char highBit = static_cast<unsigned char>((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8);
if (index >= size) {
HiLog::Error(LABEL, "There is not enough space for writing EXIF block length!");
free(tempBuf);
tempBuf = nullptr;
exif_data_unref(ptrExifData);
return Media::ERR_MEDIA_OUT_OF_RANGE;
}
return EXIF_IFD_COUNT;
tempBuf[index] = highBit;
index += 1;
unsigned char lowBit = static_cast<unsigned char>((exifDataBufLength + LENGTH_OFFSET_2) & 0xff);
if (index >= size) {
HiLog::Error(LABEL, "There is not enough space for writing EXIF block length!");
free(tempBuf);
tempBuf = nullptr;
exif_data_unref(ptrExifData);
return Media::ERR_MEDIA_OUT_OF_RANGE;
}
tempBuf[index] = lowBit;
index += 1;
// Write EXIF data block
if ((index + exifDataBufLength) >= size) {
HiLog::Error(LABEL, "There is not enough space for writing EXIF data block!");
free(tempBuf);
tempBuf = nullptr;
exif_data_unref(ptrExifData);
return Media::ERR_MEDIA_OUT_OF_RANGE;
}
for (unsigned int i = 0; i < exifDataBufLength; i++) {
tempBuf[index] = exifDataBuf[i];
index += 1;
}
// Write JPEG image data, skipping the non-EXIF header
if ((index + size - orginExifDataLength - sizeof(exifHeader)) > size) {
HiLog::Error(LABEL, "There is not enough space for writing JPEG image data!");
free(tempBuf);
tempBuf = nullptr;
exif_data_unref(ptrExifData);
return Media::ERR_MEDIA_OUT_OF_RANGE;
}
for (unsigned int i = 0; i < (size - orginExifDataLength - sizeof(exifHeader)); i++) {
tempBuf[index] = data[orginExifDataLength + sizeof(exifHeader) + i];
index += 1;
}
for (unsigned int i = 0; i < size; i++) {
data[i] = tempBuf[i];
}
ParseExifData(data, static_cast<unsigned int>(index));
free(tempBuf);
tempBuf = nullptr;
exif_data_unref(ptrExifData);
return Media::SUCCESS;
}
ExifEntry* EXIFInfo::InitExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag)
@ -411,7 +434,7 @@ ExifEntry* EXIFInfo::CreateExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag,
{
void *buf;
ExifEntry *entry;
if ((entry = exif_content_get_entry(exif->ifd[ifd], tag)) != nullptr) {
return entry;
}
@ -461,30 +484,247 @@ long EXIFInfo::GetFileSize(FILE *fp)
/* Save the current position. */
position = ftell(fp);
/* Jump to the end of the file. */
fseek(fp, 0L, SEEK_END);
(void)fseek(fp, 0L, SEEK_END);
/* Get the end position. */
size = ftell(fp);
/* Jump back to the original position. */
fseek(fp, position, SEEK_SET);
(void)fseek(fp, position, SEEK_SET);
return size;
}
void EXIFInfo::ReleaseSource(unsigned char *buf, FILE *file)
bool EXIFInfo::CreateExifData(unsigned char *buf, unsigned long length, ExifData **ptrData, bool &isNewExifData)
{
if (buf) {
free(buf);
buf = nullptr;
if ((buf[BUFFER_POSITION_6] == 'E' && buf[BUFFER_POSITION_7] == 'x' &&
buf[BUFFER_POSITION_8] == 'i' && buf[BUFFER_POSITION_9] == 'f')) {
*ptrData = exif_data_new_from_data(buf, static_cast<unsigned int>(length));
if (!(*ptrData)) {
HiLog::Error(LABEL, "Create exif data from file failed.");
return false;
}
isNewExifData = false;
HiLog::Error(LABEL, "Create exif data from buffer.");
} else {
*ptrData = exif_data_new();
if (!(*ptrData)) {
HiLog::Error(LABEL, "Create exif data failed.");
return false;
}
/* Set the image options */
exif_data_set_option(*ptrData, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
exif_data_set_data_type(*ptrData, EXIF_DATA_TYPE_COMPRESSED);
exif_data_set_byte_order(*ptrData, EXIF_BYTE_ORDER_INTEL);
/* Create the mandatory EXIF fields with default data */
exif_data_fix(*ptrData);
isNewExifData = true;
HiLog::Error(LABEL, "Create new exif data.");
}
return true;
}
unsigned int EXIFInfo::GetOrginExifDataLength(const bool &isNewExifData, unsigned char *buf)
{
unsigned int orginExifDataLength = 0;
if (!isNewExifData) {
unsigned char lenthArray[LENGTH_ARRAY_SIZE] = {
buf[BUFFER_POSITION_5], buf[BUFFER_POSITION_4]
};
orginExifDataLength = *(unsigned int*)lenthArray;
}
return orginExifDataLength;
}
ExifByteOrder EXIFInfo::GetExifByteOrder(const bool &isNewExifData, unsigned char *buf)
{
if (isNewExifData) {
return EXIF_BYTE_ORDER_INTEL;
} else {
if (buf[BUFFER_POSITION_12] == 'M' && buf[BUFFER_POSITION_13] == 'M') {
return EXIF_BYTE_ORDER_MOTOROLA;
} else {
return EXIF_BYTE_ORDER_INTEL;
}
}
}
bool EXIFInfo::CreateExifEntry(const ExifTag &tag, ExifData *data, const std::string &value,
ExifByteOrder order, ExifEntry **ptrEntry)
{
switch (tag) {
case EXIF_TAG_BITS_PER_SAMPLE: {
*ptrEntry = InitExifTag(data, EXIF_IFD_1, EXIF_TAG_BITS_PER_SAMPLE);
std::vector<std::string> bitsVec;
SplitStr(value, ",", bitsVec);
if (bitsVec.size() > CONSTANT_2) {
HiLog::Error(LABEL, "BITS_PER_SAMPLE Invalid value %{public}s", value.c_str());
return false;
}
if (bitsVec.size() != 0) {
for (size_t i = 0; i < bitsVec.size(); i++) {
exif_set_short((*ptrEntry)->data + i * CONSTANT_2, order, (ExifShort)atoi(bitsVec[i].c_str()));
}
}
break;
}
case EXIF_TAG_ORIENTATION: {
*ptrEntry = InitExifTag(data, EXIF_IFD_0, EXIF_TAG_ORIENTATION);
exif_set_short((*ptrEntry)->data, order, (ExifShort)atoi(value.c_str()));
break;
}
case EXIF_TAG_IMAGE_LENGTH: {
*ptrEntry = InitExifTag(data, EXIF_IFD_1, EXIF_TAG_IMAGE_LENGTH);
exif_set_long((*ptrEntry)->data, order, (ExifLong)atoi(value.c_str()));
break;
}
case EXIF_TAG_IMAGE_WIDTH: {
*ptrEntry = InitExifTag(data, EXIF_IFD_1, EXIF_TAG_IMAGE_WIDTH);
exif_set_long((*ptrEntry)->data, order, (ExifLong)atoi(value.c_str()));
break;
}
case EXIF_TAG_GPS_LATITUDE: {
std::vector<std::string> latVec;
SplitStr(value, ",", latVec);
if (latVec.size() != CONSTANT_2) {
HiLog::Error(LABEL, "GPS_LATITUDE Invalid value %{public}s", value.c_str());
return false;
}
ExifRational latRational;
latRational.numerator = atoi(latVec[0].c_str());
latRational.denominator = atoi(latVec[1].c_str());
*ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE,
sizeof(latRational), EXIF_FORMAT_RATIONAL);
exif_set_rational((*ptrEntry)->data, order, latRational);
break;
}
case EXIF_TAG_GPS_LONGITUDE: {
std::vector<std::string> longVec;
SplitStr(value, ",", longVec);
if (longVec.size() != CONSTANT_2) {
HiLog::Error(LABEL, "GPS_LONGITUDE Invalid value %{public}s", value.c_str());
return false;
}
ExifRational longRational;
longRational.numerator = atoi(longVec[0].c_str());
longRational.denominator = atoi(longVec[1].c_str());
*ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE,
sizeof(longRational), EXIF_FORMAT_RATIONAL);
exif_set_rational((*ptrEntry)->data, order, longRational);
break;
}
case EXIF_TAG_GPS_LATITUDE_REF: {
*ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF,
value.length(), EXIF_FORMAT_ASCII);
if (memcpy_s((*ptrEntry)->data, value.length(), value.c_str(), value.length()) != 0) {
HiLog::Error(LABEL, "LATITUDE ref memcpy error");
}
break;
}
case EXIF_TAG_GPS_LONGITUDE_REF: {
*ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF,
value.length(), EXIF_FORMAT_ASCII);
if (memcpy_s((*ptrEntry)->data, value.length(), value.c_str(), value.length()) != 0) {
HiLog::Error(LABEL, "LONGITUDE ref memcpy error");
}
break;
}
default:
break;
}
return true;
}
bool EXIFInfo::WriteExifDataToFile(ExifData *data, unsigned int orginExifDataLength, unsigned long fileLength,
unsigned char *buf, FILE *fp)
{
unsigned char* exifDataBuf = nullptr;
unsigned int exifDataBufLength = 0;
exif_data_save_data(data, &exifDataBuf, &exifDataBufLength);
if (exifDataBuf == nullptr) {
HiLog::Error(LABEL, "Get Exif Data Buf failed!");
return false;
}
if (file != nullptr) {
fclose(file);
file = nullptr;
// Write EXIF header
if (fwrite(exifHeader, sizeof(exifHeader), 1, fp) != 1) {
HiLog::Error(LABEL, "Error writing EXIF header to file!");
return false;
}
// Write EXIF block length in big-endian order
if (fputc((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8, fp) < 0) {
HiLog::Error(LABEL, "Error writing EXIF block length to file!");
return false;
}
if (fputc((exifDataBufLength + LENGTH_OFFSET_2) & 0xff, fp) < 0) {
HiLog::Error(LABEL, "Error writing EXIF block length to file!");
return false;
}
// Write EXIF data block
if (fwrite(exifDataBuf, exifDataBufLength, 1, fp) != 1) {
HiLog::Error(LABEL, "Error writing EXIF data block to file!");
return false;
}
// Write JPEG image data, skipping the non-EXIF header
unsigned int dataOffset = orginExifDataLength + sizeof(exifHeader);
if (fwrite(buf + dataOffset, fileLength - dataOffset, 1, fp) != 1) {
HiLog::Error(LABEL, "Error writing JPEG image data to file!");
return false;
}
UpdateCacheExifData(fp);
return true;
}
void EXIFInfo::ReleaseSource(unsigned char **ptrBuf, FILE **ptrFile)
{
if (*ptrBuf) {
free(*ptrBuf);
*ptrBuf = nullptr;
ptrBuf = nullptr;
}
if (*ptrFile != nullptr) {
fclose(*ptrFile);
*ptrFile = nullptr;
ptrFile = nullptr;
}
}
void EXIFInfo::UpdateCacheExifData(FILE *fp)
{
unsigned long fileLength = GetFileSize(fp);
if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
HiLog::Error(LABEL, "Get file size failed.");
return;
}
unsigned char *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
if (fileBuf == nullptr) {
HiLog::Error(LABEL, "Allocate buf failed.");
return;
}
// Set current position to begin of file.
(void)fseek(fp, 0L, 0);
if (fread(fileBuf, fileLength, 1, fp) != 1) {
HiLog::Error(LABEL, "Read new file failed.");
free(fileBuf);
fileBuf = nullptr;
return;
}
ParseExifData(fileBuf, static_cast<unsigned int>(fileLength));
free(fileBuf);
fileBuf = nullptr;
}
} // namespace ImagePlugin
} // namespace OHOS

View File

@ -600,34 +600,25 @@ uint32_t JpegDecoder::GetImagePropertyString(uint32_t index, const std::string &
return Media::SUCCESS;
}
ExifTag JpegDecoder::getExifTagFromKey(const std::string &key, const std::string &value)
ExifTag JpegDecoder::getExifTagFromKey(const std::string &key)
{
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;
@ -637,15 +628,50 @@ ExifTag JpegDecoder::getExifTagFromKey(const std::string &key, const std::string
uint32_t JpegDecoder::ModifyImageProperty(uint32_t index, const std::string &key,
const std::string &value, const std::string &path)
{
HiLog::Error(LABEL, "[ModifyImageProperty] enter jped plugin, key:%{public}s, value:%{public}s",
key.c_str(), value.c_str());
ExifTag tag = getExifTagFromKey(key, value);
HiLog::Error(LABEL, "[ModifyImageProperty] with path:%{public}s, key:%{public}s, value:%{public}s",
path.c_str(), key.c_str(), value.c_str());
ExifTag tag = getExifTagFromKey(key);
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;
uint32_t ret = exifInfo_.ModifyExifData(tag, value, path);
if (ret != Media::SUCCESS) {
return ret;
}
return Media::SUCCESS;
}
uint32_t JpegDecoder::ModifyImageProperty(uint32_t index, const std::string &key,
const std::string &value, const int fd)
{
HiLog::Error(LABEL, "[ModifyImageProperty] with fd:%{public}d, key:%{public}s, value:%{public}s",
fd, key.c_str(), value.c_str());
ExifTag tag = getExifTagFromKey(key);
if (tag == EXIF_TAG_PRINT_IMAGE_MATCHING) {
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
uint32_t ret = exifInfo_.ModifyExifData(tag, value, fd);
if (ret != Media::SUCCESS) {
return ret;
}
return Media::SUCCESS;
}
uint32_t JpegDecoder::ModifyImageProperty(uint32_t index, const std::string &key,
const std::string &value, uint8_t *data, uint32_t size)
{
HiLog::Error(LABEL, "[ModifyImageProperty] with buffer:%{public}p, key:%{public}s, value:%{public}s",
data, key.c_str(), value.c_str());
ExifTag tag = getExifTagFromKey(key);
if (tag == EXIF_TAG_PRINT_IMAGE_MATCHING) {
return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
}
uint32_t ret = exifInfo_.ModifyExifData(tag, value, data, size);
if (ret != Media::SUCCESS) {
return ret;
}
return Media::SUCCESS;
}

View File

@ -154,6 +154,18 @@ public:
return Media::ERR_MEDIA_INVALID_OPERATION;
}
virtual uint32_t ModifyImageProperty(uint32_t index, const std::string &key,
const std::string &value, const int fd)
{
return Media::ERR_MEDIA_INVALID_OPERATION;
}
virtual uint32_t ModifyImageProperty(uint32_t index, const std::string &key,
const std::string &value, uint8_t *data, uint32_t size)
{
return Media::ERR_MEDIA_INVALID_OPERATION;
}
// define multiple subservices for this interface
static constexpr uint16_t SERVICE_DEFAULT = 0;
};