1/* 2 * Copyright (C) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "gtest/gtest.h" 17 18#include "image_effect_inner.h" 19#include "efilter_factory.h" 20#include "mock_pixel_map.h" 21#include "brightness_efilter.h" 22#include "contrast_efilter.h" 23#include "test_common.h" 24#include "external_loader.h" 25#include "crop_efilter.h" 26#include "mock_producer_surface.h" 27 28using namespace testing::ext; 29using namespace OHOS::Media::Effect; 30 31static std::string g_jpgPath; 32static std::string g_notJpgPath; 33static std::string g_jpgUri; 34static std::string g_notJpgUri; 35 36namespace OHOS { 37namespace Media { 38namespace Effect { 39namespace Test { 40class CustomTestEFilter : public IFilterDelegate { 41public: 42 bool Render(void *efilter, EffectBuffer *src, EffectBuffer *dst, std::shared_ptr<EffectContext> &context) override 43 { 44 return true; 45 } 46 47 bool Render(void *efilter, EffectBuffer *src, std::shared_ptr<EffectContext> &context) override 48 { 49 return true; 50 } 51 52 bool SetValue(void *efilter, const std::string &key, const Plugin::Any &value) override 53 { 54 return true; 55 } 56 57 bool Save(void *efilter, EffectJsonPtr &res) override 58 { 59 auto *filter = static_cast<EFilter *>(efilter); 60 return filter != nullptr && filter->Save(res) == ErrorCode::SUCCESS; 61 } 62 63 void *Restore(const EffectJsonPtr &values) override 64 { 65 filter_ = EFilterFactory::Instance()->Create(CUSTOM_TEST_EFILTER); 66 Plugin::Any brightness = values->GetFloat("brightness"); 67 filter_->SetValue("brightness", brightness); 68 return filter_.get(); 69 } 70 71 void *GetEffectInfo() override 72 { 73 if (info_ != nullptr) { 74 return &info_; 75 } 76 info_ = std::make_unique<EffectInfo>(); 77 info_->formats_.emplace(IEffectFormat::RGBA8888, std::vector<IPType>{ IPType::CPU }); 78 info_->category_ = Category::SHAPE_ADJUST; 79 return &info_; 80 } 81private: 82 static std::shared_ptr<EffectInfo> info_; 83 std::shared_ptr<EFilter> filter_; 84}; 85std::shared_ptr<EffectInfo> CustomTestEFilter::info_ = nullptr; 86 87class TestImageEffect : public testing::Test { 88public: 89 TestImageEffect() = default; 90 91 ~TestImageEffect() override = default; 92 93 static void SetUpTestCase() 94 { 95 g_jpgPath = std::string("/data/test/resource/image_effect_test1.jpg"); 96 g_notJpgPath = std::string("/data/test/resource/image_effect_test2.png"); 97 g_jpgUri = std::string("file:///data/test/resource/image_effect_test1.jpg"); 98 g_notJpgUri = std::string("file:///data/test/resource/image_effect_test2.png"); 99 } 100 101 static void TearDownTestCase() {} 102 103 void SetUp() override 104 { 105 mockPixelMap_ = new MockPixelMap(); 106 imageEffect_ = new ImageEffect(); 107 ExternLoader::Instance()->InitExt(); 108 EFilterFactory::Instance()->functions_.clear(); 109 EFilterFactory::Instance()->RegisterEFilter<BrightnessEFilter>(BRIGHTNESS_EFILTER); 110 EFilterFactory::Instance()->RegisterEFilter<ContrastEFilter>(CONTRAST_EFILTER); 111 EFilterFactory::Instance()->RegisterEFilter<CropEFilter>(CROP_EFILTER); 112 } 113 114 void TearDown() override 115 { 116 delete mockPixelMap_; 117 mockPixelMap_ = nullptr; 118 delete imageEffect_; 119 imageEffect_ = nullptr; 120 } 121 PixelMap *mockPixelMap_ = nullptr; 122 ImageEffect *imageEffect_ = nullptr; 123}; 124 125HWTEST_F(TestImageEffect, AddEfilter001, TestSize.Level1) 126{ 127 std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(IMAGE_EFFECT_NAME); 128 std::shared_ptr<EFilter> brightnessEFilter = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 129 imageEffect->AddEFilter(brightnessEFilter); 130 ASSERT_EQ(imageEffect->efilters_.size(), 1); 131 ASSERT_EQ(imageEffect->efilters_.at(0), brightnessEFilter); 132 133 std::shared_ptr<EFilter> cropEFilter1 = EFilterFactory::Instance()->Create(CROP_EFILTER); 134 imageEffect->AddEFilter(cropEFilter1); 135 ASSERT_EQ(imageEffect->efilters_.size(), 2); 136 ASSERT_EQ(imageEffect->efilters_.at(0), cropEFilter1); 137 ASSERT_EQ(imageEffect->efilters_.at(1), brightnessEFilter); 138 139 std::shared_ptr<EFilter> cropEFilter2 = EFilterFactory::Instance()->Create(CROP_EFILTER); 140 imageEffect->AddEFilter(cropEFilter2); 141 ASSERT_EQ(imageEffect->efilters_.size(), 3); 142 ASSERT_EQ(imageEffect->efilters_.at(0), cropEFilter1); 143 ASSERT_EQ(imageEffect->efilters_.at(1), cropEFilter2); 144 ASSERT_EQ(imageEffect->efilters_.at(2), brightnessEFilter); 145} 146 147HWTEST_F(TestImageEffect, Start001, TestSize.Level1) 148{ 149 std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(IMAGE_EFFECT_NAME); 150 std::shared_ptr<EFilter> efilter = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 151 Plugin::Any value = 100.f; 152 ErrorCode result = efilter->SetValue(KEY_FILTER_INTENSITY, value); 153 ASSERT_EQ(result, ErrorCode::SUCCESS); 154 imageEffect->AddEFilter(efilter); 155 result = imageEffect->SetInputPixelMap(mockPixelMap_); 156 ASSERT_EQ(result, ErrorCode::SUCCESS); 157 result = imageEffect->SetOutputPixelMap(mockPixelMap_); 158 ASSERT_EQ(result, ErrorCode::SUCCESS); 159 result = imageEffect->Start(); 160 ASSERT_EQ(result, ErrorCode::SUCCESS); 161} 162 163HWTEST_F(TestImageEffect, InsertEfilter001, TestSize.Level1) 164{ 165 std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(IMAGE_EFFECT_NAME); 166 std::shared_ptr<EFilter> brightnessEFilter1 = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 167 imageEffect->InsertEFilter(brightnessEFilter1, 0); 168 ASSERT_EQ(imageEffect->efilters_.size(), 1); 169 ASSERT_EQ(imageEffect->efilters_.at(0), brightnessEFilter1); 170 171 std::shared_ptr<EFilter> contrastEFilter = EFilterFactory::Instance()->Create(CONTRAST_EFILTER); 172 imageEffect->AddEFilter(contrastEFilter); 173 ASSERT_EQ(imageEffect->efilters_.size(), 2); 174 ASSERT_EQ(imageEffect->efilters_.at(0), brightnessEFilter1); 175 ASSERT_EQ(imageEffect->efilters_.at(1), contrastEFilter); 176 177 std::shared_ptr<EFilter> brightnessEFilter2 = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 178 imageEffect->InsertEFilter(brightnessEFilter2, 1); 179 ASSERT_EQ(imageEffect->efilters_.size(), 3); 180 ASSERT_EQ(imageEffect->efilters_.at(0), brightnessEFilter1); 181 ASSERT_EQ(imageEffect->efilters_.at(1), brightnessEFilter2); 182 ASSERT_EQ(imageEffect->efilters_.at(2), contrastEFilter); 183} 184 185HWTEST_F(TestImageEffect, InsertEfilter002, TestSize.Level1) 186{ 187 std::shared_ptr<ImageEffect> imageEffect = std::make_unique<ImageEffect>(IMAGE_EFFECT_NAME); 188 std::shared_ptr<EFilter> brightnessEFilter1 = EFilterFactory::Instance()->Create(BRIGHTNESS_EFILTER); 189 ErrorCode result = imageEffect->InsertEFilter(brightnessEFilter1, 1); 190 ASSERT_NE(result, ErrorCode::SUCCESS); 191} 192 193/** 194 * Feature: ImageEffect 195 * Function: Test ImageEffect::SetInputPath with normal param 196 * SubFunction: NA 197 * FunctionPoints: NA 198 * EnvConditions: NA 199 * CaseDescription: Test ImageEffect::SetInputPath with normal param 200 */ 201HWTEST_F(TestImageEffect, SetInputPath001, TestSize.Level1) 202{ 203 ErrorCode result = imageEffect_->SetInputPath(g_jpgPath); 204 ASSERT_EQ(result, ErrorCode::SUCCESS); 205} 206 207/** 208 * Feature: ImageEffect 209 * Function: Test ImageEffect::SetInputPath with nullptr param 210 * SubFunction: NA 211 * FunctionPoints: NA 212 * EnvConditions: NA 213 * CaseDescription: Test ImageEffect::SetInputPath with nullptr param 214 */ 215HWTEST_F(TestImageEffect, SetInputPath002, TestSize.Level1) 216{ 217 ErrorCode result = imageEffect_->SetInputPath(nullptr); 218 ASSERT_NE(result, ErrorCode::SUCCESS); 219} 220 221/** 222 * Feature: ImageEffect 223 * Function: Test ImageEffect::SetInputPath with not support type param 224 * SubFunction: NA 225 * FunctionPoints: NA 226 * EnvConditions: NA 227 * CaseDescription: Test ImageEffect::SetInputPath with not support type param 228 */ 229HWTEST_F(TestImageEffect, SetInputPath003, TestSize.Level1) 230{ 231 ErrorCode result = imageEffect_->SetInputPath(g_notJpgPath); 232 ASSERT_NE(result, ErrorCode::SUCCESS); 233} 234 235/** 236 * Feature: ImageEffect 237 * Function: Test ImageEffect::SetOutputPath with normal param 238 * SubFunction: NA 239 * FunctionPoints: NA 240 * EnvConditions: NA 241 * CaseDescription: Test ImageEffect::SetOutputPath with normal param 242 */ 243HWTEST_F(TestImageEffect, SetOutputPath001, TestSize.Level1) 244{ 245 ErrorCode result = imageEffect_->SetOutputPath(g_jpgPath); 246 ASSERT_EQ(result, ErrorCode::SUCCESS); 247} 248 249/** 250 * Feature: ImageEffect 251 * Function: Test ImageEffect::SetOutputPath with nullptr param 252 * SubFunction: NA 253 * FunctionPoints: NA 254 * EnvConditions: NA 255 * CaseDescription: Test ImageEffect::SetOutputPath with nullptr param 256 */ 257HWTEST_F(TestImageEffect, SetOutputPath002, TestSize.Level1) 258{ 259 ErrorCode result = imageEffect_->SetOutputPath(nullptr); 260 ASSERT_EQ(result, ErrorCode::SUCCESS); 261} 262 263/** 264 * Feature: ImageEffect 265 * Function: Test ImageEffect::SetOutputPath with not support type param 266 * SubFunction: NA 267 * FunctionPoints: NA 268 * EnvConditions: NA 269 * CaseDescription: Test ImageEffect::SetOutputPath with not support type param 270 */ 271HWTEST_F(TestImageEffect, SetOutputPath003, TestSize.Level1) 272{ 273 ErrorCode result = imageEffect_->SetOutputPath(g_notJpgPath); 274 ASSERT_NE(result, ErrorCode::SUCCESS); 275} 276 277/** 278 * Feature: ImageEffect 279 * Function: Test ImageEffect::SetInputUri with normal param 280 * SubFunction: NA 281 * FunctionPoints: NA 282 * EnvConditions: NA 283 * CaseDescription: Test ImageEffect::SetInputUri with normal param 284 */ 285HWTEST_F(TestImageEffect, SetInputUri001, TestSize.Level1) 286{ 287 ErrorCode result = imageEffect_->SetInputUri(g_jpgUri); 288 ASSERT_EQ(result, ErrorCode::SUCCESS); 289} 290 291/** 292 * Feature: ImageEffect 293 * Function: Test ImageEffect::SetInputUri with nullptr param 294 * SubFunction: NA 295 * FunctionPoints: NA 296 * EnvConditions: NA 297 * CaseDescription: Test ImageEffect::SetInputUri with nullptr param 298 */ 299HWTEST_F(TestImageEffect, SetInputUri002, TestSize.Level1) 300{ 301 ErrorCode result = imageEffect_->SetInputUri(nullptr); 302 ASSERT_NE(result, ErrorCode::SUCCESS); 303} 304 305/** 306 * Feature: ImageEffect 307 * Function: Test ImageEffect::SetInputUri with not support type param 308 * SubFunction: NA 309 * FunctionPoints: NA 310 * EnvConditions: NA 311 * CaseDescription: Test ImageEffect::SetInputUri with not support type param 312 */ 313HWTEST_F(TestImageEffect, SetInputUri003, TestSize.Level1) 314{ 315 ErrorCode result = imageEffect_->SetInputUri(g_notJpgUri); 316 ASSERT_NE(result, ErrorCode::SUCCESS); 317} 318 319/** 320 * Feature: ImageEffect 321 * Function: Test ImageEffect::SetOutputUri with normal param 322 * SubFunction: NA 323 * FunctionPoints: NA 324 * EnvConditions: NA 325 * CaseDescription: Test ImageEffect::SetOutputUri with normal param 326 */ 327HWTEST_F(TestImageEffect, SetOutputUri001, TestSize.Level1) 328{ 329 ErrorCode result = imageEffect_->SetOutputUri(g_jpgUri); 330 ASSERT_EQ(result, ErrorCode::SUCCESS); 331} 332 333/** 334 * Feature: ImageEffect 335 * Function: Test ImageEffect::SetOutputUri with nullptr param 336 * SubFunction: NA 337 * FunctionPoints: NA 338 * EnvConditions: NA 339 * CaseDescription: Test ImageEffect::SetOutputUri with nullptr param 340 */ 341HWTEST_F(TestImageEffect, SetOutputUri002, TestSize.Level1) 342{ 343 ErrorCode result = imageEffect_->SetOutputUri(nullptr); 344 ASSERT_EQ(result, ErrorCode::SUCCESS); 345} 346 347/** 348 * Feature: ImageEffect 349 * Function: Test ImageEffect::SetOutputUri with not support type param 350 * SubFunction: NA 351 * FunctionPoints: NA 352 * EnvConditions: NA 353 * CaseDescription: Test ImageEffect::SetOutputUri with not support type param 354 */ 355HWTEST_F(TestImageEffect, SetOutputUri003, TestSize.Level1) 356{ 357 ErrorCode result = imageEffect_->SetOutputUri(g_notJpgUri); 358 ASSERT_NE(result, ErrorCode::SUCCESS); 359} 360 361HWTEST_F(TestImageEffect, Restore001, TestSize.Level1) 362{ 363 std::string info = "{\"imageEffect\":{\"filters\":[{\"name\":\"Brightness\",\"values\":{\"FilterIntensity\":" 364 "100.0}},{\"name\":\"Contrast\",\"values\":{\"FilterIntensity\":50.0}}],\"name\":\"imageEdit\"}}"; 365 std::shared_ptr<ImageEffect> imageEffect = ImageEffect::Restore(info); 366 ASSERT_NE(imageEffect, nullptr); 367 std::vector<std::shared_ptr<EFilter>> efilters = imageEffect->GetEFilters(); 368 ASSERT_EQ(efilters.size(), 2); 369 ASSERT_STREQ(efilters.at(0)->GetName().c_str(), BRIGHTNESS_EFILTER); 370 Plugin::Any value; 371 ASSERT_EQ(efilters.at(0)->GetValue(KEY_FILTER_INTENSITY, value), ErrorCode::SUCCESS); 372 auto brightnessRatio = Plugin::AnyCast<float>(&value); 373 ASSERT_NE(brightnessRatio, nullptr); 374 ASSERT_FLOAT_EQ(*brightnessRatio, 100.f); 375 376 Plugin::Any any; 377 ASSERT_STREQ(efilters.at(1)->GetName().c_str(), CONTRAST_EFILTER); 378 ASSERT_EQ(efilters.at(1)->GetValue(KEY_FILTER_INTENSITY, any), ErrorCode::SUCCESS); 379 auto contrastRatio = Plugin::AnyCast<float>(&any); 380 ASSERT_NE(contrastRatio, nullptr); 381 ASSERT_FLOAT_EQ(*contrastRatio, 50.f); 382} 383 384HWTEST_F(TestImageEffect, Restore002, TestSize.Level1) 385{ 386 std::shared_ptr<IFilterDelegate> customTestEFilter = std::make_unique<CustomTestEFilter>(); 387 auto *effectInfo = static_cast<std::shared_ptr<EffectInfo> *>(customTestEFilter->GetEffectInfo()); 388 ASSERT_NE(effectInfo, nullptr); 389 EFilterFactory::Instance()->RegisterDelegate(CUSTOM_TEST_EFILTER, customTestEFilter, *effectInfo); 390 391 std::string info = "{\"imageEffect\":{\"filters\":[{\"name\":\"CustomTestEFilter\",\"values\":{\"brightness\":" 392 "60.0}},{\"name\":\"Contrast\",\"values\":{\"FilterIntensity\":50.0}}],\"name\":\"imageEdit\"}}"; 393 394 std::shared_ptr<ImageEffect> imageEffect = ImageEffect::Restore(info); 395 ASSERT_NE(imageEffect, nullptr); 396 std::vector<std::shared_ptr<EFilter>> efilters = imageEffect->GetEFilters(); 397 ASSERT_EQ(efilters.size(), 2); 398 ASSERT_STREQ(efilters.at(0)->GetName().c_str(), "CustomTestEFilter"); 399 Plugin::Any value; 400 ASSERT_EQ(efilters.at(0)->GetValue("brightness", value), ErrorCode::SUCCESS); 401 auto brightness = Plugin::AnyCast<float>(&value); 402 ASSERT_NE(brightness, nullptr); 403 ASSERT_FLOAT_EQ(*brightness, 60.f); 404 405 ErrorCode errorCode = imageEffect->SetInputPixelMap(mockPixelMap_); 406 ASSERT_EQ(errorCode, ErrorCode::SUCCESS); 407 errorCode = imageEffect->Start(); 408 ASSERT_EQ(errorCode, ErrorCode::SUCCESS); 409} 410 411HWTEST_F(TestImageEffect, Restore003, TestSize.Level1) 412{ 413 std::string info = "{\"imageEffect\":{\"filters\":[{\"name\":\"Crop\"}],\"name\":\"imageEdit\"}}"; 414 std::shared_ptr<ImageEffect> imageEffect = ImageEffect::Restore(info); 415 ASSERT_NE(imageEffect, nullptr); 416 std::vector<std::shared_ptr<EFilter>> efilters = imageEffect->GetEFilters(); 417 ASSERT_EQ(efilters.size(), 1); 418 ASSERT_STREQ(efilters.at(0)->GetName().c_str(), CROP_EFILTER); 419} 420 421HWTEST_F(TestImageEffect, Surface001, TestSize.Level1) 422{ 423 sptr<Surface> consumerSurface = Surface::CreateSurfaceAsConsumer("UnitTest"); 424 sptr<IBufferProducer> producer = consumerSurface->GetProducer(); 425 sptr<ProducerSurface> surf = new(std::nothrow) MockProducerSurface(producer); 426 surf->Init(); 427 sptr<Surface> outputSurface = surf; 428 429 ErrorCode result = imageEffect_->SetOutputSurface(outputSurface); 430 ASSERT_EQ(result, ErrorCode::SUCCESS); 431 432 sptr<Surface> inputSurface = imageEffect_->GetInputSurface(); 433 ASSERT_NE(inputSurface, nullptr); 434 435 sptr<SurfaceBuffer> surfaceBuffer; 436 MockProducerSurface::AllocDmaMemory(surfaceBuffer); 437 OHOS::Rect damages; 438 int64_t timeStamp = 0; 439 440 // running without filter 441 imageEffect_->ConsumerBufferAvailable(surfaceBuffer, damages, timeStamp); 442 443 std::shared_ptr<EFilter> contrastEFilter = EFilterFactory::Instance()->Create(CONTRAST_EFILTER); 444 Plugin::Any value = 50.f; 445 result = contrastEFilter->SetValue(KEY_FILTER_INTENSITY, value); 446 ASSERT_EQ(result, ErrorCode::SUCCESS); 447 imageEffect_->AddEFilter(contrastEFilter); 448 449 result = imageEffect_->Start(); 450 ASSERT_EQ(result, ErrorCode::SUCCESS); 451 452 // contrast filter 453 imageEffect_->ConsumerBufferAvailable(surfaceBuffer, damages, timeStamp); 454 MockProducerSurface::ReleaseDmaBuffer(surfaceBuffer); 455} 456} // namespace Test 457} // namespace Effect 458} // namespace Media 459} // namespace OHOS