• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 "effect/image_filter.h"
17 
18 #include "impl_factory.h"
19 
20 #include "impl_interface/image_filter_impl.h"
21 #include "utils/log.h"
22 
23 #ifdef ROSEN_OHOS
24 #include "utils/object_helper.h"
25 #endif
26 
27 namespace OHOS {
28 namespace Rosen {
29 namespace Drawing {
ImageFilter(FilterType t,scalar x,scalar y,std::shared_ptr<ImageFilter> input,const Rect & cropRect)30 ImageFilter::ImageFilter(FilterType t, scalar x, scalar y,
31     std::shared_ptr<ImageFilter> input, const Rect& cropRect) noexcept : ImageFilter()
32 {
33     type_ = t;
34     impl_->InitWithOffset(x, y, input, cropRect);
35 }
36 
ImageFilter(FilterType t,scalar x,scalar y,TileMode mode,std::shared_ptr<ImageFilter> input,ImageBlurType blurType,const Rect & cropRect)37 ImageFilter::ImageFilter(FilterType t, scalar x, scalar y, TileMode mode, std::shared_ptr<ImageFilter> input,
38     ImageBlurType blurType, const Rect& cropRect) noexcept
39     : ImageFilter()
40 {
41     type_ = t;
42     impl_->InitWithBlur(x, y, mode, input, blurType, cropRect);
43 }
44 
ImageFilter(FilterType t,const ColorFilter & cf,std::shared_ptr<ImageFilter> input,const Rect & cropRect)45 ImageFilter::ImageFilter(FilterType t, const ColorFilter& cf,
46     std::shared_ptr<ImageFilter> input, const Rect& cropRect) noexcept
47     : ImageFilter()
48 {
49     type_ = t;
50     impl_->InitWithColor(cf, input, cropRect);
51 }
52 
ImageFilter(FilterType t,const ColorFilter & cf,scalar x,scalar y,ImageBlurType blurType,const Rect & cropRect)53 ImageFilter::ImageFilter(FilterType t, const ColorFilter& cf, scalar x, scalar y,
54     ImageBlurType blurType, const Rect& cropRect) noexcept
55     : ImageFilter()
56 {
57     type_ = t;
58     impl_->InitWithColorBlur(cf, x, y, blurType, cropRect);
59 }
60 
InitWithColorBlur(const ColorFilter & cf,scalar x,scalar y,ImageBlurType blurType,const Rect & cropRect)61 void ImageFilter::InitWithColorBlur(const ColorFilter& cf, scalar x, scalar y,
62     ImageBlurType blurType, const Rect& cropRect)
63 {
64     type_ = ImageFilter::FilterType::COLOR_FILTER;
65     impl_->InitWithColorBlur(cf, x, y, blurType, cropRect);
66 }
67 
ImageFilter(FilterType t,const std::vector<scalar> & coefficients,bool enforcePMColor,std::shared_ptr<ImageFilter> background,std::shared_ptr<ImageFilter> foreground,const Rect & cropRect)68 ImageFilter::ImageFilter(FilterType t, const std::vector<scalar>& coefficients, bool enforcePMColor,
69     std::shared_ptr<ImageFilter> background, std::shared_ptr<ImageFilter> foreground, const Rect& cropRect) noexcept
70     :ImageFilter()
71 {
72     type_ = t;
73     impl_->InitWithArithmetic(coefficients, enforcePMColor, background, foreground, cropRect);
74 }
75 
ImageFilter(FilterType t,std::shared_ptr<ImageFilter> f1,std::shared_ptr<ImageFilter> f2)76 ImageFilter::ImageFilter(FilterType t, std::shared_ptr<ImageFilter> f1, std::shared_ptr<ImageFilter> f2) noexcept
77     : ImageFilter()
78 {
79     type_ = t;
80     impl_->InitWithCompose(f1, f2);
81 }
82 
ImageFilter(FilterType t,float radius,const std::vector<std::pair<float,float>> & fractionStops,GradientDir direction,GradientBlurType blurType,std::shared_ptr<ImageFilter> input)83 ImageFilter::ImageFilter(FilterType t, float radius, const std::vector<std::pair<float, float>>& fractionStops,
84     GradientDir direction, GradientBlurType blurType, std::shared_ptr<ImageFilter> input) noexcept
85     : ImageFilter()
86 {
87     type_ = t;
88     impl_->InitWithGradientBlur(radius, fractionStops, direction, blurType, input);
89 }
90 
ImageFilter(FilterType t,const std::shared_ptr<Image> & image,const Rect & srcRect,const Rect & dstRect,const SamplingOptions & options)91 ImageFilter::ImageFilter(FilterType t, const std::shared_ptr<Image>& image, const Rect& srcRect, const Rect& dstRect,
92     const SamplingOptions& options) noexcept : ImageFilter()
93 {
94     type_ = t;
95     impl_->InitWithImage(image, srcRect, dstRect, options);
96 }
97 
ImageFilter(FilterType t)98 ImageFilter::ImageFilter(FilterType t) noexcept
99     : type_(t), impl_(ImplFactory::CreateImageFilterImpl())
100 {}
101 
ImageFilter()102 ImageFilter::ImageFilter() noexcept
103     : type_(ImageFilter::FilterType::NO_TYPE), impl_(ImplFactory::CreateImageFilterImpl())
104 {}
105 
GetType() const106 ImageFilter::FilterType ImageFilter::GetType() const
107 {
108     return type_;
109 }
110 
CreateImageImageFilter(const std::shared_ptr<Image> & image,const Rect & srcRect,const Rect & dstRect,const SamplingOptions & options)111 std::shared_ptr<ImageFilter> ImageFilter::CreateImageImageFilter(
112     const std::shared_ptr<Image>& image, const Rect& srcRect, const Rect& dstRect, const SamplingOptions& options)
113 {
114     return std::make_shared<ImageFilter>(ImageFilter::FilterType::IMAGE, image, srcRect, dstRect, options);
115 }
116 
CreateBlurImageFilter(scalar sigmaX,scalar sigmaY,TileMode mode,std::shared_ptr<ImageFilter> input,ImageBlurType blurType,const Rect & cropRect)117 std::shared_ptr<ImageFilter> ImageFilter::CreateBlurImageFilter(scalar sigmaX, scalar sigmaY, TileMode mode,
118     std::shared_ptr<ImageFilter> input, ImageBlurType blurType, const Rect& cropRect)
119 {
120     // Check if input filter is Lazy type, not supported for direct CreateBlurImageFilter
121     if (input && input->IsLazy()) {
122         LOGE("ImageFilter::CreateBlurImageFilter, input filter is Lazy type, not supported.");
123         return nullptr;
124     }
125 
126     return std::make_shared<ImageFilter>(ImageFilter::FilterType::BLUR, sigmaX, sigmaY,
127         mode, input, blurType, cropRect);
128 }
129 
CreateColorFilterImageFilter(const ColorFilter & cf,std::shared_ptr<ImageFilter> input,const Rect & cropRect)130 std::shared_ptr<ImageFilter> ImageFilter::CreateColorFilterImageFilter(
131     const ColorFilter& cf, std::shared_ptr<ImageFilter> input, const Rect& cropRect)
132 {
133     // Check if input filter is Lazy type, not supported for direct CreateColorFilterImageFilter
134     if (input && input->IsLazy()) {
135         LOGE("ImageFilter::CreateColorFilterImageFilter, input filter is Lazy type, not supported.");
136         return nullptr;
137     }
138 
139     return std::make_shared<ImageFilter>(ImageFilter::FilterType::COLOR_FILTER, cf, input, cropRect);
140 }
141 
CreateColorBlurImageFilter(const ColorFilter & cf,scalar sigmaX,scalar sigmaY,ImageBlurType blurType,const Rect & cropRect)142 std::shared_ptr<ImageFilter> ImageFilter::CreateColorBlurImageFilter(const ColorFilter& cf,
143     scalar sigmaX, scalar sigmaY, ImageBlurType blurType, const Rect& cropRect)
144 {
145     return std::make_shared<ImageFilter>(ImageFilter::FilterType::COLOR_FILTER, cf,
146         sigmaX, sigmaY, blurType, cropRect);
147 }
148 
CreateOffsetImageFilter(scalar dx,scalar dy,std::shared_ptr<ImageFilter> input,const Rect & cropRect)149 std::shared_ptr<ImageFilter> ImageFilter::CreateOffsetImageFilter(
150     scalar dx, scalar dy, std::shared_ptr<ImageFilter> input, const Rect& cropRect)
151 {
152     // Check if input filter is Lazy type, not supported for direct CreateOffsetImageFilter
153     if (input && input->IsLazy()) {
154         LOGE("ImageFilter::CreateOffsetImageFilter, input filter is Lazy type, not supported.");
155         return nullptr;
156     }
157 
158     return std::make_shared<ImageFilter>(ImageFilter::FilterType::OFFSET,
159         dx, dy, input, cropRect);
160 }
161 
CreateGradientBlurImageFilter(float radius,const std::vector<std::pair<float,float>> & fractionStops,GradientDir direction,GradientBlurType blurType,std::shared_ptr<ImageFilter> input)162 std::shared_ptr<ImageFilter> ImageFilter::CreateGradientBlurImageFilter(float radius,
163     const std::vector<std::pair<float, float>>& fractionStops, GradientDir direction,
164     GradientBlurType blurType, std::shared_ptr<ImageFilter> input)
165 {
166     // Check if input filter is Lazy type, not supported for direct CreateGradientBlurImageFilter
167     if (input && input->IsLazy()) {
168         LOGE("ImageFilter::CreateGradientBlurImageFilter, input filter is Lazy type, not supported.");
169         return nullptr;
170     }
171 
172     return std::make_shared<ImageFilter>(
173         ImageFilter::FilterType::GRADIENT_BLUR, radius, fractionStops, direction, blurType, input);
174 }
175 
CreateArithmeticImageFilter(const std::vector<scalar> & coefficients,bool enforcePMColor,std::shared_ptr<ImageFilter> background,std::shared_ptr<ImageFilter> foreground,const Rect & cropRect)176 std::shared_ptr<ImageFilter> ImageFilter::CreateArithmeticImageFilter(const std::vector<scalar>& coefficients,
177     bool enforcePMColor, std::shared_ptr<ImageFilter> background,
178     std::shared_ptr<ImageFilter> foreground, const Rect& cropRect)
179 {
180     // Check if background filter is Lazy type, not supported for direct CreateArithmeticImageFilter
181     if (background && background->IsLazy()) {
182         LOGE("ImageFilter::CreateArithmeticImageFilter, background filter is Lazy type, not supported.");
183         return nullptr;
184     }
185 
186     // Check if foreground filter is Lazy type, not supported for direct CreateArithmeticImageFilter
187     if (foreground && foreground->IsLazy()) {
188         LOGE("ImageFilter::CreateArithmeticImageFilter, foreground filter is Lazy type, not supported.");
189         return nullptr;
190     }
191 
192     return std::make_shared<ImageFilter>(
193         ImageFilter::FilterType::ARITHMETIC, coefficients, enforcePMColor, background, foreground, cropRect);
194 }
195 
CreateComposeImageFilter(std::shared_ptr<ImageFilter> f1,std::shared_ptr<ImageFilter> f2)196 std::shared_ptr<ImageFilter> ImageFilter::CreateComposeImageFilter(
197     std::shared_ptr<ImageFilter> f1, std::shared_ptr<ImageFilter> f2)
198 {
199     // Check if f1 filter is Lazy type, not supported for direct CreateComposeImageFilter
200     if (f1 && f1->IsLazy()) {
201         LOGE("ImageFilter::CreateComposeImageFilter, f1 filter is Lazy type, not supported.");
202         return nullptr;
203     }
204 
205     // Check if f2 filter is Lazy type, not supported for direct CreateComposeImageFilter
206     if (f2 && f2->IsLazy()) {
207         LOGE("ImageFilter::CreateComposeImageFilter, f2 filter is Lazy type, not supported.");
208         return nullptr;
209     }
210 
211     return std::make_shared<ImageFilter>(ImageFilter::FilterType::COMPOSE, f1, f2);
212 }
213 
Serialize() const214 std::shared_ptr<Data> ImageFilter::Serialize() const
215 {
216     return impl_->Serialize();
217 }
218 
Deserialize(std::shared_ptr<Data> data)219 bool ImageFilter::Deserialize(std::shared_ptr<Data> data)
220 {
221     return impl_->Deserialize(data);
222 }
223 
CreateBlendImageFilter(BlendMode mode,std::shared_ptr<ImageFilter> background,std::shared_ptr<ImageFilter> foreground,const Rect & cropRect)224 std::shared_ptr<ImageFilter> ImageFilter::CreateBlendImageFilter(BlendMode mode,
225     std::shared_ptr<ImageFilter> background, std::shared_ptr<ImageFilter> foreground, const Rect& cropRect)
226 {
227     // Check if background filter is Lazy type, not supported for direct CreateBlendImageFilter
228     if (background && background->IsLazy()) {
229         LOGE("ImageFilter::CreateBlendImageFilter, background filter is Lazy type, not supported.");
230         return nullptr;
231     }
232 
233     // Check if foreground filter is Lazy type, not supported for direct CreateBlendImageFilter
234     if (foreground && foreground->IsLazy()) {
235         LOGE("ImageFilter::CreateBlendImageFilter, foreground filter is Lazy type, not supported.");
236         return nullptr;
237     }
238 
239     return std::make_shared<ImageFilter>(ImageFilter::FilterType::BLEND, mode, background, foreground, cropRect);
240 }
241 
ImageFilter(FilterType t,BlendMode mode,std::shared_ptr<ImageFilter> background,std::shared_ptr<ImageFilter> foreground,const Rect & cropRect)242 ImageFilter::ImageFilter(FilterType t, BlendMode mode, std::shared_ptr<ImageFilter> background,
243     std::shared_ptr<ImageFilter> foreground, const Rect& cropRect) noexcept
244     : ImageFilter()
245 {
246     type_ = t;
247     impl_->InitWithBlend(mode, cropRect, background, foreground);
248 }
249 
CreateShaderImageFilter(std::shared_ptr<ShaderEffect> shader,const Rect & cropRect)250 std::shared_ptr<ImageFilter> ImageFilter::CreateShaderImageFilter(
251     std::shared_ptr<ShaderEffect> shader, const Rect& cropRect)
252 {
253     return std::make_shared<ImageFilter>(ImageFilter::FilterType::SHADER, shader, cropRect);
254 }
255 
ImageFilter(FilterType t,std::shared_ptr<ShaderEffect> shader,const Rect & cropRect)256 ImageFilter::ImageFilter(FilterType t, std::shared_ptr<ShaderEffect> shader, const Rect& cropRect) noexcept
257     : ImageFilter()
258 {
259     type_ = t;
260     impl_->InitWithShader(shader, cropRect);
261 }
262 
CreateHDSampleImageFilter(const std::shared_ptr<Image> & image,const Rect & src,const Rect & dst,const HDSampleInfo & info)263 std::shared_ptr<ImageFilter> ImageFilter::CreateHDSampleImageFilter(
264     const std::shared_ptr<Image>& image, const Rect& src, const Rect& dst, const HDSampleInfo& info)
265 {
266     if (!image || src.IsEmpty() || dst.IsEmpty()) {
267         LOGE("ImageFilter::CreateHDSampleImageFilter, image is nullptr or src or dst is empty.");
268         return nullptr;
269     }
270     return std::make_shared<ImageFilter>(ImageFilter::FilterType::HD_SAMPLE, image, src, dst, info);
271 }
272 
ImageFilter(FilterType t,const std::shared_ptr<Image> & image,const Rect & src,const Rect & dst,const HDSampleInfo & info)273 ImageFilter::ImageFilter(FilterType t, const std::shared_ptr<Image>& image,
274     const Rect& src, const Rect& dst, const HDSampleInfo& info) noexcept
275     : ImageFilter()
276 {
277     type_ = t;
278     impl_->InitWithHDSample(image, src, dst, info);
279 }
280 
281 #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel)282 bool ImageFilter::Marshalling(Parcel& parcel)
283 {
284     // Write type first
285     if (!parcel.WriteInt32(static_cast<int32_t>(type_))) {
286         LOGE("ImageFilter::Marshalling, failed to write type");
287         return false;
288     }
289 
290     // Use Serialize to convert to Data then serialize
291     auto data = Serialize();
292 
293     // Write flag indicating whether data is valid
294     bool hasValidData = (data != nullptr && data->GetSize() > 0);
295     if (!parcel.WriteBool(hasValidData)) {
296         LOGE("ImageFilter::Marshalling, failed to write hasData flag");
297         return false;
298     }
299 
300     // If data is null or empty (empty filter), just write the flag and return success
301     // This prevents parcel failure when underlying filter creation failed
302     if (!hasValidData) {
303         LOGD("ImageFilter::Marshalling, Serialize returned null or empty data (empty filter), "
304              "continuing with empty marker");
305         return true;
306     }
307 
308     // Use registered callback for Data marshalling
309     auto callback = ObjectHelper::Instance().GetDataMarshallingCallback();
310     if (!callback) {
311         LOGE("ImageFilter::Marshalling, DataMarshallingCallback is not registered");
312         return false;
313     }
314     if (!callback(parcel, data)) {
315         LOGE("ImageFilter::Marshalling, DataMarshallingCallback failed");
316         return false;
317     }
318     return true;
319 }
320 
Unmarshalling(Parcel & parcel,bool & isValid)321 std::shared_ptr<ImageFilter> ImageFilter::Unmarshalling(Parcel& parcel, bool& isValid)
322 {
323     // Read type first
324     int32_t typeValue;
325     if (!parcel.ReadInt32(typeValue)) {
326         LOGE("ImageFilter::Unmarshalling, failed to read type");
327         return nullptr;
328     }
329 
330     // Validate type range (should be valid filter types, excluding NO_TYPE and LAZY_IMAGE_FILTER)
331     if (typeValue < static_cast<int32_t>(FilterType::NO_TYPE) ||
332         typeValue >= static_cast<int32_t>(FilterType::LAZY_IMAGE_FILTER)) {
333         LOGE("ImageFilter::Unmarshalling, invalid type value: %{public}d", typeValue);
334         return nullptr;
335     }
336 
337     // Read hasData flag
338     bool hasData;
339     if (!parcel.ReadBool(hasData)) {
340         LOGE("ImageFilter::Unmarshalling, failed to read hasData flag");
341         return nullptr;
342     }
343 
344     // If no data (empty filter), create an empty ImageFilter and return
345     if (!hasData) {
346         LOGD("ImageFilter::Unmarshalling, empty filter marker detected, creating empty ImageFilter");
347         auto imageFilter = std::make_shared<ImageFilter>(static_cast<FilterType>(typeValue));
348         return imageFilter;
349     }
350 
351     // Use registered callback for Data unmarshalling
352     auto callback = ObjectHelper::Instance().GetDataUnmarshallingCallback();
353     if (!callback) {
354         LOGE("ImageFilter::Unmarshalling, DataUnmarshallingCallback is not registered");
355         return nullptr;
356     }
357     auto data = callback(parcel);
358     if (!data) {
359         LOGE("ImageFilter::Unmarshalling, DataUnmarshallingCallback failed");
360         return nullptr;
361     }
362 
363     // Create ImageFilter with correct type
364     auto imageFilter = std::make_shared<ImageFilter>(static_cast<FilterType>(typeValue));
365     if (!imageFilter->Deserialize(data)) {
366         LOGE("ImageFilter::Unmarshalling, Deserialize failed");
367         // For compatibility: mark as invalid but return object instead of nullptr
368         isValid = false;
369         return imageFilter;
370     }
371     return imageFilter;
372 }
373 #endif
374 
375 } // namespace Drawing
376 } // namespace Rosen
377 } // namespace OHOS