• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "memory_manager.h"
26 #include "pixel_convert_adapter.h"
27 #include "pixel_map.h"
28 
29 namespace OHOS {
30 namespace Media {
31 // Define bytes per pixel
32 constexpr int8_t ALPHA_8_BYTES = 1;
33 constexpr int8_t RGB_565_BYTES = 2;
34 constexpr int8_t RGB_888_BYTES = 3;
35 constexpr int8_t ARGB_8888_BYTES = 4;
36 constexpr int8_t BGRA_F16_BYTES = 8;
37 constexpr int8_t YUV420_BYTES = 2;  // in fact NV21 one pixel used 1.5 bytes.
38 constexpr int8_t YUV420_P010_BYTES = 3;
39 constexpr int8_t ASTC_4x4_BYTES = 1;
40 
41 // Define shift bits of bytes per pixel
42 constexpr int8_t ALPHA_8_SHIFT = 0;
43 constexpr int8_t RGB_565_SHIFT = 1;
44 constexpr int8_t ARGB_8888_SHIFT = 2;
45 
46 // Convert RGB565 16bit pixel to 32bit pixel
47 constexpr uint8_t RGB565_R_BITS = 5;
48 constexpr uint8_t RGB565_G_BITS = 6;
49 constexpr uint8_t RGB565_B_BITS = 5;
50 
51 #if __BYTE_ORDER == __LITTLE_ENDIAN
52 constexpr uint8_t RGB565_R_SHIFT = 0;
53 constexpr uint8_t RGB565_G_SHIFT = RGB565_R_BITS;
54 constexpr uint8_t RGB565_B_SHIFT = RGB565_R_BITS + RGB565_G_BITS;
55 constexpr uint16_t RGB565_R_MASK = 0x001F;
56 constexpr uint16_t RGB565_G_MASK = 0x07E0;
57 constexpr uint16_t RGB565_B_MASK = 0xF800;
58 #else
59 constexpr uint8_t RGB565_R_SHIFT = RGB565_B_BITS + RGB565_G_BITS;
60 constexpr uint8_t RGB565_G_SHIFT = RGB565_B_BITS;
61 constexpr uint8_t RGB565_B_SHIFT = 0;
62 constexpr uint16_t RGB565_R_MASK = 0xF800;
63 constexpr uint16_t RGB565_G_MASK = 0x07E0;
64 constexpr uint16_t RGB565_B_MASK = 0x001F;
65 #endif
66 constexpr uint8_t BYTE_BITS = 8;
67 constexpr uint8_t RGB565_CONVERT_BIT = 2;
68 constexpr uint8_t ARGB8888_CONVERT_BIT = 24;
69 
70 // Convert for ARGB_8888 32bit pixel
71 #if __BYTE_ORDER == __LITTLE_ENDIAN
72 constexpr uint8_t ARGB32_A_SHIFT = 0;
73 constexpr uint8_t ARGB32_R_SHIFT = 8;
74 constexpr uint8_t ARGB32_G_SHIFT = 16;
75 constexpr uint8_t ARGB32_B_SHIFT = 24;
76 #else
77 constexpr uint8_t ARGB32_A_SHIFT = 24;
78 constexpr uint8_t ARGB32_R_SHIFT = 16;
79 constexpr uint8_t ARGB32_G_SHIFT = 8;
80 constexpr uint8_t ARGB32_B_SHIFT = 0;
81 #endif
82 
83 // Convert for RGBA_8888 32bit pixel
84 #if __BYTE_ORDER == __LITTLE_ENDIAN
85 constexpr uint8_t RGBA32_R_SHIFT = 0;
86 constexpr uint8_t RGBA32_G_SHIFT = 8;
87 constexpr uint8_t RGBA32_B_SHIFT = 16;
88 constexpr uint8_t RGBA32_A_SHIFT = 24;
89 #else
90 constexpr uint8_t RGBA32_R_SHIFT = 24;
91 constexpr uint8_t RGBA32_G_SHIFT = 16;
92 constexpr uint8_t RGBA32_B_SHIFT = 8;
93 constexpr uint8_t RGBA32_A_SHIFT = 0;
94 #endif
95 
96 // Convert for BGRA_8888 32bit pixel
97 #if __BYTE_ORDER == __LITTLE_ENDIAN
98 constexpr uint8_t BGRA32_B_SHIFT = 0;
99 constexpr uint8_t BGRA32_G_SHIFT = 8;
100 constexpr uint8_t BGRA32_R_SHIFT = 16;
101 constexpr uint8_t BGRA32_A_SHIFT = 24;
102 #else
103 constexpr uint8_t BGRA32_B_SHIFT = 24;
104 constexpr uint8_t BGRA32_G_SHIFT = 16;
105 constexpr uint8_t BGRA32_R_SHIFT = 8;
106 constexpr uint8_t BGRA32_A_SHIFT = 0;
107 #endif
108 
109 constexpr uint8_t BYTE_FULL = 0xFF;
110 constexpr uint8_t BYTE_ZERO = 0;
111 constexpr uint8_t ONE_PIXEL_SIZE = 1;
112 
113 /*
114  * For RGB_565
115  * 1. get R(5-bits)/G(6-bits)/B(5-bits) channel value form color value(uint16_t)
116  * 2. convert R(5-bits)/G(6-bits)/B(5-bits) value to R(8-bits)/G(8-bits)/B(8-bits)
117  * 3. construct normalized color value with A(255)/R(8-bits)/G(8-bits)/B(8-bits)
118  * 4. the normalized color format: (A << 24 | R << 16 | G << 8 | B << 0)
119  */
GetRGB565Channel(uint16_t color,uint16_t mask,uint8_t shift)120 static uint8_t GetRGB565Channel(uint16_t color, uint16_t mask, uint8_t shift)
121 {
122     return (color & mask) >> shift;
123 }
124 
RGB565To32(uint8_t channel,uint8_t bits)125 static uint8_t RGB565To32(uint8_t channel, uint8_t bits)
126 {
127     return (channel << (BYTE_BITS - bits)) | (channel >> (RGB565_CONVERT_BIT * bits - BYTE_BITS));
128 }
129 
RGB565ToR32(uint16_t color)130 static uint8_t RGB565ToR32(uint16_t color)
131 {
132     return RGB565To32(GetRGB565Channel(color, RGB565_R_MASK, RGB565_R_SHIFT), RGB565_R_BITS);
133 }
134 
RGB565ToG32(uint16_t color)135 static uint8_t RGB565ToG32(uint16_t color)
136 {
137     return RGB565To32(GetRGB565Channel(color, RGB565_G_MASK, RGB565_G_SHIFT), RGB565_G_BITS);
138 }
139 
RGB565ToB32(uint16_t color)140 static uint8_t RGB565ToB32(uint16_t color)
141 {
142     return RGB565To32(GetRGB565Channel(color, RGB565_B_MASK, RGB565_B_SHIFT), RGB565_B_BITS);
143 }
144 
145 /*
146  * For ARGB_8888
147  * 1. get A(8-bits)/R(8-bits)/G(8-bits)/B(8-bits) channel value form color value(uint32_t)
148  * 2. construct normalized color value with A(8-bits)/R(8-bits)/G(8-bits)/B(8-bits)
149  * 3. the normalized color format: (A << 24 | R << 16 | G << 8 | B << 0)
150  */
GetColorComp(uint32_t color,uint8_t shift)151 static uint8_t GetColorComp(uint32_t color, uint8_t shift)
152 {
153     return ((color) << (ARGB8888_CONVERT_BIT - shift)) >> ARGB8888_CONVERT_BIT;
154 }
155 
GetColorARGB(uint8_t a,uint8_t r,uint8_t g,uint8_t b)156 static uint32_t GetColorARGB(uint8_t a, uint8_t r, uint8_t g, uint8_t b)
157 {
158     return ((uint32_t)(a << ARGB_A_SHIFT) | (uint32_t)(r << ARGB_R_SHIFT)
159         | (uint32_t)(g << ARGB_G_SHIFT) | (uint32_t)(b << ARGB_B_SHIFT));
160 }
161 
162 static ImageInfo MakeImageInfo(int width, int height, PixelFormat pf, AlphaType at, ColorSpace cs = ColorSpace::SRGB)
163 {
164     ImageInfo info;
165     info.size.width = width;
166     info.size.height = height;
167     info.pixelFormat = pf;
168     info.alphaType = at;
169     info.colorSpace = cs;
170     return info;
171 }
172 
173 static bool CheckAshmemSize(const int &fd, const int32_t &bufferSize, bool isAstc = false)
174 {
175 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) &&!defined(ANDROID_PLATFORM)
176     if (fd < 0) {
177         return false;
178     }
179     int32_t ashmemSize = AshmemGetSize(fd);
180     return isAstc || bufferSize == ashmemSize;
181 #else
182     return false;
183 #endif
184 }
185 
ExpandRGBToRGBX(const uint8_t * srcPixels,int32_t srcBytes,std::unique_ptr<uint8_t[]> & dstPixels)186 static bool ExpandRGBToRGBX(const uint8_t* srcPixels, int32_t srcBytes, std::unique_ptr<uint8_t[]>& dstPixels)
187 {
188     if (srcPixels == nullptr) {
189         IMAGE_LOGE("[PixelMap] ExpandRGBToRGBX failed: srcPixels is null");
190         return false;
191     }
192     int64_t dstBytes = srcBytes / RGB_888_BYTES * ARGB_8888_BYTES;
193     if (srcBytes <= 0 || dstBytes > INT32_MAX) {
194         IMAGE_LOGE("[PixelMap] ExpandRGBToRGBX failed: byte count invalid or overflowed");
195         return false;
196     }
197 
198     dstPixels = std::make_unique<uint8_t[]>(dstBytes);
199     if (!PixelConvertAdapter::RGBToRGBx(srcPixels, dstPixels.get(), srcBytes)) {
200         IMAGE_LOGE("[PixelMap] ExpandRGBToRGBX failed: format conversion failed");
201         return false;
202     }
203     return true;
204 }
205 
ShrinkRGBXToRGB(const std::unique_ptr<AbsMemory> & srcMemory,std::unique_ptr<AbsMemory> & dstMemory)206 static bool ShrinkRGBXToRGB(const std::unique_ptr<AbsMemory>& srcMemory, std::unique_ptr<AbsMemory>& dstMemory)
207 {
208     size_t srcBytes = srcMemory->data.size;
209     if (srcBytes > INT32_MAX) {
210         IMAGE_LOGE("[PixelMap] ShrinkRGBXToRGB failed: byte count too large");
211         return false;
212     }
213     int32_t dstBytes = static_cast<int32_t>(srcBytes) / ARGB_8888_BYTES * RGB_888_BYTES;
214     MemoryData memoryData = {nullptr, dstBytes, "Shrink RGBX to RGB"};
215     memoryData.format = PixelFormat::RGB_888;
216     memoryData.usage = srcMemory->data.usage;
217     dstMemory = MemoryManager::CreateMemory(srcMemory->GetType(), memoryData);
218     if (dstMemory == nullptr) {
219         IMAGE_LOGE("[PixelMap] ShrinkRGBXToRGB failed: allocate memory failed");
220         return false;
221     }
222 
223     if (!PixelConvertAdapter::RGBxToRGB(static_cast<uint8_t*>(srcMemory->data.data),
224         static_cast<uint8_t*>(dstMemory->data.data), srcBytes)) {
225         IMAGE_LOGE("[PixelMap] ShrinkRGBXToRGB failed: format conversion failed");
226         dstMemory->Release();
227         return false;
228     }
229     return true;
230 }
231 } // namespace Media
232 } // namespace OHOS
233 
234 #endif // FRAMEWORKS_INNERKITSIMPL_COMMON_INCLUDE_PIXEL_MAP_UTILS_H
235