• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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