1 /*
2 * Copyright (c) 2024 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 #include "filter_common.h"
16
17 #include <atomic>
18 #include <mutex>
19 #include <shared_mutex>
20 #include <unordered_map>
21
22 #include "effect_errors.h"
23 #include "effect_utils.h"
24 #include "sk_image_chain.h"
25 #include "sk_image_filter_factory.h"
26
27 namespace OHOS {
28 namespace Rosen {
29 using namespace OHOS::Media;
30
31 namespace {
32 constexpr uint32_t MALLOC_FAILED = -1;
33 }
34
35 struct CMFilterContext {
36 uint32_t status = SUCCESS;
37 std::shared_ptr<FilterCommon> filter = nullptr;
38 bool forceCPU = true;
39 std::shared_ptr<Media::PixelMap> dstPixelMap_;
40 };
41
42 thread_local std::shared_ptr<FilterCommon> FilterCommon::sConstructor_ = nullptr;
43
AddNextFilter(sk_sp<SkImageFilter> filter)44 void FilterCommon::AddNextFilter(sk_sp<SkImageFilter> filter)
45 {
46 skFilters_.emplace_back(filter);
47 }
48
CreateEffect(const std::shared_ptr<PixelMap> & pixmap,uint32_t & errorCode)49 std::shared_ptr<FilterCommon> FilterCommon::CreateEffect(const std::shared_ptr<PixelMap>& pixmap, uint32_t& errorCode)
50 {
51 if (pixmap == nullptr) {
52 errorCode = ERR_INVALID_PARAM;
53 return nullptr;
54 }
55 auto context = std::make_shared<FilterCommon>();
56 if (context == nullptr) {
57 EFFECT_LOG_E("[FilterCommon]failed to create ColorPickerCommon with null context.");
58 errorCode = MALLOC_FAILED;
59 return nullptr;
60 }
61
62 context->srcPixelMap_ = pixmap;
63 sConstructor_ = context;
64 return context;
65 }
66
Blur(float radius)67 bool FilterCommon::Blur(float radius)
68 {
69 SkTileMode tileMode = SkTileMode::kDecal;
70 auto blur = Rosen::SKImageFilterFactory::Blur(radius, tileMode);
71 if (!blur) {
72 EFFECT_LOG_E("[FilterCommon]blur is nullptr.");
73 return false;
74 }
75 sConstructor_->AddNextFilter(blur);
76 return true;
77 }
78
Invert()79 bool FilterCommon::Invert()
80 {
81 auto invert = Rosen::SKImageFilterFactory::Invert();
82 if (!invert) {
83 EFFECT_LOG_E("[FilterCommon]invert is nullptr.");
84 return false;
85 }
86 sConstructor_->AddNextFilter(invert);
87 return true;
88 }
89
Brightness(float bright)90 bool FilterCommon::Brightness(float bright)
91 {
92 auto brightness = Rosen::SKImageFilterFactory::Brightness(bright);
93 if (!brightness) {
94 EFFECT_LOG_E("[FilterCommon]brightness is nullptr.");
95 return false;
96 }
97 sConstructor_->AddNextFilter(brightness);
98 return true;
99 }
100
Grayscale()101 bool FilterCommon::Grayscale()
102 {
103 auto grayscale = Rosen::SKImageFilterFactory::Grayscale();
104 if (!grayscale) {
105 EFFECT_LOG_E("[FilterCommon]grayscale is nullptr.");
106 return false;
107 }
108 sConstructor_->AddNextFilter(grayscale);
109 return true;
110 }
111
ParseColorMatrix(std::vector<float> inputColorMatrix,PixelColorMatrix & colorMatrix)112 static uint32_t ParseColorMatrix(std::vector<float> inputColorMatrix, PixelColorMatrix& colorMatrix)
113 {
114 size_t len = inputColorMatrix.size();
115 for (size_t i = 0; i < len; i++) {
116 colorMatrix.val[i] = inputColorMatrix[i];
117 }
118 return SUCCESS;
119 }
120
SetColorMatrix(std::vector<float> inputcolorMatrix,uint32_t & code)121 bool FilterCommon::SetColorMatrix(std::vector<float> inputcolorMatrix, uint32_t& code)
122 {
123 uint32_t res = 0;
124 PixelColorMatrix colorMatrix;
125 res = ParseColorMatrix(inputcolorMatrix, colorMatrix);
126 if (res != SUCCESS) {
127 EFFECT_LOG_E("[FilterCommon]Color matrix mismatch");
128 code = ERR_INVALID_PARAM;
129 return false;
130 }
131
132 auto applyColorMatrix = Rosen::SKImageFilterFactory::ApplyColorMatrix(colorMatrix);
133 if (!applyColorMatrix) {
134 EFFECT_LOG_E("[FilterCommon]applyColorMatrix is nullptr.");
135 return false;
136 }
137 sConstructor_->AddNextFilter(applyColorMatrix);
138 return true;
139 }
140
Render(bool forceCPU)141 DrawError FilterCommon::Render(bool forceCPU)
142 {
143 Rosen::SKImageChain skImage(srcPixelMap_);
144 return skImage.Render(skFilters_, forceCPU, dstPixelMap_);
145 }
146
GetDstPixelMap()147 std::shared_ptr<Media::PixelMap> FilterCommon::GetDstPixelMap()
148 {
149 return dstPixelMap_;
150 }
151
GetEffectPixelMap()152 std::shared_ptr<OHOS::Media::PixelMap> FilterCommon::GetEffectPixelMap()
153 {
154 std::unique_ptr<CMFilterContext> ctx = std::make_unique<CMFilterContext>();
155 ctx->filter = sConstructor_;
156 if (ctx->filter->Render(ctx->forceCPU) != DrawError::ERR_OK) {
157 EFFECT_LOG_E("[FilterCommon]Render fail");
158 return nullptr;
159 }
160 ctx->dstPixelMap_ = ctx->filter->GetDstPixelMap();
161
162 return ctx->dstPixelMap_;
163 }
164
165 } // namespace Rosen
166 } // namespace OHOS