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