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