1 /*
2 * Copyright (c) 2023 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 "effect/image_filter.h"
19 #include "effect/image_filter_lazy.h"
20 #include "effect_test_utils.h"
21 #include "image/image.h"
22 #include "utils/object_helper.h"
23 #ifdef ROSEN_OHOS
24 #include <parcel.h>
25 #include <message_parcel.h>
26 #endif
27 #include "transaction/rs_marshalling_helper.h"
28 using namespace testing;
29 using namespace testing::ext;
30
31 namespace OHOS {
32 namespace Rosen {
33 namespace Drawing {
34 class ImageFilterTest : public testing::Test {
35 public:
36 static void SetUpTestCase();
37 static void TearDownTestCase();
38 void SetUp() override;
39 void TearDown() override;
40 };
41
SetUpTestCase()42 void ImageFilterTest::SetUpTestCase()
43 {
44 #ifdef ROSEN_OHOS
45 EffectTestUtils::SetupMarshallingCallbacks();
46 #endif
47 }
48
TearDownTestCase()49 void ImageFilterTest::TearDownTestCase()
50 {
51 #ifdef ROSEN_OHOS
52 EffectTestUtils::RestoreMarshallingCallbacks();
53 #endif
54 }
SetUp()55 void ImageFilterTest::SetUp() {}
TearDown()56 void ImageFilterTest::TearDown() {}
57
58 // Create a mock filter that will return null from Serialize
59 class MockImageFilter : public ImageFilter {
60 public:
MockImageFilter()61 MockImageFilter() : ImageFilter(FilterType::BLUR) {}
62
63 // Override Serialize to return null to simulate empty data scenario
Serialize() const64 std::shared_ptr<Data> Serialize() const override
65 {
66 return nullptr;
67 }
68 };
69
70 /*
71 * @tc.name: CreateBlurImageFilterTest001
72 * @tc.desc: test for creating a filter that blurs its input by the separate X and Y sinma value.
73 * @tc.type: FUNC
74 * @tc.require: I77M3W
75 */
76 HWTEST_F(ImageFilterTest, CreateBlurImageFilterTest001, TestSize.Level1)
77 {
78 auto input = ImageFilter::CreateBlurImageFilter(10.0f, 10.0f, TileMode::CLAMP, nullptr);
79 EXPECT_TRUE(input != nullptr);
80 auto imageFilter = ImageFilter::CreateBlurImageFilter(10.0f, 10.0f, TileMode::CLAMP, input);
81 EXPECT_TRUE(imageFilter != nullptr);
82 auto imageFilter1 = ImageFilter::CreateBlurImageFilter(-1.0f, -1.0f, TileMode::CLAMP, input);
83 EXPECT_TRUE(imageFilter1 != nullptr);
84 auto imageFilter2 = ImageFilter::CreateBlurImageFilter(-1.0f, 10.0f, TileMode::CLAMP, input);
85 EXPECT_TRUE(imageFilter2 != nullptr);
86 auto imageFilter3 = ImageFilter::CreateBlurImageFilter(10.0f, -1.0f, TileMode::CLAMP, input);
87 EXPECT_TRUE(imageFilter3 != nullptr);
88 }
89
90 /*
91 * @tc.name: CreateColorFilterImageFilterTest001
92 * @tc.desc: test for creating a filter that applies the color filter to the input filter results.
93 * @tc.type: FUNC
94 * @tc.require: I77M3W
95 */
96 HWTEST_F(ImageFilterTest, CreateColorFilterImageFilterTest001, TestSize.Level1)
97 {
98 auto colorFilter = ColorFilter::CreateBlendModeColorFilter(11, OHOS::Rosen::Drawing::BlendMode::CLEAR);
99 auto input = ImageFilter::CreateColorFilterImageFilter(*colorFilter, nullptr);
100 EXPECT_TRUE(input != nullptr);
101 auto imageFilter = ImageFilter::CreateColorFilterImageFilter(*colorFilter, input);
102 EXPECT_TRUE(imageFilter != nullptr);
103 }
104
105 /*
106 * @tc.name: CreateOffsetImageFilterTest001
107 * @tc.desc: test for creating a filter that offsets the input filter by the given vector.
108 * @tc.type: FUNC
109 * @tc.require: I77M3W
110 */
111 HWTEST_F(ImageFilterTest, CreateOffsetImageFilterTest001, TestSize.Level1)
112 {
113 auto input = ImageFilter::CreateOffsetImageFilter(10.0f, 10.0f, nullptr);
114 EXPECT_TRUE(input != nullptr);
115 auto imageFilter = ImageFilter::CreateOffsetImageFilter(10.0f, 10.0f, input);
116 EXPECT_TRUE(imageFilter != nullptr);
117 }
118
119 /*
120 * @tc.name: CreateArithmeticImageFilterTest001
121 * @tc.desc: test for creating a filter that implements a custom blend mode.
122 * @tc.type: FUNC
123 * @tc.require: I77M3W
124 */
125 HWTEST_F(ImageFilterTest, CreateArithmeticImageFilterTest001, TestSize.Level1)
126 {
127 std::vector<scalar> coefficients;
128 coefficients.push_back(10.0f);
129 coefficients.push_back(10.0f);
130 coefficients.push_back(10.0f);
131 coefficients.push_back(10.0f);
132 auto f1 = ImageFilter::CreateBlurImageFilter(10.0f, 10.0f, TileMode::CLAMP, nullptr);
133 auto f2 = ImageFilter::CreateOffsetImageFilter(10.0f, 10.0f, nullptr);
134 auto imageFilter = ImageFilter::CreateArithmeticImageFilter(coefficients, true, f1, f2);
135 EXPECT_TRUE(imageFilter != nullptr);
136 imageFilter = ImageFilter::CreateArithmeticImageFilter(coefficients, false, f1, f2);
137 EXPECT_TRUE(imageFilter != nullptr);
138 std::vector<scalar> coefficients1;
139 coefficients1.push_back(-1.0f);
140 coefficients1.push_back(0.0f);
141 coefficients1.push_back(10.0f);
142 coefficients1.push_back(10.0f);
143 imageFilter = ImageFilter::CreateArithmeticImageFilter(coefficients1, true, f1, f2);
144 EXPECT_TRUE(imageFilter != nullptr);
145 imageFilter = ImageFilter::CreateArithmeticImageFilter(coefficients, true, nullptr, f2);
146 EXPECT_TRUE(imageFilter != nullptr);
147 imageFilter = ImageFilter::CreateArithmeticImageFilter(coefficients, true, f1, nullptr);
148 EXPECT_TRUE(imageFilter != nullptr);
149 imageFilter = ImageFilter::CreateArithmeticImageFilter(coefficients, true, nullptr, nullptr);
150 EXPECT_TRUE(imageFilter != nullptr);
151 }
152
153 /*
154 * @tc.name: CreateComposeImageFilterTest001
155 * @tc.desc: test for creating a filter that composes f1 with f2.
156 * @tc.type: FUNC
157 * @tc.require: I77M3W
158 */
159 HWTEST_F(ImageFilterTest, CreateComposeImageFilterTest001, TestSize.Level1)
160 {
161 auto imageFilter1 = ImageFilter::CreateBlurImageFilter(10.0f, 20.0f, TileMode::CLAMP, nullptr);
162 auto imageFilter2 = ImageFilter::CreateOffsetImageFilter(30.0f, 40.0f, nullptr);
163 auto imageFilter = ImageFilter::CreateComposeImageFilter(imageFilter1, imageFilter2);
164 EXPECT_TRUE(imageFilter != nullptr);
165 }
166
167 /*
168 * @tc.name: ImageFilterCreateTest001
169 * @tc.desc: testing the ImageFilter Construction Method
170 * @tc.type: FUNC
171 * @tc.require: I77M3W
172 */
173 HWTEST_F(ImageFilterTest, ImageFilterCreateTest001, TestSize.Level1)
174 {
175 auto imageFilter = std::make_shared<ImageFilter>(ImageFilter::FilterType::BLUR, 10.0f, 10.0f, nullptr);
176 ASSERT_TRUE(imageFilter != nullptr);
177 }
178
179 /*
180 * @tc.name: ImageFilterCreateTest002
181 * @tc.desc: testing the ImageFilter Construction Method
182 * @tc.type: FUNC
183 * @tc.require: I77M3W
184 */
185 HWTEST_F(ImageFilterTest, ImageFilterCreateTest002, TestSize.Level1)
186 {
187 auto colorFilter = ColorFilter::CreateBlendModeColorFilter(11, OHOS::Rosen::Drawing::BlendMode::CLEAR);
188 auto imageFilter = std::make_shared<ImageFilter>(ImageFilter::FilterType::COLOR_FILTER, *colorFilter, nullptr);
189 ASSERT_TRUE(imageFilter != nullptr);
190 }
191
192 /*
193 * @tc.name: ImageFilterCreateTest003
194 * @tc.desc: testing the ImageFilter Construction Method
195 * @tc.type: FUNC
196 * @tc.require: I77M3W
197 */
198 HWTEST_F(ImageFilterTest, ImageFilterCreateTest003, TestSize.Level1)
199 {
200 std::vector<scalar> coefficients;
201 coefficients.push_back(10.0f);
202 coefficients.push_back(10.0f);
203 coefficients.push_back(10.0f);
204 coefficients.push_back(10.0f);
205 auto imageFilter = std::make_shared<ImageFilter>(ImageFilter::FilterType::ARITHMETIC, coefficients,
206 true, nullptr, nullptr);
207 ASSERT_TRUE(imageFilter != nullptr);
208 }
209
210 /*
211 * @tc.name: ImageFilterCreateTest004
212 * @tc.desc: testing the ImageFilter Construction Method
213 * @tc.type: FUNC
214 * @tc.require: I77M3W
215 */
216 HWTEST_F(ImageFilterTest, ImageFilterCreateTest004, TestSize.Level1)
217 {
218 auto imageFilter1 = ImageFilter::CreateBlurImageFilter(10.0f, 20.0f, TileMode::CLAMP, nullptr);
219 auto imageFilter2 = ImageFilter::CreateOffsetImageFilter(30.0f, 40.0f, nullptr);
220 auto imageFilter = std::make_shared<ImageFilter>(ImageFilter::FilterType::COMPOSE, imageFilter1, imageFilter2);
221 ASSERT_TRUE(imageFilter != nullptr);
222 }
223
224 /*
225 * @tc.name: CreateBlendImageFilterTest001
226 * @tc.desc: test for creating a filter takes an BlendMode
227 * and uses it to composite the two filters together.
228 * @tc.type: FUNC
229 * @tc.require: I77M3W
230 */
231 HWTEST_F(ImageFilterTest, CreateBlendImageFilterTest001, TestSize.Level1)
232 {
233 auto imageFilter1 = ImageFilter::CreateBlurImageFilter(10.0f, 20.0f, TileMode::CLAMP, nullptr);
234 auto imageFilter2 = ImageFilter::CreateOffsetImageFilter(30.0f, 40.0f, nullptr);
235 auto imageFilter = ImageFilter::CreateBlendImageFilter(BlendMode::CLEAR, imageFilter1, imageFilter2);
236 EXPECT_TRUE(imageFilter != nullptr);
237 }
238
239 /*
240 * @tc.name: CreateBlendImageFilterTest002
241 * @tc.desc: test for creating a filter takes an invalid BlendMode
242 * and uses it to composite the two filters together.
243 * @tc.type: FUNC
244 * @tc.require: I77M3W
245 */
246 HWTEST_F(ImageFilterTest, CreateBlendImageFilterTest002, TestSize.Level1)
247 {
248 auto imageFilter1 = ImageFilter::CreateBlurImageFilter(10.0f, 20.0f, TileMode::CLAMP, nullptr);
249 auto imageFilter2 = ImageFilter::CreateOffsetImageFilter(30.0f, 40.0f, nullptr);
250 auto imageFilter = ImageFilter::CreateBlendImageFilter(BlendMode::EXCLUSION, imageFilter1, imageFilter2);
251 EXPECT_TRUE(imageFilter != nullptr);
252 }
253
254 /*
255 * @tc.name: CreateBlendImageFilterTest003
256 * @tc.desc: test for creating a filter takes a BlendMode
257 * and uses it to composite the two filters together.
258 * @tc.type: FUNC
259 * @tc.require: I77M3W
260 */
261 HWTEST_F(ImageFilterTest, CreateBlendImageFilterTest003, TestSize.Level1)
262 {
263 auto imageFilter2 = ImageFilter::CreateOffsetImageFilter(30.0f, 40.0f, nullptr);
264 auto imageFilter = ImageFilter::CreateBlendImageFilter(BlendMode::CLEAR, nullptr, imageFilter2);
265 EXPECT_TRUE(imageFilter != nullptr);
266 }
267
268 /*
269 * @tc.name: CreateBlendImageFilterTest004
270 * @tc.desc: test for creating a filter takes a BlendMode
271 * and uses it to composite the two filters together.
272 * @tc.type: FUNC
273 * @tc.require: I77M3W
274 */
275 HWTEST_F(ImageFilterTest, CreateBlendImageFilterTest004, TestSize.Level1)
276 {
277 auto imageFilter1 = ImageFilter::CreateBlurImageFilter(10.0f, 20.0f, TileMode::CLAMP, nullptr);
278 auto imageFilter = ImageFilter::CreateBlendImageFilter(BlendMode::CLEAR, imageFilter1, nullptr);
279 EXPECT_TRUE(imageFilter != nullptr);
280 }
281
282 /*
283 * @tc.name: CreateBlendImageFilterTest005
284 * @tc.desc: test for creating a filter takes a BlendMode
285 * and uses it to composite the two filters together.
286 * @tc.type: FUNC
287 * @tc.require: I77M3W
288 */
289 HWTEST_F(ImageFilterTest, CreateBlendImageFilterTest005, TestSize.Level1)
290 {
291 auto imageFilter = ImageFilter::CreateBlendImageFilter(BlendMode::CLEAR, nullptr, nullptr);
292 EXPECT_TRUE(imageFilter != nullptr);
293 }
294
295 /*
296 * @tc.name: CreateShaderImageFilterTest001
297 * @tc.desc: test for creating a filter that fills the output with the per-pixel evaluation of the ShaderEffect.
298 * @tc.type: FUNC
299 * @tc.require: I77M3W
300 */
301 HWTEST_F(ImageFilterTest, CreateShaderImageFilterTest001, TestSize.Level1)
302 {
303 std::shared_ptr<ShaderEffect> effect = ShaderEffect::CreateColorShader(0);
304 auto imageFilter = ImageFilter::CreateShaderImageFilter(effect);
305 EXPECT_TRUE(imageFilter != nullptr);
306 }
307
308 /*
309 * @tc.name: CreateShaderImageFilterTest002
310 * @tc.desc: test for creating a filter that with invalid input.
311 * @tc.type: FUNC
312 * @tc.require: I77M3W
313 */
314 HWTEST_F(ImageFilterTest, CreateShaderImageFilterTest002, TestSize.Level1)
315 {
316 auto imageFilter = ImageFilter::CreateShaderImageFilter(nullptr);
317 EXPECT_TRUE(imageFilter != nullptr);
318 }
319
320 /*
321 * @tc.name: CreateShaderImageFilterTest003
322 * @tc.desc: test for creating a filter that with invalid input.
323 * @tc.type: FUNC
324 * @tc.require: I77M3W
325 */
326 HWTEST_F(ImageFilterTest, CreateShaderImageFilterTest003, TestSize.Level1)
327 {
328 std::shared_ptr<ShaderEffect> effect = ShaderEffect::CreateColorShader(0);
329 Rect rect {0, 0, 100.0f, 100.0f};
330 auto imageFilter = ImageFilter::CreateShaderImageFilter(effect, rect);
331 EXPECT_TRUE(imageFilter != nullptr);
332 }
333
334 /*
335 * @tc.name: CreateImageImageFilterTest001
336 * @tc.desc: test for creating a filter that with image.
337 * @tc.type: FUNC
338 * @tc.require: I77M3W
339 */
340 HWTEST_F(ImageFilterTest, CreateImageImageFilterTest001, TestSize.Level1)
341 {
342 std::shared_ptr<Image> image = std::make_shared<Image>();
343 Rect rect {0, 0, 100.0f, 100.0f};
344 Rect rect2 {0, 0, 10.0f, 10.0f};
345 SamplingOptions options;
346 auto imageFilter = ImageFilter::CreateImageImageFilter(image, rect, rect2, options);
347 EXPECT_TRUE(imageFilter != nullptr);
348 auto imageFilter2 = ImageFilter::CreateImageImageFilter(nullptr, rect, rect2, options);
349 EXPECT_TRUE(imageFilter2 != nullptr);
350 }
351
352 /*
353 * @tc.name: CreateHDSampleImageFilterTest001
354 * @tc.desc: test for creating HDSampleImageFilter.
355 * @tc.type: FUNC
356 * @tc.require:ICR1ZE
357 */
358 HWTEST_F(ImageFilterTest, CreateHDSampleImageFilterTest001, TestSize.Level1)
359 {
360 std::shared_ptr<Image> image = std::make_shared<Image>();
361 Rect srcRect {0, 0, 100.0f, 100.0f};
362 Rect dstRect {0, 0, 10.0f, 10.0f};
363 HDSampleInfo info;
364 auto imageFilter = ImageFilter::CreateHDSampleImageFilter(image, srcRect, dstRect, info);
365 EXPECT_TRUE(imageFilter != nullptr);
366
367 auto imageFilter1 = ImageFilter::CreateHDSampleImageFilter(nullptr, srcRect, dstRect, info);
368 EXPECT_TRUE(imageFilter1 == nullptr);
369
370 Rect srcRect1 {100.0f, 100.0f, 100.0f, 100.0f};
371 auto imageFilter2 = ImageFilter::CreateHDSampleImageFilter(image, srcRect1, dstRect, info);
372 EXPECT_TRUE(imageFilter2 == nullptr);
373
374 Rect dstRect1 {10.0f, 10.0f, 10.0f, 10.0f};
375 auto imageFilter3 = ImageFilter::CreateHDSampleImageFilter(image, srcRect, dstRect1, info);
376 EXPECT_TRUE(imageFilter3 == nullptr);
377 }
378
379 #ifdef ROSEN_OHOS
380 /*
381 * @tc.name: UnmarshallingCompleteRoundTrip001
382 * @tc.desc: Test complete round-trip marshalling and serialization data consistency
383 * @tc.type: FUNC
384 * @tc.require: AR000GGNV3
385 * @tc.author:
386 */
387 HWTEST_F(ImageFilterTest, UnmarshallingCompleteRoundTrip001, TestSize.Level1)
388 {
389 // Test 1: Complete round-trip with multiple filter types
390 std::vector<std::shared_ptr<ImageFilter>> testFilters;
391 Rect cropRect(0.0f, 0.0f, 100.0f, 100.0f);
392 // BlurFilter
393 testFilters.push_back(ImageFilter::CreateBlurImageFilter(3.0f, 3.0f, TileMode::CLAMP, nullptr,
394 ImageBlurType::GAUSS, cropRect));
395 // OffsetFilter
396 testFilters.push_back(ImageFilter::CreateOffsetImageFilter(5.0f, 10.0f, nullptr, cropRect));
397
398 // ColorFilterImageFilter
399 auto colorFilter = ColorFilter::CreateBlendModeColorFilter(0xFFFF0000, BlendMode::MULTIPLY);
400 if (colorFilter) {
401 testFilters.push_back(ImageFilter::CreateColorFilterImageFilter(*colorFilter, nullptr, cropRect));
402 }
403
404 for (auto& originalFilter : testFilters) {
405 ASSERT_NE(originalFilter, nullptr);
406 auto originalType = originalFilter->GetType();
407
408 // Marshal and unmarshal
409 Parcel parcel;
410 bool marshalResult = originalFilter->Marshalling(parcel);
411 EXPECT_TRUE(marshalResult);
412
413 bool isValid = true;
414 auto unmarshaledFilter = ImageFilter::Unmarshalling(parcel, isValid);
415 EXPECT_NE(unmarshaledFilter, nullptr);
416 EXPECT_TRUE(isValid);
417 EXPECT_EQ(unmarshaledFilter->GetType(), originalType);
418
419 // Verify data serialization consistency
420 auto originalData = originalFilter->Serialize();
421 auto unmarshaledData = unmarshaledFilter->Serialize();
422 if (originalData && unmarshaledData) {
423 EXPECT_EQ(originalData->GetSize(), unmarshaledData->GetSize());
424 const uint8_t* originalBytes = static_cast<const uint8_t*>(originalData->GetData());
425 const uint8_t* unmarshaledBytes = static_cast<const uint8_t*>(unmarshaledData->GetData());
426 int memResult = memcmp(originalBytes, unmarshaledBytes, originalData->GetSize());
427 EXPECT_EQ(memResult, 0);
428 } else {
429 // If either serialization fails, both should fail consistently
430 EXPECT_EQ(originalData, unmarshaledData);
431 }
432 }
433 }
434
435 /*
436 * @tc.name: UnmarshallingErrorHandling001
437 * @tc.desc: Test ImageFilter::Unmarshalling error handling scenarios and boundary conditions
438 * @tc.type: FUNC
439 * @tc.require: AR000GGNV3
440 * @tc.author:
441 */
442 HWTEST_F(ImageFilterTest, UnmarshallingErrorHandling001, TestSize.Level1)
443 {
444 // Test 1: Empty parcel
445 {
446 Parcel emptyParcel;
447 bool isValid = true;
448 auto result = ImageFilter::Unmarshalling(emptyParcel, isValid);
449 EXPECT_EQ(result, nullptr);
450 }
451
452 // Test 2: NO_TYPE - 1 (negative boundary)
453 {
454 Parcel parcel;
455 parcel.WriteInt32(static_cast<int32_t>(ImageFilter::FilterType::NO_TYPE) - 1);
456 bool isValid = true;
457 auto result = ImageFilter::Unmarshalling(parcel, isValid);
458 EXPECT_EQ(result, nullptr); // Should be rejected due to invalid type
459 }
460
461 // Test 3: NO_TYPE (lower boundary) - can construct empty ImageFilter
462 {
463 Parcel parcel;
464 parcel.WriteInt32(static_cast<int32_t>(ImageFilter::FilterType::NO_TYPE));
465 parcel.WriteInt32(false);
466 bool isValid = true;
467 auto result = ImageFilter::Unmarshalling(parcel, isValid);
468 EXPECT_NE(result, nullptr); // Should succeed, creating empty ImageFilter
469 EXPECT_TRUE(isValid);
470 if (result) {
471 EXPECT_EQ(result->GetType(), ImageFilter::FilterType::NO_TYPE);
472 }
473 }
474
475 // Test 4: LAZY_IMAGE_FILTER (should be rejected in normal ImageFilter unmarshalling)
476 {
477 Parcel parcel;
478 parcel.WriteInt32(static_cast<int32_t>(ImageFilter::FilterType::LAZY_IMAGE_FILTER));
479 bool isValid = true;
480 auto result = ImageFilter::Unmarshalling(parcel, isValid);
481 EXPECT_EQ(result, nullptr); // Should be rejected
482 }
483
484 // Test 5: Beyond LAZY_IMAGE_FILTER (upper boundary + 1)
485 {
486 Parcel parcel;
487 parcel.WriteInt32(static_cast<int32_t>(ImageFilter::FilterType::LAZY_IMAGE_FILTER) + 1);
488 bool isValid = true;
489 auto result = ImageFilter::Unmarshalling(parcel, isValid);
490 EXPECT_EQ(result, nullptr); // Should be rejected due to invalid type
491 }
492
493 // Test 6: Large invalid value
494 {
495 Parcel parcel;
496 parcel.WriteInt32(999);
497 bool isValid = true;
498 auto result = ImageFilter::Unmarshalling(parcel, isValid);
499 EXPECT_EQ(result, nullptr); // Should be rejected
500 }
501 }
502
503 /*
504 * @tc.name: MarshallingEmptyData001
505 * @tc.desc: Test ImageFilter::Marshalling with empty Serialize data
506 * @tc.type: FUNC
507 * @tc.require: AR000GGNV3
508 */
509 HWTEST_F(ImageFilterTest, MarshallingEmptyData001, TestSize.Level1)
510 {
511 auto mockFilter = std::make_shared<MockImageFilter>();
512 Parcel parcel;
513 // Should succeed even with null Serialize data
514 bool result = mockFilter->Marshalling(parcel);
515 EXPECT_TRUE(result);
516
517 // Verify the parcel contains the expected structure
518 // Read type
519 int32_t type;
520 EXPECT_TRUE(parcel.ReadInt32(type));
521 EXPECT_EQ(type, static_cast<int32_t>(ImageFilter::FilterType::BLUR));
522
523 // Read hasData flag - should be false
524 bool hasData;
525 EXPECT_TRUE(parcel.ReadBool(hasData));
526 EXPECT_FALSE(hasData);
527
528 // No more data should be available since hasData was false
529 EXPECT_EQ(parcel.GetDataSize() - parcel.GetReadPosition(), 0);
530 }
531
532 /*
533 * @tc.name: UnmarshallingEmptyData001
534 * @tc.desc: Test ImageFilter::Unmarshalling with empty data marker
535 * @tc.type: FUNC
536 * @tc.require: AR000GGNV3
537 */
538 HWTEST_F(ImageFilterTest, UnmarshallingEmptyData001, TestSize.Level1)
539 {
540 Parcel parcel;
541 // Write type
542 EXPECT_TRUE(parcel.WriteInt32(static_cast<int32_t>(ImageFilter::FilterType::BLUR)));
543 // Write hasData as false to simulate empty data scenario
544 EXPECT_TRUE(parcel.WriteBool(false));
545
546 // Should successfully create empty filter
547 bool isValid = true;
548 auto filter = ImageFilter::Unmarshalling(parcel, isValid);
549 EXPECT_NE(filter, nullptr);
550 EXPECT_TRUE(isValid);
551 EXPECT_EQ(filter->GetType(), ImageFilter::FilterType::BLUR);
552 }
553
554 /*
555 * @tc.name: MarshallingUnmarshallingEmptyData001
556 * @tc.desc: Test round-trip Marshalling and Unmarshalling with empty data
557 * @tc.type: FUNC
558 * @tc.require: AR000GGNV3
559 */
560 HWTEST_F(ImageFilterTest, MarshallingUnmarshallingEmptyData001, TestSize.Level1)
561 {
562 auto originalFilter = std::make_shared<MockImageFilter>();
563 Parcel parcel;
564 // Marshal - should succeed with empty data
565 bool marshalResult = originalFilter->Marshalling(parcel);
566 EXPECT_TRUE(marshalResult);
567
568 // Unmarshal - should create empty filter with correct type
569 bool isValid = true;
570 auto unmarshaledFilter = ImageFilter::Unmarshalling(parcel, isValid);
571 EXPECT_NE(unmarshaledFilter, nullptr);
572 EXPECT_TRUE(isValid);
573 EXPECT_EQ(unmarshaledFilter->GetType(), ImageFilter::FilterType::BLUR);
574
575 // Serialize validation - both should return null consistently
576 auto originalData = originalFilter->Serialize();
577 auto unmarshaledData = unmarshaledFilter->Serialize();
578 EXPECT_EQ(originalData, nullptr);
579 EXPECT_EQ(unmarshaledData, nullptr);
580 }
581
582 /*
583 * @tc.name: MarshallingCallbackFailure001
584 * @tc.desc: Test ImageFilter::Marshalling with callback failure to cover (!callback(parcel, data)) branch
585 * @tc.type: FUNC
586 * @tc.require: AR000GGNV3
587 */
588 HWTEST_F(ImageFilterTest, MarshallingCallbackFailure001, TestSize.Level1)
589 {
590 // Create a valid filter with non-null Serialize data
591 Rect cropRect(0.0f, 0.0f, 100.0f, 100.0f);
592 auto filter = ImageFilter::CreateBlurImageFilter(5.0f, 5.0f, TileMode::CLAMP, nullptr,
593 ImageBlurType::GAUSS, cropRect);
594 ASSERT_NE(filter, nullptr);
595
596 // Backup original callback
597 auto originalCallback = ObjectHelper::Instance().GetDataMarshallingCallback();
598
599 // Set a failing callback to trigger the (!callback(parcel, data)) branch
600 ObjectHelper::Instance().SetDataMarshallingCallback(
__anonfae4c69d0102(Parcel& parcel, std::shared_ptr<Drawing::Data> data) 601 [](Parcel& parcel, std::shared_ptr<Drawing::Data> data) -> bool {
602 return false; // Always fail
603 }
604 );
605
606 Parcel parcel;
607 bool result = filter->Marshalling(parcel);
608 // Should fail due to callback failure
609 EXPECT_FALSE(result);
610
611 // Restore original callback
612 ObjectHelper::Instance().SetDataMarshallingCallback(originalCallback);
613 }
614
615 /*
616 * @tc.name: UnmarshallingCallbackNull001
617 * @tc.desc: Test ImageFilter::Unmarshalling with null callback to cover (if (!callback)) branch
618 * @tc.type: FUNC
619 * @tc.require: AR000GGNV3
620 */
621 HWTEST_F(ImageFilterTest, UnmarshallingCallbackNull001, TestSize.Level1)
622 {
623 // Backup original callback
624 auto originalCallback = ObjectHelper::Instance().GetDataUnmarshallingCallback();
625
626 // Set null callback to trigger the (if (!callback)) branch
627 ObjectHelper::Instance().SetDataUnmarshallingCallback(nullptr);
628
629 Parcel parcel;
630 // Write valid type
631 EXPECT_TRUE(parcel.WriteInt32(static_cast<int32_t>(ImageFilter::FilterType::BLUR)));
632 // Write hasData as true to reach the callback check
633 EXPECT_TRUE(parcel.WriteBool(true));
634
635 bool isValid = true;
636 auto result = ImageFilter::Unmarshalling(parcel, isValid);
637 // Should fail due to null callback
638 EXPECT_EQ(result, nullptr);
639
640 // Restore original callback
641 ObjectHelper::Instance().SetDataUnmarshallingCallback(originalCallback);
642 }
643
644 /*
645 * @tc.name: CreateBlurImageFilterLazyInput001
646 * @tc.desc: Test ImageFilter::CreateBlurImageFilter with lazy input
647 * @tc.type: FUNC
648 * @tc.require: AR000GGNV3
649 */
650 HWTEST_F(ImageFilterTest, CreateBlurImageFilterLazyInput001, TestSize.Level1)
651 {
652 // Create a lazy filter as input
653 auto lazyFilter = ImageFilterLazy::CreateBlur(2.0f, 3.0f, TileMode::CLAMP);
654 ASSERT_NE(lazyFilter, nullptr);
655 EXPECT_TRUE(lazyFilter->IsLazy());
656
657 // CreateBlurImageFilter should return nullptr with lazy input
658 auto result = ImageFilter::CreateBlurImageFilter(1.0f, 1.0f, TileMode::CLAMP, lazyFilter);
659 EXPECT_EQ(result, nullptr);
660 }
661
662 /*
663 * @tc.name: CreateColorFilterImageFilterLazyInput001
664 * @tc.desc: Test ImageFilter::CreateColorFilterImageFilter with lazy input
665 * @tc.type: FUNC
666 * @tc.require: AR000GGNV3
667 */
668 HWTEST_F(ImageFilterTest, CreateColorFilterImageFilterLazyInput001, TestSize.Level1)
669 {
670 // Create a lazy filter as input
671 auto lazyFilter = ImageFilterLazy::CreateOffset(5.0f, 5.0f);
672 ASSERT_NE(lazyFilter, nullptr);
673 EXPECT_TRUE(lazyFilter->IsLazy());
674
675 // Create a color filter
676 auto colorFilter = ColorFilter::CreateLinearToSrgbGamma();
677 ASSERT_NE(colorFilter, nullptr);
678
679 // CreateColorFilterImageFilter should return nullptr with lazy input
680 auto result = ImageFilter::CreateColorFilterImageFilter(*colorFilter, lazyFilter);
681 EXPECT_EQ(result, nullptr);
682 }
683
684 /*
685 * @tc.name: CreateOffsetImageFilterLazyInput001
686 * @tc.desc: Test ImageFilter::CreateOffsetImageFilter with lazy input
687 * @tc.type: FUNC
688 * @tc.require: AR000GGNV3
689 */
690 HWTEST_F(ImageFilterTest, CreateOffsetImageFilterLazyInput001, TestSize.Level1)
691 {
692 // Create a lazy filter as input
693 auto lazyFilter = ImageFilterLazy::CreateBlur(3.0f, 3.0f, TileMode::CLAMP);
694 ASSERT_NE(lazyFilter, nullptr);
695 EXPECT_TRUE(lazyFilter->IsLazy());
696
697 // CreateOffsetImageFilter should return nullptr with lazy input
698 auto result = ImageFilter::CreateOffsetImageFilter(10.0f, 10.0f, lazyFilter);
699 EXPECT_EQ(result, nullptr);
700 }
701
702 /*
703 * @tc.name: CreateGradientBlurImageFilterLazyInput001
704 * @tc.desc: Test ImageFilter::CreateGradientBlurImageFilter with lazy input
705 * @tc.type: FUNC
706 * @tc.require: AR000GGNV3
707 */
708 HWTEST_F(ImageFilterTest, CreateGradientBlurImageFilterLazyInput001, TestSize.Level1)
709 {
710 // Create a lazy filter as input
711 auto lazyFilter = ImageFilterLazy::CreateOffset(2.0f, 2.0f);
712 ASSERT_NE(lazyFilter, nullptr);
713 EXPECT_TRUE(lazyFilter->IsLazy());
714
715 // CreateGradientBlurImageFilter should return nullptr with lazy input
716 std::vector<std::pair<float, float>> fractionStops = {{0.0f, 0.5f}, {1.0f, 1.0f}};
717 auto result = ImageFilter::CreateGradientBlurImageFilter(5.0f, fractionStops,
718 GradientDir::LEFT, GradientBlurType::ALPHA_BLEND, lazyFilter);
719 EXPECT_EQ(result, nullptr);
720 }
721
722 /*
723 * @tc.name: CreateArithmeticImageFilterLazyInput001
724 * @tc.desc: Test ImageFilter::CreateArithmeticImageFilter with lazy inputs
725 * @tc.type: FUNC
726 * @tc.require: AR000GGNV3
727 */
728 HWTEST_F(ImageFilterTest, CreateArithmeticImageFilterLazyInput001, TestSize.Level1)
729 {
730 // Create lazy filters as inputs
731 auto lazyBackground = ImageFilterLazy::CreateBlur(1.0f, 1.0f, TileMode::CLAMP);
732 auto lazyForeground = ImageFilterLazy::CreateOffset(2.0f, 2.0f);
733 ASSERT_NE(lazyBackground, nullptr);
734 ASSERT_NE(lazyForeground, nullptr);
735 EXPECT_TRUE(lazyBackground->IsLazy());
736 EXPECT_TRUE(lazyForeground->IsLazy());
737
738 // CreateArithmeticImageFilter should return nullptr with lazy background
739 std::vector<scalar> coefficients = {1.0f, 0.0f, 0.0f, 0.0f};
740 auto result1 = ImageFilter::CreateArithmeticImageFilter(coefficients, true, lazyBackground, nullptr);
741 EXPECT_EQ(result1, nullptr);
742
743 // CreateArithmeticImageFilter should return nullptr with lazy foreground
744 auto result2 = ImageFilter::CreateArithmeticImageFilter(coefficients, true, nullptr, lazyForeground);
745 EXPECT_EQ(result2, nullptr);
746 }
747
748 /*
749 * @tc.name: CreateComposeImageFilterLazyInput001
750 * @tc.desc: Test ImageFilter::CreateComposeImageFilter with lazy inputs
751 * @tc.type: FUNC
752 * @tc.require: AR000GGNV3
753 */
754 HWTEST_F(ImageFilterTest, CreateComposeImageFilterLazyInput001, TestSize.Level1)
755 {
756 // Create lazy filters as inputs
757 auto lazyFilter1 = ImageFilterLazy::CreateBlur(2.0f, 2.0f, TileMode::CLAMP);
758 auto lazyFilter2 = ImageFilterLazy::CreateOffset(3.0f, 3.0f);
759 ASSERT_NE(lazyFilter1, nullptr);
760 ASSERT_NE(lazyFilter2, nullptr);
761 EXPECT_TRUE(lazyFilter1->IsLazy());
762 EXPECT_TRUE(lazyFilter2->IsLazy());
763
764 // CreateComposeImageFilter should return nullptr with lazy f1
765 auto result1 = ImageFilter::CreateComposeImageFilter(lazyFilter1, nullptr);
766 EXPECT_EQ(result1, nullptr);
767
768 // CreateComposeImageFilter should return nullptr with lazy f2
769 auto result2 = ImageFilter::CreateComposeImageFilter(nullptr, lazyFilter2);
770 EXPECT_EQ(result2, nullptr);
771
772 // CreateComposeImageFilter should return nullptr with both lazy filters
773 auto result3 = ImageFilter::CreateComposeImageFilter(lazyFilter1, lazyFilter2);
774 EXPECT_EQ(result3, nullptr);
775 }
776
777 /*
778 * @tc.name: CreateBlendImageFilterLazyInput001
779 * @tc.desc: Test ImageFilter::CreateBlendImageFilter with lazy inputs
780 * @tc.type: FUNC
781 * @tc.require: AR000GGNV3
782 */
783 HWTEST_F(ImageFilterTest, CreateBlendImageFilterLazyInput001, TestSize.Level1)
784 {
785 // Create lazy filters as inputs
786 auto lazyBackground = ImageFilterLazy::CreateOffset(1.0f, 2.0f);
787 auto lazyForeground = ImageFilterLazy::CreateBlur(3.0f, 4.0f, TileMode::CLAMP);
788 ASSERT_NE(lazyBackground, nullptr);
789 ASSERT_NE(lazyForeground, nullptr);
790 EXPECT_TRUE(lazyBackground->IsLazy());
791 EXPECT_TRUE(lazyForeground->IsLazy());
792
793 // CreateBlendImageFilter should return nullptr with lazy background
794 auto result1 = ImageFilter::CreateBlendImageFilter(BlendMode::SRC_OVER, lazyBackground, nullptr);
795 EXPECT_EQ(result1, nullptr);
796
797 // CreateBlendImageFilter should return nullptr with lazy foreground
798 auto result2 = ImageFilter::CreateBlendImageFilter(BlendMode::SRC_OVER, nullptr, lazyForeground);
799 EXPECT_EQ(result2, nullptr);
800
801 // CreateBlendImageFilter should return nullptr with both lazy filters
802 auto result3 = ImageFilter::CreateBlendImageFilter(BlendMode::SRC_OVER, lazyBackground, lazyForeground);
803 EXPECT_EQ(result3, nullptr);
804 }
805
806 /*
807 * @tc.name: MarshallingWriteTypeFailure001
808 * @tc.desc: Test ImageFilter::Marshalling with WriteInt32(type) failure
809 * @tc.type: FUNC
810 * @tc.require: AR000GGNV3
811 */
812 HWTEST_F(ImageFilterTest, MarshallingWriteTypeFailure001, TestSize.Level1)
813 {
814 // Create a valid filter
815 Rect cropRect(0.0f, 0.0f, 100.0f, 100.0f);
816 auto filter = ImageFilter::CreateBlurImageFilter(2.0f, 2.0f, TileMode::CLAMP, nullptr,
817 ImageBlurType::GAUSS, cropRect);
818 ASSERT_NE(filter, nullptr);
819
820 // Create buffer to fill parcel capacity (200K minimum)
821 const size_t BUFFER_SIZE = 200 * 1024; // 200K
822 std::vector<uint8_t> fillBuffer(BUFFER_SIZE, 0xFF);
823
824 // Fill parcel completely, then try Marshalling (should fail on WriteInt32(type))
825 Parcel parcel;
826 parcel.SetMaxCapacity(BUFFER_SIZE);
827 bool fillResult = parcel.WriteBuffer(fillBuffer.data(), BUFFER_SIZE);
828 EXPECT_TRUE(fillResult);
829
830 bool result = filter->Marshalling(parcel);
831 EXPECT_FALSE(result); // Should fail due to WriteInt32 failure
832 }
833
834 /*
835 * @tc.name: MarshallingWriteHasDataFailure001
836 * @tc.desc: Test ImageFilter::Marshalling with WriteBool(hasValidData) failure
837 * @tc.type: FUNC
838 * @tc.require: AR000GGNV3
839 */
840 HWTEST_F(ImageFilterTest, MarshallingWriteHasDataFailure001, TestSize.Level1)
841 {
842 // Create a valid filter
843 Rect cropRect(0.0f, 0.0f, 100.0f, 100.0f);
844 auto filter = ImageFilter::CreateBlurImageFilter(2.0f, 2.0f, TileMode::CLAMP, nullptr,
845 ImageBlurType::GAUSS, cropRect);
846 ASSERT_NE(filter, nullptr);
847
848 // Create buffer to fill parcel capacity (200K minimum)
849 const size_t BUFFER_SIZE = 200 * 1024; // 200K
850 std::vector<uint8_t> fillBuffer(BUFFER_SIZE, 0xFF);
851
852 // Fill parcel leaving space for int32 only (4 bytes), should fail on WriteBool
853 Parcel parcel;
854 parcel.SetMaxCapacity(BUFFER_SIZE);
855 bool fillResult = parcel.WriteBuffer(fillBuffer.data(), BUFFER_SIZE - 4);
856 EXPECT_TRUE(fillResult);
857
858 bool result = filter->Marshalling(parcel);
859 EXPECT_FALSE(result); // Should fail due to WriteBool failure
860 }
861
862 /*
863 * @tc.name: MarshallingCallbackNull001
864 * @tc.desc: Test ImageFilter::Marshalling with null DataMarshallingCallback
865 * @tc.type: FUNC
866 * @tc.require: AR000GGNV3
867 */
868 HWTEST_F(ImageFilterTest, MarshallingCallbackNull001, TestSize.Level1)
869 {
870 // Create a valid filter
871 Rect cropRect(0.0f, 0.0f, 100.0f, 100.0f);
872 auto filter = ImageFilter::CreateBlurImageFilter(2.0f, 2.0f, TileMode::CLAMP, nullptr,
873 ImageBlurType::GAUSS, cropRect);
874 ASSERT_NE(filter, nullptr);
875
876 // Backup original callback
877 auto originalCallback = ObjectHelper::Instance().GetDataMarshallingCallback();
878
879 // Set null callback to trigger the (if (!callback)) branch
880 ObjectHelper::Instance().SetDataMarshallingCallback(nullptr);
881
882 Parcel parcel;
883 bool result = filter->Marshalling(parcel);
884 EXPECT_FALSE(result); // Should fail due to null callback
885
886 // Restore original callback
887 ObjectHelper::Instance().SetDataMarshallingCallback(originalCallback);
888 }
889
890 /*
891 * @tc.name: UnmarshallingReadHasDataFailure001
892 * @tc.desc: Test ImageFilter::Unmarshalling with ReadBool(hasData) failure
893 * @tc.type: FUNC
894 * @tc.require: AR000GGNV3
895 */
896 HWTEST_F(ImageFilterTest, UnmarshallingReadHasDataFailure001, TestSize.Level1)
897 {
898 Parcel parcel;
899 // Write valid type
900 EXPECT_TRUE(parcel.WriteInt32(static_cast<int32_t>(ImageFilter::FilterType::BLUR)));
901 // Don't write hasData bool, leaving parcel incomplete
902
903 bool isValid = true;
904 auto result = ImageFilter::Unmarshalling(parcel, isValid);
905 EXPECT_EQ(result, nullptr); // Should fail due to ReadBool failure
906 }
907
908 /*
909 * @tc.name: UnmarshallingCallbackReturnNull001
910 * @tc.desc: Test ImageFilter::Unmarshalling with callback returning null data
911 * @tc.type: FUNC
912 * @tc.require: AR000GGNV3
913 */
914 HWTEST_F(ImageFilterTest, UnmarshallingCallbackReturnNull001, TestSize.Level1)
915 {
916 // Backup original callback
917 auto originalCallback = ObjectHelper::Instance().GetDataUnmarshallingCallback();
918
919 // Set callback that returns null data to trigger the (if (!data)) branch
920 ObjectHelper::Instance().SetDataUnmarshallingCallback(
__anonfae4c69d0202(Parcel& parcel) 921 [](Parcel& parcel) -> std::shared_ptr<Drawing::Data> {
922 return nullptr; // Always return null
923 }
924 );
925
926 Parcel parcel;
927 // Write valid type
928 EXPECT_TRUE(parcel.WriteInt32(static_cast<int32_t>(ImageFilter::FilterType::BLUR)));
929 // Write hasData as true to reach the callback
930 EXPECT_TRUE(parcel.WriteBool(true));
931
932 bool isValid = true;
933 auto result = ImageFilter::Unmarshalling(parcel, isValid);
934 EXPECT_EQ(result, nullptr); // Should fail due to null data from callback
935
936 // Restore original callback
937 ObjectHelper::Instance().SetDataUnmarshallingCallback(originalCallback);
938 }
939 #endif
940
941 } // namespace Drawing
942 } // namespace Rosen
943 } // namespace OHOS
944