diff --git a/frameworks/innerkitsimpl/codec/src/image_source.cpp b/frameworks/innerkitsimpl/codec/src/image_source.cpp index 5ea45128d3106536a6294b735c7beb771c04d94c..4f5510205e290e4ce9bdc8baec9db9a411e1652b 100644 --- a/frameworks/innerkitsimpl/codec/src/image_source.cpp +++ b/frameworks/innerkitsimpl/codec/src/image_source.cpp @@ -1213,11 +1213,17 @@ uint32_t ImageSource::ModifyImageProperty(std::shared_ptr meta return metadataAccessor->Write(); } +uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value) +{ + std::unique_lock guard(decodingMutex_); + return ModifyImageProperty(key, value); +} + uint32_t ImageSource::ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value, const std::string &path) { ImageDataStatistics imageDataStatistics("[ImageSource]ModifyImageProperty by path."); - + #if !defined(IOS_PLATFORM) if (!std::filesystem::exists(path)) { return ERR_IMAGE_SOURCE_DATA; @@ -1467,6 +1473,36 @@ bool ImageSource::IsHdrImage() return sourceHdrType_ > ImageHdrType::SDR; } +uint32_t ImageSource::RemoveImageProperties(uint32_t index, const std::set &keys, const std::string &path) +{ +#if !defined(IOS_PLATFORM) + if (!std::filesystem::exists(path)) { + return ERR_IMAGE_SOURCE_DATA; + } +#endif + + std::unique_lock guard(decodingMutex_); + auto metadataAccessor = MetadataAccessorFactory::Create(path); + return RemoveImageProperties(metadataAccessor, keys); +} + +uint32_t ImageSource::RemoveImageProperties(uint32_t index, const std::set &keys, const int fd) +{ + if (fd <= STDERR_FILENO) { + return ERR_IMAGE_SOURCE_DATA; + } + + std::unique_lock guard(decodingMutex_); + auto metadataAccessor = MetadataAccessorFactory::Create(fd); + return RemoveImageProperties(metadataAccessor, keys); +} + +uint32_t ImageSource::RemoveImageProperties(uint32_t index, const std::set &keys, + uint8_t *data, uint32_t size) +{ + return ERR_MEDIA_WRITE_PARCEL_FAIL; +} + // ------------------------------- private method ------------------------------- ImageSource::ImageSource(unique_ptr &&stream, const SourceOptions &opts) : sourceStreamPtr_(stream.release()) @@ -3071,6 +3107,33 @@ bool ImageSource::ComposeHdrImage(ImageHdrType hdrType, DecodeContext& baseCtx, return true; } +uint32_t ImageSource::RemoveImageProperties(std::shared_ptr metadataAccessor, + const std::set &keys) +{ + if (metadataAccessor == nullptr) { + IMAGE_LOGE("Failed to create image accessor when attempting to modify image property."); + return ERR_IMAGE_SOURCE_DATA; + } + uint32_t ret = CreatExifMetadataByImageSource(); + if (ret != SUCCESS) { + IMAGE_LOGE("Failed to create ExifMetadata."); + return ret; + } + + bool deletFlag = false; + for (auto key: keys) { + bool result = exifMetadata_->RemoveEntry(key); + deletFlag |= result; + } + + if (!deletFlag) { + return ERR_MEDIA_NO_EXIF_DATA; + } + + metadataAccessor->Set(exifMetadata_); + return metadataAccessor->Write(); +} + static void SetContext(DecodeContext& context, sptr& sb, void* fd) { context.allocatorType = AllocatorType::DMA_ALLOC; diff --git a/frameworks/innerkitsimpl/test/unittest/image_source_test/image_source_exif_test.cpp b/frameworks/innerkitsimpl/test/unittest/image_source_test/image_source_exif_test.cpp index fd191163ab61a4c6ab9a71cccdc9c86d2d1a9fc1..370f1302379fd35580b37bc428cb82c64531dacb 100644 --- a/frameworks/innerkitsimpl/test/unittest/image_source_test/image_source_exif_test.cpp +++ b/frameworks/innerkitsimpl/test/unittest/image_source_test/image_source_exif_test.cpp @@ -28,6 +28,12 @@ namespace Media { static const std::string IMAGE_INPUT_EXIF_JPEG_PATH = "/data/local/tmp/image/test_exif.jpg"; static const std::string IMAGE_INPUT_NO_EXIF_JPEG_PATH = "/data/local/tmp/image/hasNoExif.jpg"; +static const std::string IMAGE_REMOVE_EXIF_JPEG_PATH = "/data/local/tmp/image/test_remove_exif.jpg"; +static const std::string IMAGE_REMOVE_EXIF_PNG_PATH = "/data/local/tmp/image/test_remove_exif.png"; +static const std::string IMAGE_REMOVE_EXIF_WEBP_PATH = "/data/local/tmp/image/test_remove_exif.webp"; +static const std::string IMAGE_REMOVE_EXIF_HEIF_PATH = "/data/local/tmp/image/test_remove_exif.heic"; +static const std::string IMAGE_REMOVE_HW_EXIF_PATH = "/data/local/tmp/image/test_remove_hw_exif.jpg"; +static const std::string IMAGE_REMOVE_NO_EXIF_JPEG_PATH = "/data/local/tmp/image/test_remove_no_exif.jpg"; class ImageSourceExifTest : public testing::Test { public: @@ -35,6 +41,13 @@ public: ~ImageSourceExifTest() {} }; +static std::string GetProperty(std::unique_ptr &imageSource, const std::string &prop) +{ + std::string value; + imageSource->GetImagePropertyString(0, prop, value); + return value; +} + /** * @tc.name: ModifyImageProperty001 * @tc.desc: test ModifyImageProperty fd jpeg @@ -156,6 +169,37 @@ HWTEST_F(ImageSourceExifTest, ModifyImageProperty003, TestSize.Level3) GTEST_LOG_(INFO) << "ImageSourceExifTest: ModifyImageProperty003 end"; } +HWTEST_F(ImageSourceExifTest, ModifyImageProperty004, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImageSourceExifTest: ModifyImageProperty004 start"; + uint32_t errorCode = 0; + SourceOptions opts; + opts.formatHint = "image/jpeg"; + std::string path = IMAGE_INPUT_EXIF_JPEG_PATH; + std::unique_ptr imageSource = ImageSource::CreateImageSource(path, opts, errorCode); + std::string valueGetIn; + uint32_t index = 0; + std::string key = "GPSLongitudeRef"; + errorCode = imageSource->GetImagePropertyString(index, key, valueGetIn); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_EQ(valueGetIn, "W"); + + int32_t retModify = imageSource->ModifyImageProperty(index, key, "E"); + ASSERT_EQ(retModify, OHOS::Media::SUCCESS); + std::string checkStr; + imageSource->GetImagePropertyString(index, key, checkStr); + ASSERT_EQ(checkStr, "E"); + + std::string value; + std::unique_ptr imageSourceOut = ImageSource::CreateImageSource(path, opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + errorCode = imageSourceOut->GetImagePropertyString(index, key, value); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_EQ(value, "W"); + + GTEST_LOG_(INFO) << "ImageSourceExifTest: ModifyImageProperty004 end"; +} + HWTEST_F(ImageSourceExifTest, GetImagePropertyInt001, TestSize.Level3) { GTEST_LOG_(INFO) << "ImageSourceExifTest: GetImagePropertyInt001 start"; @@ -230,5 +274,146 @@ HWTEST_F(ImageSourceExifTest, GetImagePropertyInt002, TestSize.Level3) GTEST_LOG_(INFO) << "ImageSourceExifTest: GetImagePropertyInt002 end"; } + +HWTEST_F(ImageSourceExifTest, RemoveImageProperty001, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty001 start"; + + std::string path =IMAGE_REMOVE_EXIF_JPEG_PATH; + const int fd = open(path.c_str(), O_RDWR | S_IRUSR | S_IWUSR); + ASSERT_NE(fd, -1); + uint32_t errorCode = 0; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(fd, opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_EQ(GetProperty(imageSource, "DateTimeOriginal"), "2024:01:11 09:39:58"); + ASSERT_EQ(GetProperty(imageSource, "ExposureTime"), "1/590 sec."); + ASSERT_EQ(GetProperty(imageSource, "SceneType"), "Directly photographed"); + std::set keys = {"DateTimeOriginal", "ExposureTime", "SceneType"}; + errorCode = imageSource->RemoveImageProperties(0, keys, fd); + ASSERT_EQ(errorCode, SUCCESS); + + std::unique_ptr imageSourceNew = ImageSource::CreateImageSource(path, opts, errorCode); + std::string value; + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "DateTimeOriginal", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "ExposureTime", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "SceneType", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty001 end"; +} + +HWTEST_F(ImageSourceExifTest, RemoveImageProperty002, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty002 start"; + + uint32_t errorCode = 0; + std::string path = IMAGE_REMOVE_EXIF_PNG_PATH; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(path, opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_EQ(GetProperty(imageSource, "DateTime"), "2015:11:05 23:04:30"); + ASSERT_EQ(GetProperty(imageSource, "YCbCrPositioning"), "Centered"); + + std::set keys = {"DateTime", "YCbCrPositioning"}; + errorCode = imageSource->RemoveImageProperties(0, keys, path); + ASSERT_EQ(errorCode, SUCCESS); + std::unique_ptr imageSourceNew = ImageSource::CreateImageSource(path, opts, errorCode); + std::string value; + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "DateTime", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "YCbCrPositioning", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty002 end"; +} + +HWTEST_F(ImageSourceExifTest, RemoveImageProperty003, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty003 start"; + + uint32_t errorCode = 0; + std::string path = IMAGE_REMOVE_EXIF_WEBP_PATH; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(path, opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_EQ(GetProperty(imageSource, "DateTimeOriginal"), "2022:06:02 15:51:35"); + ASSERT_EQ(GetProperty(imageSource, "ExposureTime"), "1/33 sec."); + ASSERT_EQ(GetProperty(imageSource, "SceneType"), "Directly photographed"); + std::set keys = {"DateTimeOriginal", "ExposureTime", "SceneType"}; + errorCode = imageSource->RemoveImageProperties(0, keys, path); + ASSERT_EQ(errorCode, SUCCESS); + + std::unique_ptr imageSourceNew = ImageSource::CreateImageSource(path, opts, errorCode); + std::string value; + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "DateTimeOriginal", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "ExposureTime", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "SceneType", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty003 end"; +} + +HWTEST_F(ImageSourceExifTest, RemoveImageProperty004, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty004 start"; + + uint32_t errorCode = 0; + std::string path = IMAGE_REMOVE_HW_EXIF_PATH; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(path, opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + + ASSERT_EQ(GetProperty(imageSource, "HwMnoteBurstNumber"), "2"); + ASSERT_EQ(GetProperty(imageSource, "HwMnoteCaptureMode"), "1"); + ASSERT_EQ(GetProperty(imageSource, "HwMnoteFaceConf"), "3"); + std::set keys = {"HwMnoteBurstNumber", "HwMnoteCaptureMode", "HwMnoteFaceConf"}; + errorCode = imageSource->RemoveImageProperties(0, keys, path); + ASSERT_EQ(errorCode, SUCCESS); + + ASSERT_EQ(GetProperty(imageSource, "HwMnoteBurstNumber"), "2"); + ASSERT_EQ(GetProperty(imageSource, "HwMnoteCaptureMode"), "default_exif_value"); + ASSERT_EQ(GetProperty(imageSource, "HwMnoteFaceConf"), "3"); + + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty004 end"; +} + +HWTEST_F(ImageSourceExifTest, RemoveImageProperty005, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty005 start"; + + uint32_t errorCode = 0; + std::string path = IMAGE_REMOVE_EXIF_HEIF_PATH; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(path, opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_EQ(GetProperty(imageSource, "DateTimeOriginal"), "2024:02:28 09:23:06"); + ASSERT_EQ(GetProperty(imageSource, "ExposureTime"), "1/50 sec."); + ASSERT_EQ(GetProperty(imageSource, "SceneType"), "Directly photographed"); + std::set keys = {"DateTimeOriginal", "ExposureTime", "SceneType"}; + errorCode = imageSource->RemoveImageProperties(0, keys, path); + ASSERT_EQ(errorCode, SUCCESS); + + std::unique_ptr imageSourceNew = ImageSource::CreateImageSource(path, opts, errorCode); + std::string value; + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "DateTimeOriginal", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "ExposureTime", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + ASSERT_EQ(imageSourceNew->GetImagePropertyString(0, "SceneType", value), ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty005 end"; +} + +HWTEST_F(ImageSourceExifTest, RemoveImageProperty006, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty006 start"; + + uint32_t errorCode = 0; + std::string path = IMAGE_REMOVE_NO_EXIF_JPEG_PATH; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(path, opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + std::set keys = {"DateTimeOriginal", "ExposureTime", "SceneType"}; + errorCode = imageSource->RemoveImageProperties(0, keys, path); + ASSERT_EQ(errorCode, ERR_IMAGE_DECODE_EXIF_UNSUPPORT); + + GTEST_LOG_(INFO) << "ImageSourceExifTest: RemoveImageProperty006 end"; +} + } // namespace Multimedia } // namespace OHOS diff --git a/interfaces/innerkits/include/image_source.h b/interfaces/innerkits/include/image_source.h index 93eebb95c4a06d1781156249b01b652bf1fa115b..c32c7ac9950f4ab3bed245d67340981c15de34b1 100644 --- a/interfaces/innerkits/include/image_source.h +++ b/interfaces/innerkits/include/image_source.h @@ -201,6 +201,13 @@ public: 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 uint32_t ModifyImageProperty(uint32_t index, const std::string &key, const std::string &value); + NATIVEEXPORT uint32_t RemoveImageProperties(uint32_t index, const std::set &keys, + const std::string &path); + NATIVEEXPORT uint32_t RemoveImageProperties(uint32_t index, const std::set &keys, + const int fd); + NATIVEEXPORT uint32_t RemoveImageProperties(uint32_t index, const std::set &keys, + uint8_t *data, uint32_t size); NATIVEEXPORT const NinePatchInfo &GetNinePatchInfo() const; NATIVEEXPORT void SetMemoryUsagePreference(const MemoryUsagePreference preference); NATIVEEXPORT MemoryUsagePreference GetMemoryUsagePreference(); @@ -287,6 +294,8 @@ private: static uint64_t GetNowTimeMicroSeconds(); uint32_t ModifyImageProperty(std::shared_ptr metadataAccessor, const std::string &key, const std::string &value); + uint32_t RemoveImageProperties(std::shared_ptr metadataAccessor, + const std::set &key); uint32_t ModifyImageProperty(const std::string &key, const std::string &value); uint32_t CreatExifMetadataByImageSource(bool addFlag = false); uint32_t SetExifMetadata(uint8_t *buffer, const uint32_t size, bool addFlag); diff --git a/test/resource/image/images/exif/test_remove_exif.heic b/test/resource/image/images/exif/test_remove_exif.heic new file mode 100644 index 0000000000000000000000000000000000000000..baf2ebd2993ec047d3f4451561605d7c4787d4a1 Binary files /dev/null and b/test/resource/image/images/exif/test_remove_exif.heic differ diff --git a/test/resource/image/images/exif/test_remove_exif.jpg b/test/resource/image/images/exif/test_remove_exif.jpg new file mode 100644 index 0000000000000000000000000000000000000000..61c7d661586403275bb95eb94f229b90048c9969 Binary files /dev/null and b/test/resource/image/images/exif/test_remove_exif.jpg differ diff --git a/test/resource/image/images/exif/test_remove_exif.png b/test/resource/image/images/exif/test_remove_exif.png new file mode 100644 index 0000000000000000000000000000000000000000..f10516fb2a9c674f56dab0b36277b2650d31a657 Binary files /dev/null and b/test/resource/image/images/exif/test_remove_exif.png differ diff --git a/test/resource/image/images/exif/test_remove_exif.webp b/test/resource/image/images/exif/test_remove_exif.webp new file mode 100644 index 0000000000000000000000000000000000000000..41a62c92e8b69738fe161f556d557de16d64f6a4 Binary files /dev/null and b/test/resource/image/images/exif/test_remove_exif.webp differ diff --git a/test/resource/image/images/exif/test_remove_hw_exif.jpg b/test/resource/image/images/exif/test_remove_hw_exif.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b8052eaaab36cc7860231c0a2ba4f9e4c4815519 Binary files /dev/null and b/test/resource/image/images/exif/test_remove_hw_exif.jpg differ diff --git a/test/resource/image/images/exif/test_remove_no_exif.jpg b/test/resource/image/images/exif/test_remove_no_exif.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e09e9fa50455263369cb0ae4f7990948ff45b3db Binary files /dev/null and b/test/resource/image/images/exif/test_remove_no_exif.jpg differ diff --git a/test/resource/image/ohos_test.xml b/test/resource/image/ohos_test.xml index 3b50f79ef62e7d532add204346fffd0d61bd8fed..0338a1c258ad054654a766acf3bf8600a315a338 100644 --- a/test/resource/image/ohos_test.xml +++ b/test/resource/image/ohos_test.xml @@ -73,6 +73,12 @@