1 /*
2 * Copyright (C) 2021 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 #ifndef FRAMEWORKS_INNERKITSIMPL_CONVERTER_INCLUDE_PIXEL_CONVERT_H_
17 #define FRAMEWORKS_INNERKITSIMPL_CONVERTER_INCLUDE_PIXEL_CONVERT_H_
18
19 #include <cstdint>
20 #include <cmath>
21 #include <memory>
22 #include "hilog/log.h"
23 #include "image_type.h"
24 #include "log_tags.h"
25
26 namespace OHOS {
27 namespace Media {
28 enum class AlphaConvertType : uint32_t {
29 NO_CONVERT = 0,
30 PREMUL_CONVERT_UNPREMUL = 1,
31 PREMUL_CONVERT_OPAQUE = 2,
32 UNPREMUL_CONVERT_PREMUL = 3,
33 UNPREMUL_CONVERT_OPAQUE = 4,
34 };
35
36 // now support AlphaConvertType
37 struct ProcFuncExtension {
38 AlphaConvertType alphaConvertType;
39 };
40
41 // These values SHOULD be sync with image_type.h PixelFormat
42 constexpr uint32_t GRAY_BIT = 0x80000001; /* Tow value image, just white or black. */
43 constexpr uint32_t GRAY_ALPHA = 0x80000002;
44 constexpr uint32_t ARGB_8888 = 0x00000001;
45 constexpr uint32_t RGB_565 = 0x00000002;
46 constexpr uint32_t RGBA_8888 = 0x00000003;
47 constexpr uint32_t BGRA_8888 = 0x00000004;
48 constexpr uint32_t RGB_888 = 0x00000005;
49 constexpr uint32_t ALPHA_8 = 0x00000006; /* Gray image, 8 bit = 255 color. */
50 constexpr uint32_t RGBA_F16 = 0x00000007;
51 constexpr uint32_t ABGR_8888 = 0x00000008;
52 constexpr uint32_t BGR_888 = 0x40000002;
53 constexpr uint32_t RGB_161616 = 0x40000007;
54 constexpr uint32_t RGBA_16161616 = 0x40000008;
55
56 constexpr uint32_t CMKY = 0x0000000A;
57
58 constexpr uint32_t SIZE_1_BYTE = 0x00000001; /* a pixel has 8 bit = 1 byte */
59 constexpr uint32_t SIZE_2_BYTE = 0x00000002; /* a pixel has 16 bit = 2 byte */
60 constexpr uint32_t SIZE_3_BYTE = 0x00000003;
61 constexpr uint32_t SIZE_4_BYTE = 0x00000004;
62 constexpr uint32_t SIZE_6_BYTE = 0x00000006;
63 constexpr uint32_t SIZE_8_BYTE = 0x00000008;
64
65 constexpr uint8_t GRAYSCALE_WHITE = 0xFF;
66 constexpr uint8_t GRAYSCALE_BLACK = 0x00;
67 constexpr uint32_t ARGB_WHITE = 0xFFFFFFFF;
68 constexpr uint32_t ARGB_BLACK = 0xFF000000;
69 constexpr uint16_t RGB_WHITE = 0xFFFF;
70 constexpr uint16_t RGB_BLACK = 0x0000;
71
72 constexpr uint8_t ALPHA_OPAQUE = 0xFF;
73 constexpr uint8_t ALPHA_TRANSPARENT = 0x00;
74
75 constexpr uint32_t GET_8_BIT = 0x80;
76 constexpr uint32_t GET_1_BIT = 0x01;
77
78 constexpr uint32_t SHIFT_48_BIT = 0x30;
79 constexpr uint32_t SHIFT_32_BIT = 0x20;
80 constexpr uint32_t SHIFT_24_BIT = 0x18;
81 constexpr uint32_t SHIFT_16_BIT = 0x10;
82 constexpr uint32_t SHIFT_8_BIT = 0x08;
83 constexpr uint32_t SHIFT_11_BIT = 0x0B;
84 constexpr uint32_t SHIFT_5_BIT = 0x05;
85 constexpr uint32_t SHIFT_3_BIT = 0x03;
86 constexpr uint32_t SHIFT_2_BIT = 0x02;
87
88 constexpr uint32_t SHIFT_32_MASK = 0x80000000;
89 constexpr uint32_t SHIFT_16_MASK = 0x8000;
90 constexpr uint32_t SHIFT_7_MASK = 0x1C000;
91 constexpr uint8_t SHIFT_5_MASK = 0x1F;
92 constexpr uint8_t SHIFT_3_MASK = 0x07;
93
94 constexpr uint8_t SHIFT_HALF_BIT = 0x0D;
95 constexpr uint32_t SHIFT_HALF_MASK = 0x38000000;
96
97 constexpr uint16_t MAX_15_BIT_VALUE = 0x7FFF;
98 constexpr uint16_t MAX_16_BIT_VALUE = 0xFFFF;
99 constexpr uint32_t MAX_31_BIT_VALUE = 0x7FFFFFFF;
100 constexpr float HALF_ONE = 0.5F;
101 constexpr float MAX_HALF = 65504;
102 constexpr float MIN_EPSILON = 1e-6;
103
FloatCompareTo(float val,float compare)104 static inline bool FloatCompareTo(float val, float compare)
105 {
106 return fabs(val - compare) < MIN_EPSILON;
107 }
108
Premul255(uint32_t colorComponent,uint32_t alpha)109 static inline uint32_t Premul255(uint32_t colorComponent, uint32_t alpha)
110 {
111 if (colorComponent == 0 || colorComponent > MAX_15_BIT_VALUE || alpha > MAX_15_BIT_VALUE) {
112 return 0;
113 }
114 uint32_t product = colorComponent * alpha + GET_8_BIT;
115 if (colorComponent * alpha / colorComponent != alpha) {
116 return 0;
117 }
118 return ((product + (product >> SHIFT_8_BIT)) >> SHIFT_8_BIT);
119 }
120
Unpremul255(uint32_t colorComponent,uint32_t alpha)121 static inline uint32_t Unpremul255(uint32_t colorComponent, uint32_t alpha)
122 {
123 if (colorComponent > ALPHA_OPAQUE || alpha > ALPHA_OPAQUE) {
124 return 0;
125 }
126 if (alpha == ALPHA_TRANSPARENT) {
127 return ALPHA_TRANSPARENT;
128 }
129 if (alpha == ALPHA_OPAQUE) {
130 return colorComponent;
131 }
132 uint32_t result = static_cast<float>(colorComponent) * ALPHA_OPAQUE / alpha + HALF_ONE;
133 return (result > ALPHA_OPAQUE) ? ALPHA_OPAQUE : result;
134 }
135
FloatToUint(float f)136 static inline uint32_t FloatToUint(float f)
137 {
138 uint32_t *p = reinterpret_cast<uint32_t*>(&f);
139 return *p;
140 }
141
UintToFloat(uint32_t ui)142 static inline float UintToFloat(uint32_t ui)
143 {
144 float *pf = reinterpret_cast<float*>(&ui);
145 return *pf;
146 }
147
FloatToHalf(float f)148 static inline uint16_t FloatToHalf(float f)
149 {
150 uint32_t u32 = FloatToUint(f);
151 uint16_t u16 = static_cast<uint16_t>(
152 (((u32 & MAX_31_BIT_VALUE) >> SHIFT_HALF_BIT) - SHIFT_7_MASK) & MAX_16_BIT_VALUE);
153 u16 |= static_cast<uint16_t>(
154 ((u32 & SHIFT_32_MASK) >> SHIFT_16_BIT) & MAX_16_BIT_VALUE);
155 return u16;
156 }
157
HalfToFloat(uint16_t ui)158 static inline float HalfToFloat(uint16_t ui)
159 {
160 uint32_t u32 = ((ui & MAX_15_BIT_VALUE) << SHIFT_HALF_BIT) + SHIFT_HALF_MASK;
161 u32 |= ((ui & SHIFT_16_MASK) << SHIFT_16_BIT);
162 return UintToFloat(u32);
163 }
164
U8ToU16(uint8_t val1,uint8_t val2)165 static inline uint16_t U8ToU16(uint8_t val1, uint8_t val2)
166 {
167 uint16_t ret = val1;
168 return ((ret << SHIFT_8_BIT) | val2);
169 }
170
HalfToUint32(const uint8_t * ui,bool isLittleEndian)171 static inline uint32_t HalfToUint32(const uint8_t* ui, bool isLittleEndian)
172 {
173 uint16_t val = isLittleEndian?U8ToU16(*ui, *(ui + 1)):U8ToU16(*(ui + 1), *ui);
174 float fRet = HalfToFloat(val);
175 return static_cast<uint32_t> (fRet);
176 }
177
178 using ProcFuncType = void (*)(void *destinationRow, const uint8_t *sourceRow, uint32_t sourceWidth,
179 const ProcFuncExtension &extension);
180 class PixelConvert {
181 public:
182 ~PixelConvert() = default;
183 static std::unique_ptr<PixelConvert> Create(const ImageInfo &srcInfo, const ImageInfo &dstInfo);
184 void Convert(void *destinationPixels, const uint8_t *sourcePixels, uint32_t sourcePixelsNum);
185
186 private:
187 PixelConvert(ProcFuncType funcPtr, ProcFuncExtension extension, bool isNeedConvert);
188 static AlphaConvertType GetAlphaConvertType(const AlphaType &srcType, const AlphaType &dstType);
189
190 ProcFuncType procFunc_;
191 ProcFuncExtension procFuncExtension_;
192 bool isNeedConvert_ = true;
193 };
194 } // namespace Media
195 } // namespace OHOS
196
197 #endif // FRAMEWORKS_INNERKITSIMPL_CONVERTER_INCLUDE_PIXEL_CONVERT_H_
198