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
25 namespace OHOS {
26 namespace Rosen {
27 using namespace OHOS::Media;
28
29 namespace {
30 constexpr uint32_t MALLOC_FAILED = -1;
31 }
32
33 struct CMFilterContext {
34 uint32_t status = SUCCESS;
35 std::shared_ptr<FilterCommon> filter = nullptr;
36 bool forceCPU = true;
37 std::shared_ptr<Media::PixelMap> dstPixelMap_;
38 };
39
40 thread_local std::shared_ptr<FilterCommon> FilterCommon::sConstructor_ = nullptr;
41
AddNextFilter(std::shared_ptr<EffectImageFilter> filter)42 void FilterCommon::AddNextFilter(std::shared_ptr<EffectImageFilter> filter)
43 {
44 effectFilters_.emplace_back(filter);
45 }
46
CreateEffect(const std::shared_ptr<PixelMap> & pixmap,uint32_t & errorCode)47 std::shared_ptr<FilterCommon> FilterCommon::CreateEffect(const std::shared_ptr<PixelMap>& pixmap, uint32_t& errorCode)
48 {
49 if (pixmap == nullptr) {
50 errorCode = ERR_INVALID_PARAM;
51 return nullptr;
52 }
53 auto context = std::make_shared<FilterCommon>();
54 if (context == nullptr) {
55 EFFECT_LOG_E("[FilterCommon]failed to create ColorPickerCommon with null context.");
56 errorCode = MALLOC_FAILED;
57 return nullptr;
58 }
59
60 context->srcPixelMap_ = pixmap;
61 sConstructor_ = context;
62 return context;
63 }
64
Blur(float radius)65 bool FilterCommon::Blur(float radius)
66 {
67 Drawing::TileMode tileMode = Drawing::TileMode::DECAL;
68 auto blur = EffectImageFilter::Blur(radius, tileMode);
69 if (!blur) {
70 EFFECT_LOG_E("[FilterCommon]blur is nullptr.");
71 return false;
72 }
73 sConstructor_->AddNextFilter(blur);
74 return true;
75 }
76
Invert()77 bool FilterCommon::Invert()
78 {
79 auto invert = EffectImageFilter::Invert();
80 if (!invert) {
81 EFFECT_LOG_E("[FilterCommon]invert is nullptr.");
82 return false;
83 }
84 sConstructor_->AddNextFilter(invert);
85 return true;
86 }
87
Brightness(float bright)88 bool FilterCommon::Brightness(float bright)
89 {
90 auto brightness = EffectImageFilter::Brightness(bright);
91 if (!brightness) {
92 EFFECT_LOG_E("[FilterCommon]brightness is nullptr.");
93 return false;
94 }
95 sConstructor_->AddNextFilter(brightness);
96 return true;
97 }
98
Grayscale()99 bool FilterCommon::Grayscale()
100 {
101 auto grayscale = EffectImageFilter::Grayscale();
102 if (!grayscale) {
103 EFFECT_LOG_E("[FilterCommon]grayscale is nullptr.");
104 return false;
105 }
106 sConstructor_->AddNextFilter(grayscale);
107 return true;
108 }
109
ParseColorMatrix(std::vector<float> inputColorMatrix,Drawing::ColorMatrix & colorMatrix)110 static uint32_t ParseColorMatrix(std::vector<float> inputColorMatrix, Drawing::ColorMatrix& colorMatrix)
111 {
112 float matrix[Drawing::ColorMatrix::MATRIX_SIZE] = { 0 };
113 size_t len = inputColorMatrix.size();
114 for (size_t i = 0; i < len; i++) {
115 matrix[i] = inputColorMatrix[i];
116 }
117 colorMatrix.SetArray(matrix);
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 Drawing::ColorMatrix 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 = EffectImageFilter::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 DrawingError FilterCommon::Render(bool forceCPU)
142 {
143 EffectImageRender imageRender;
144 return imageRender.Render(srcPixelMap_, effectFilters_, 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) != DrawingError::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