1 /* 2 * Copyright (c) 2022 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 #ifndef GRAPHIC_LITE_FILTER_BLUR_H 16 #define GRAPHIC_LITE_FILTER_BLUR_H 17 18 #include "gfx_utils/diagram/common/common_basics.h" 19 #include "gfx_utils/graphic_math.h" 20 #include "graphic_config.h" 21 #include "securec.h" 22 23 namespace OHOS { 24 class Filterblur { 25 #if defined(GRAPHIC_ENABLE_BLUR_EFFECT_FLAG) && GRAPHIC_ENABLE_BLUR_EFFECT_FLAG 26 27 public: Filterblur()28 Filterblur() 29 { 30 integral_ = nullptr; 31 imageWidth_ = 0; 32 imageHeight_ = 0; 33 } ~Filterblur()34 ~Filterblur() 35 { 36 if (integral_ != nullptr) { 37 free(integral_); 38 } 39 } 40 41 template <class Img> BoxBlur(Img & img,uint16_t radius,int32_t channel,int32_t stride)42 void BoxBlur(Img& img, uint16_t radius, int32_t channel, int32_t stride) 43 { 44 if (radius < 1) { 45 return; 46 } 47 int32_t width = img.GetWidth(); 48 int32_t height = img.GetHeight(); 49 bool isGetRGBAIntegral = false; 50 if (integral_ == nullptr || ((imageWidth_ * imageHeight_) != (width * height))) { 51 if (integral_ != nullptr) { 52 free(integral_); 53 } 54 integral_ = (int32_t*)malloc((width + 1) * (height + 1) * channel * sizeof(int32_t)); 55 isGetRGBAIntegral = true; 56 } 57 if (channel == FOUR_TIMES) { 58 if (isGetRGBAIntegral) { 59 GetRGBAIntegralImage((uint8_t*)img.PixValuePtr(0, 0), width, height, stride); 60 } 61 #ifndef __ICCARM__ 62 #pragma omp parallel for 63 #endif 64 for (int32_t y = 0; y < height; y++) { 65 int32_t y1 = MATH_MAX(y - radius, 0); 66 int32_t y2 = MATH_MIN(y + radius + 1, height); 67 uint8_t* lineImageHeader = (uint8_t*)img.PixValuePtr(0, 0) + y * stride; 68 uint8_t* linePD = lineImageHeader; 69 int32_t* lineP1 = integral_ + y1 * ((width + 1) << 2); 70 int32_t* lineP2 = integral_ + y2 * ((width + 1) << 2); 71 72 for (int32_t x = 0; x < width; x++) { 73 int32_t x1 = MATH_MAX(x - radius, 0); 74 int32_t x2 = MATH_MIN(x + radius + 1, width); 75 int32_t index1 = x1 << 2; 76 int32_t index2 = x2 << 2; 77 int32_t sumB = lineP2[index2 + 0] - lineP1[index2 + 0] - 78 lineP2[index1 + 0] + lineP1[index1 + 0]; 79 int32_t sumG = lineP2[index2 + 1] - lineP1[index2 + 1] - 80 lineP2[index1 + 1] + lineP1[index1 + 1]; 81 int32_t sumR = lineP2[index2 + 2] - lineP1[index2 + 2] - 82 lineP2[index1 + 2] + lineP1[index1 + 2]; 83 84 const int32_t pixelCount = (x2 - x1) * (y2 - y1); 85 linePD[0] = (sumB + (pixelCount >> 1)) / pixelCount; 86 linePD[1] = (sumG + (pixelCount >> 1)) / pixelCount; 87 linePD[2] = (sumR + (pixelCount >> 1)) / pixelCount; 88 uint8_t* alpha = lineImageHeader + (x << 2); 89 linePD[3] = alpha[3]; 90 linePD += 4; 91 } 92 } 93 } 94 } 95 private: GetRGBAIntegralImage(uint8_t * src,uint16_t width,uint16_t height,uint16_t stride)96 void GetRGBAIntegralImage(uint8_t* src, uint16_t width, uint16_t height, uint16_t stride) 97 { 98 int32_t channel = FOUR_TIMES; 99 if (integral_ != nullptr && ((imageWidth_ * imageHeight_) != (width * height))) { 100 int32_t integralSize = (width + 1) * channel * sizeof(int32_t); 101 memset_s(integral_, integralSize, 0, integralSize); 102 } 103 for (int y = 0; y < height; y++) { 104 uint8_t* linePS = src + y * stride; 105 // last position 106 int32_t* linePL = integral_ + y * (width + 1) * channel + channel; 107 // curretn position£¬waring the first column of every line row is zero 108 int32_t* linePD = integral_ + (y + 1) * (width + 1) * channel + channel; 109 // the first column is 0 110 linePD[-4] = 0; 111 linePD[-3] = 0; 112 linePD[-2] = 0; 113 linePD[-1] = 0; 114 for (int x = 0, sumB = 0, sumG = 0, sumR = 0, sumA = 0; x < width; x++) { 115 sumB += linePS[0]; 116 sumG += linePS[1]; 117 sumR += linePS[2]; 118 sumA += linePS[3]; 119 linePD[0] = linePL[0] + sumB; 120 linePD[1] = linePL[1] + sumG; 121 linePD[2] = linePL[2] + sumR; 122 linePD[3] = linePL[3] + sumA; 123 linePS += channel; 124 linePL += channel; 125 linePD += channel; 126 } 127 } 128 } 129 130 int32_t* integral_; 131 int32_t imageWidth_; 132 int32_t imageHeight_; 133 #endif 134 }; 135 } // namespace OHOS 136 #endif 137