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
28 using namespace testing::ext;
29 using namespace OHOS::Media::Effect;
30
31 static std::string g_jpgPath;
32 static std::string g_notJpgPath;
33 static std::string g_jpgUri;
34 static std::string g_notJpgUri;
35
36 namespace OHOS {
37 namespace Media {
38 namespace Effect {
39 namespace Test {
40 class CustomTestEFilter : public IFilterDelegate {
41 public:
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 }
81 private:
82 static std::shared_ptr<EffectInfo> info_;
83 std::shared_ptr<EFilter> filter_;
84 };
85 std::shared_ptr<EffectInfo> CustomTestEFilter::info_ = nullptr;
86
87 class TestImageEffect : public testing::Test {
88 public:
89 TestImageEffect() = default;
90
91 ~TestImageEffect() override = default;
92
SetUpTestCase()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
TearDownTestCase()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
HWTEST_F(TestImageEffect, AddEfilter001, TestSize.Level1)125 HWTEST_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
HWTEST_F(TestImageEffect, Start001, TestSize.Level1)147 HWTEST_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
HWTEST_F(TestImageEffect, InsertEfilter001, TestSize.Level1)163 HWTEST_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
HWTEST_F(TestImageEffect, InsertEfilter002, TestSize.Level1)185 HWTEST_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 */
HWTEST_F(TestImageEffect, SetInputPath001, TestSize.Level1)201 HWTEST_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 */
HWTEST_F(TestImageEffect, SetInputPath002, TestSize.Level1)215 HWTEST_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 */
HWTEST_F(TestImageEffect, SetInputPath003, TestSize.Level1)229 HWTEST_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 */
HWTEST_F(TestImageEffect, SetOutputPath001, TestSize.Level1)243 HWTEST_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 */
HWTEST_F(TestImageEffect, SetOutputPath002, TestSize.Level1)257 HWTEST_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 */
HWTEST_F(TestImageEffect, SetOutputPath003, TestSize.Level1)271 HWTEST_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 */
HWTEST_F(TestImageEffect, SetInputUri001, TestSize.Level1)285 HWTEST_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 */
HWTEST_F(TestImageEffect, SetInputUri002, TestSize.Level1)299 HWTEST_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 */
HWTEST_F(TestImageEffect, SetInputUri003, TestSize.Level1)313 HWTEST_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 */
HWTEST_F(TestImageEffect, SetOutputUri001, TestSize.Level1)327 HWTEST_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 */
HWTEST_F(TestImageEffect, SetOutputUri002, TestSize.Level1)341 HWTEST_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 */
HWTEST_F(TestImageEffect, SetOutputUri003, TestSize.Level1)355 HWTEST_F(TestImageEffect, SetOutputUri003, TestSize.Level1)
356 {
357 ErrorCode result = imageEffect_->SetOutputUri(g_notJpgUri);
358 ASSERT_NE(result, ErrorCode::SUCCESS);
359 }
360
HWTEST_F(TestImageEffect, Restore001, TestSize.Level1)361 HWTEST_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
HWTEST_F(TestImageEffect, Restore002, TestSize.Level1)384 HWTEST_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
HWTEST_F(TestImageEffect, Restore003, TestSize.Level1)411 HWTEST_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
HWTEST_F(TestImageEffect, Surface001, TestSize.Level1)421 HWTEST_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