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