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_COMMON_INCLUDE_PIXEL_MAP_UTILS_H
17 #define FRAMEWORKS_INNERKITSIMPL_COMMON_INCLUDE_PIXEL_MAP_UTILS_H
18 
19 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
20 #include "ashmem.h"
21 #endif
22 
23 #include "image_type.h"
24 #include "log_tags.h"
25 #include "pixel_map.h"
26 
27 namespace OHOS {
28 namespace Media {
29 // Define bytes per pixel
30 constexpr int8_t ALPHA_8_BYTES = 1;
31 constexpr int8_t RGB_565_BYTES = 2;
32 constexpr int8_t RGB_888_BYTES = 3;
33 constexpr int8_t ARGB_8888_BYTES = 4;
34 constexpr int8_t BGRA_F16_BYTES = 8;
35 constexpr int8_t YUV420_BYTES = 2;  // in fact NV21 one pixel used 1.5 bytes.
36 constexpr int8_t YUV420_P010_BYTES = 3;
37 constexpr int8_t ASTC_4x4_BYTES = 1;
38 
39 // Define shift bits of bytes per pixel
40 constexpr int8_t ALPHA_8_SHIFT = 0;
41 constexpr int8_t RGB_565_SHIFT = 1;
42 constexpr int8_t ARGB_8888_SHIFT = 2;
43 
44 // Convert RGB565 16bit pixel to 32bit pixel
45 constexpr uint8_t RGB565_R_BITS = 5;
46 constexpr uint8_t RGB565_G_BITS = 6;
47 constexpr uint8_t RGB565_B_BITS = 5;
48 
49 #if __BYTE_ORDER == __LITTLE_ENDIAN
50 constexpr uint8_t RGB565_R_SHIFT = 0;
51 constexpr uint8_t RGB565_G_SHIFT = RGB565_R_BITS;
52 constexpr uint8_t RGB565_B_SHIFT = RGB565_R_BITS + RGB565_G_BITS;
53 constexpr uint16_t RGB565_R_MASK = 0x001F;
54 constexpr uint16_t RGB565_G_MASK = 0x07E0;
55 constexpr uint16_t RGB565_B_MASK = 0xF800;
56 #else
57 constexpr uint8_t RGB565_R_SHIFT = RGB565_B_BITS + RGB565_G_BITS;
58 constexpr uint8_t RGB565_G_SHIFT = RGB565_B_BITS;
59 constexpr uint8_t RGB565_B_SHIFT = 0;
60 constexpr uint16_t RGB565_R_MASK = 0xF800;
61 constexpr uint16_t RGB565_G_MASK = 0x07E0;
62 constexpr uint16_t RGB565_B_MASK = 0x001F;
63 #endif
64 constexpr uint8_t BYTE_BITS = 8;
65 constexpr uint8_t RGB565_CONVERT_BIT = 2;
66 constexpr uint8_t ARGB8888_CONVERT_BIT = 24;
67 
68 // Convert for ARGB_8888 32bit pixel
69 #if __BYTE_ORDER == __LITTLE_ENDIAN
70 constexpr uint8_t ARGB32_A_SHIFT = 0;
71 constexpr uint8_t ARGB32_R_SHIFT = 8;
72 constexpr uint8_t ARGB32_G_SHIFT = 16;
73 constexpr uint8_t ARGB32_B_SHIFT = 24;
74 #else
75 constexpr uint8_t ARGB32_A_SHIFT = 24;
76 constexpr uint8_t ARGB32_R_SHIFT = 16;
77 constexpr uint8_t ARGB32_G_SHIFT = 8;
78 constexpr uint8_t ARGB32_B_SHIFT = 0;
79 #endif
80 
81 // Convert for RGBA_8888 32bit pixel
82 #if __BYTE_ORDER == __LITTLE_ENDIAN
83 constexpr uint8_t RGBA32_R_SHIFT = 0;
84 constexpr uint8_t RGBA32_G_SHIFT = 8;
85 constexpr uint8_t RGBA32_B_SHIFT = 16;
86 constexpr uint8_t RGBA32_A_SHIFT = 24;
87 #else
88 constexpr uint8_t RGBA32_R_SHIFT = 24;
89 constexpr uint8_t RGBA32_G_SHIFT = 16;
90 constexpr uint8_t RGBA32_B_SHIFT = 8;
91 constexpr uint8_t RGBA32_A_SHIFT = 0;
92 #endif
93 
94 // Convert for BGRA_8888 32bit pixel
95 #if __BYTE_ORDER == __LITTLE_ENDIAN
96 constexpr uint8_t BGRA32_B_SHIFT = 0;
97 constexpr uint8_t BGRA32_G_SHIFT = 8;
98 constexpr uint8_t BGRA32_R_SHIFT = 16;
99 constexpr uint8_t BGRA32_A_SHIFT = 24;
100 #else
101 constexpr uint8_t BGRA32_B_SHIFT = 24;
102 constexpr uint8_t BGRA32_G_SHIFT = 16;
103 constexpr uint8_t BGRA32_R_SHIFT = 8;
104 constexpr uint8_t BGRA32_A_SHIFT = 0;
105 #endif
106 
107 constexpr uint8_t BYTE_FULL = 0xFF;
108 constexpr uint8_t BYTE_ZERO = 0;
109 constexpr uint8_t ONE_PIXEL_SIZE = 1;
110 
111 /*
112  * For RGB_565
113  * 1. get R(5-bits)/G(6-bits)/B(5-bits) channel value form color value(uint16_t)
114  * 2. convert R(5-bits)/G(6-bits)/B(5-bits) value to R(8-bits)/G(8-bits)/B(8-bits)
115  * 3. construct normalized color value with A(255)/R(8-bits)/G(8-bits)/B(8-bits)
116  * 4. the normalized color format: (A << 24 | R << 16 | G << 8 | B << 0)
117  */
GetRGB565Channel(uint16_t color,uint16_t mask,uint8_t shift)118 static uint8_t GetRGB565Channel(uint16_t color, uint16_t mask, uint8_t shift)
119 {
120     return (color & mask) >> shift;
121 }
122 
RGB565To32(uint8_t channel,uint8_t bits)123 static uint8_t RGB565To32(uint8_t channel, uint8_t bits)
124 {
125     return (channel << (BYTE_BITS - bits)) | (channel >> (RGB565_CONVERT_BIT * bits - BYTE_BITS));
126 }
127 
RGB565ToR32(uint16_t color)128 static uint8_t RGB565ToR32(uint16_t color)
129 {
130     return RGB565To32(GetRGB565Channel(color, RGB565_R_MASK, RGB565_R_SHIFT), RGB565_R_BITS);
131 }
132 
RGB565ToG32(uint16_t color)133 static uint8_t RGB565ToG32(uint16_t color)
134 {
135     return RGB565To32(GetRGB565Channel(color, RGB565_G_MASK, RGB565_G_SHIFT), RGB565_G_BITS);
136 }
137 
RGB565ToB32(uint16_t color)138 static uint8_t RGB565ToB32(uint16_t color)
139 {
140     return RGB565To32(GetRGB565Channel(color, RGB565_B_MASK, RGB565_B_SHIFT), RGB565_B_BITS);
141 }
142 
143 /*
144  * For ARGB_8888
145  * 1. get A(8-bits)/R(8-bits)/G(8-bits)/B(8-bits) channel value form color value(uint32_t)
146  * 2. construct normalized color value with A(8-bits)/R(8-bits)/G(8-bits)/B(8-bits)
147  * 3. the normalized color format: (A << 24 | R << 16 | G << 8 | B << 0)
148  */
GetColorComp(uint32_t color,uint8_t shift)149 static uint8_t GetColorComp(uint32_t color, uint8_t shift)
150 {
151     return ((color) << (ARGB8888_CONVERT_BIT - shift)) >> ARGB8888_CONVERT_BIT;
152 }
153 
GetColorARGB(uint8_t a,uint8_t r,uint8_t g,uint8_t b)154 static uint32_t GetColorARGB(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
155 {
156     return ((uint32_t)(a << ARGB_A_SHIFT) | (uint32_t)(r << ARGB_R_SHIFT)
157         | (uint32_t)(g << ARGB_G_SHIFT) | (uint32_t)(b << ARGB_B_SHIFT));
158 }
159 
160 static ImageInfo MakeImageInfo(int width, int height, PixelFormat pf, AlphaType at, ColorSpace cs = ColorSpace::SRGB)
161 {
162     ImageInfo info;
163     info.size.width = width;
164     info.size.height = height;
165     info.pixelFormat = pf;
166     info.alphaType = at;
167     info.colorSpace = cs;
168     return info;
169 }
170 
171 static bool CheckAshmemSize(const int &fd, const int32_t &bufferSize, bool isAstc = false)
172 {
173 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
174     if (fd < 0) {
175         return false;
176     }
177     int32_t ashmemSize = AshmemGetSize(fd);
178     return isAstc || bufferSize == ashmemSize;
179 #else
180     return false;
181 #endif
182 }
183 } // namespace Media
184 } // namespace OHOS
185 
186 #endif // FRAMEWORKS_INNERKITSIMPL_COMMON_INCLUDE_PIXEL_MAP_UTILS_H
187