1 /*
2 * Copyright (c) 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_lazy.h"
17
18 #include "effect/blur_image_filter_obj.h"
19 #include "effect/color_filter_image_filter_obj.h"
20 #include "effect/offset_image_filter_obj.h"
21 #include "effect/shader_image_filter_obj.h"
22 #include "utils/data.h"
23 #include "utils/log.h"
24
25 #ifdef ROSEN_OHOS
26 #include "utils/object_helper.h"
27 #endif
28
29 namespace OHOS {
30 namespace Rosen {
31 namespace Drawing {
32
ImageFilterLazy(std::shared_ptr<ImageFilterObj> imageFilterObj)33 ImageFilterLazy::ImageFilterLazy(std::shared_ptr<ImageFilterObj> imageFilterObj) noexcept
34 : ImageFilter(FilterType::LAZY_IMAGE_FILTER), imageFilterObj_(imageFilterObj)
35 {
36 }
37
CreateBlur(scalar sigmaX,scalar sigmaY,TileMode tileMode,const std::shared_ptr<ImageFilter> & input,ImageBlurType blurType,const Rect & cropRect)38 std::shared_ptr<ImageFilterLazy> ImageFilterLazy::CreateBlur(scalar sigmaX, scalar sigmaY,
39 TileMode tileMode, const std::shared_ptr<ImageFilter>& input, ImageBlurType blurType, const Rect& cropRect)
40 {
41 auto blurImageFilterObj = BlurImageFilterObj::Create(sigmaX, sigmaY, tileMode, input, blurType, cropRect);
42 if (!blurImageFilterObj) {
43 LOGD("ImageFilterLazy::CreateBlur, failed to create BlurImageFilterObj");
44 return nullptr;
45 }
46 return CreateFromImageFilterObj(blurImageFilterObj);
47 }
48
CreateColorFilter(const std::shared_ptr<ColorFilter> & colorFilter,const std::shared_ptr<ImageFilter> & input,const Rect & cropRect)49 std::shared_ptr<ImageFilterLazy> ImageFilterLazy::CreateColorFilter(const std::shared_ptr<ColorFilter>& colorFilter,
50 const std::shared_ptr<ImageFilter>& input, const Rect& cropRect)
51 {
52 if (!colorFilter) {
53 LOGD("ImageFilterLazy::CreateColorFilter, colorFilter is null");
54 return nullptr;
55 }
56
57 auto colorFilterImageFilterObj = ColorFilterImageFilterObj::Create(colorFilter, input, cropRect);
58 if (!colorFilterImageFilterObj) {
59 LOGD("ImageFilterLazy::CreateColorFilter, failed to create ColorFilterImageFilterObj");
60 return nullptr;
61 }
62 return CreateFromImageFilterObj(colorFilterImageFilterObj);
63 }
64
CreateOffset(scalar dx,scalar dy,const std::shared_ptr<ImageFilter> & input,const Rect & cropRect)65 std::shared_ptr<ImageFilterLazy> ImageFilterLazy::CreateOffset(scalar dx, scalar dy,
66 const std::shared_ptr<ImageFilter>& input, const Rect& cropRect)
67 {
68 auto offsetImageFilterObj = OffsetImageFilterObj::Create(dx, dy, input, cropRect);
69 if (!offsetImageFilterObj) {
70 LOGD("ImageFilterLazy::CreateOffset, failed to create OffsetImageFilterObj");
71 return nullptr;
72 }
73 return CreateFromImageFilterObj(offsetImageFilterObj);
74 }
75
CreateShader(const std::shared_ptr<ShaderEffect> & shader,const Rect & cropRect)76 std::shared_ptr<ImageFilterLazy> ImageFilterLazy::CreateShader(const std::shared_ptr<ShaderEffect>& shader,
77 const Rect& cropRect)
78 {
79 if (!shader) {
80 LOGD("ImageFilterLazy::CreateShader, shader is null");
81 return nullptr;
82 }
83
84 auto shaderImageFilterObj = ShaderImageFilterObj::Create(shader, cropRect);
85 if (!shaderImageFilterObj) {
86 LOGD("ImageFilterLazy::CreateShader, failed to create ShaderImageFilterObj");
87 return nullptr;
88 }
89 return CreateFromImageFilterObj(shaderImageFilterObj);
90 }
91
CreateFromImageFilterObj(std::shared_ptr<ImageFilterObj> object)92 std::shared_ptr<ImageFilterLazy> ImageFilterLazy::CreateFromImageFilterObj(std::shared_ptr<ImageFilterObj> object)
93 {
94 if (!object) {
95 LOGD("ImageFilterLazy::CreateFromImageFilterObj, object is null");
96 return nullptr;
97 }
98
99 // Validate object type
100 if (object->GetType() != static_cast<int32_t>(Object::ObjectType::IMAGE_FILTER)) {
101 LOGE("ImageFilterLazy::CreateFromImageFilterObj, invalid object type: %{public}d, expected: %{public}d",
102 object->GetType(), static_cast<int32_t>(Object::ObjectType::IMAGE_FILTER));
103 return nullptr;
104 }
105
106 return std::shared_ptr<ImageFilterLazy>(new ImageFilterLazy(object));
107 }
108
Materialize()109 std::shared_ptr<ImageFilter> ImageFilterLazy::Materialize()
110 {
111 if (imageFilterCache_) {
112 return imageFilterCache_;
113 }
114
115 if (!imageFilterObj_) {
116 return nullptr;
117 }
118
119 auto baseObject = imageFilterObj_->GenerateBaseObject();
120 if (!baseObject) {
121 return nullptr;
122 }
123
124 imageFilterCache_ = std::static_pointer_cast<ImageFilter>(baseObject);
125 return imageFilterCache_;
126 }
127
Serialize() const128 std::shared_ptr<Data> ImageFilterLazy::Serialize() const
129 {
130 LOGE("ImageFilterLazy::Serialize, should use Marshalling() instead. Check IsLazy() first.");
131 LOGD("ImageFilterObj type: %{public}d, subType: %{public}d",
132 imageFilterObj_ ? imageFilterObj_->GetType() : -1,
133 imageFilterObj_ ? imageFilterObj_->GetSubType() : -1);
134 return nullptr;
135 }
136
Deserialize(std::shared_ptr<Data> data)137 bool ImageFilterLazy::Deserialize(std::shared_ptr<Data> data)
138 {
139 LOGE("ImageFilterLazy::Deserialize, should use Unmarshalling() instead. Check IsLazy() first.");
140 LOGD("Attempted to deserialize %zu bytes into Lazy object", data ? data->GetSize() : 0);
141 return false;
142 }
143
144 #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel)145 bool ImageFilterLazy::Marshalling(Parcel& parcel)
146 {
147 if (!imageFilterObj_) {
148 return false;
149 }
150
151 // Write type and subType from internal object
152 if (!parcel.WriteInt32(imageFilterObj_->GetType()) ||
153 !parcel.WriteInt32(imageFilterObj_->GetSubType())) {
154 LOGE("ImageFilterLazy::Marshalling, failed to write type and subType");
155 return false;
156 }
157
158 // Use ImageFilterObj's Marshalling for internal data
159 return imageFilterObj_->Marshalling(parcel);
160 }
161
Unmarshalling(Parcel & parcel,bool & isValid,int32_t depth)162 std::shared_ptr<ImageFilterLazy> ImageFilterLazy::Unmarshalling(Parcel& parcel, bool& isValid, int32_t depth)
163 {
164 // Read type and subType with safety checks
165 int32_t type;
166 if (!parcel.ReadInt32(type)) {
167 LOGE("ImageFilterLazy::Unmarshalling, failed to read type");
168 return nullptr;
169 }
170 int32_t subType;
171 if (!parcel.ReadInt32(subType)) {
172 LOGE("ImageFilterLazy::Unmarshalling, failed to read subType");
173 return nullptr;
174 }
175
176 // Create corresponding ImageFilterObj (depth check is done inside func)
177 auto func = ObjectHelper::Instance().GetFunc(type, subType);
178 auto obj = func ? func(parcel, isValid, depth + 1) : nullptr;
179 if (!obj) {
180 LOGE("ImageFilterLazy::Unmarshalling, failed to create ImageFilterObj for type=%{public}d, subType=%{public}d",
181 type, subType);
182 return nullptr;
183 }
184
185 // Create ImageFilterLazy to wrap ExtendObject
186 auto imageFilterObj = std::static_pointer_cast<ImageFilterObj>(obj);
187 auto lazyFilter = CreateFromImageFilterObj(imageFilterObj);
188 if (!lazyFilter) {
189 LOGE("ImageFilterLazy::Unmarshalling, failed to create ImageFilterLazy");
190 return nullptr;
191 }
192
193 return lazyFilter;
194 }
195 #endif
196
197 } // namespace Drawing
198 } // namespace Rosen
199 } // namespace OHOS