• 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 #include <map>
17 #include "include/core/SkBitmap.h"
18 #include "include/core/SkCanvas.h"
19 #include "include/core/SkColor.h"
20 #include "include/core/SkColorSpace.h"
21 #include "include/core/SkImageInfo.h"
22 #include "include/core/SkPaint.h"
23 #include "include/core/SkPixmap.h"
24 #include "pixel_convert_adapter.h"
25 #ifdef _WIN32
26 #include <iomanip>
27 #endif
28 
29 namespace OHOS {
30 namespace Media {
31 using namespace OHOS::HiviewDFX;
32 using namespace std;
33 
34 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "PixelConvertAdapter" };
35 static const uint8_t NUM_0 = 0;
36 static const uint8_t NUM_1 = 1;
37 static const uint8_t NUM_2 = 2;
38 static const uint8_t NUM_3 = 3;
39 static const uint8_t NUM_4 = 4;
40 
41 static const map<PixelFormat, SkColorType> PIXEL_FORMAT_MAP = {
42     { PixelFormat::UNKNOWN, SkColorType::kUnknown_SkColorType},
43     { PixelFormat::ARGB_8888, SkColorType::kRGBA_8888_SkColorType},
44     { PixelFormat::ALPHA_8, SkColorType::kAlpha_8_SkColorType},
45     { PixelFormat::RGB_565, SkColorType::kRGB_565_SkColorType},
46     { PixelFormat::RGBA_F16, SkColorType::kRGBA_F16_SkColorType},
47     { PixelFormat::RGBA_8888, SkColorType::kRGBA_8888_SkColorType},
48     { PixelFormat::BGRA_8888, SkColorType::kBGRA_8888_SkColorType},
49     { PixelFormat::RGB_888, SkColorType::kRGB_888x_SkColorType},
50 };
51 
PixelFormatConvert(const PixelFormat & pixelFormat)52 static SkColorType PixelFormatConvert(const PixelFormat &pixelFormat)
53 {
54     auto formatSearch = PIXEL_FORMAT_MAP.find(pixelFormat);
55     return (formatSearch != PIXEL_FORMAT_MAP.end()) ? formatSearch->second : SkColorType::kUnknown_SkColorType;
56 }
57 
ARGBToRGBA(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)58 static void ARGBToRGBA(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
59 {
60     if (byteCount % NUM_4 != NUM_0) {
61         HiLog::Error(LABEL, "Pixel count must multiple of 4.");
62         return;
63     }
64     uint8_t *src = srcPixels;
65     uint8_t *dst = dstPixels;
66     for (uint32_t i = NUM_0 ; i < byteCount; i += NUM_4) {
67         // 0-R 1-G 2-B 3-A
68         dst[NUM_0] = src[NUM_1];
69         dst[NUM_1] = src[NUM_2];
70         dst[NUM_2] = src[NUM_3];
71         dst[NUM_3] = src[NUM_0];
72         src += NUM_4;
73         dst += NUM_4;
74     }
75 }
76 
RGBAToARGB(uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)77 static void RGBAToARGB(uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
78 {
79     if (byteCount % NUM_4 != NUM_0) {
80         HiLog::Error(LABEL, "Pixel count must multiple of 4.");
81         return;
82     }
83     uint8_t *src = srcPixels;
84     uint8_t *dst = dstPixels;
85     for (uint32_t i = NUM_0 ; i < byteCount; i += NUM_4) {
86         // 0-A 1-R 2-G 3-B
87         dst[NUM_0] = src[NUM_3];
88         dst[NUM_1] = src[NUM_0];
89         dst[NUM_2] = src[NUM_1];
90         dst[NUM_3] = src[NUM_2];
91         src += NUM_4;
92         dst += NUM_4;
93     }
94 }
95 
RGBxToRGB(const uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)96 static void RGBxToRGB(const uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
97 {
98     if (byteCount % NUM_4 != NUM_0) {
99         HiLog::Error(LABEL, "Pixel count must multiple of 4.");
100         return;
101     }
102     const uint8_t *src = srcPixels;
103     uint8_t *dst = dstPixels;
104     for (uint32_t i = NUM_0 ; i < byteCount; i += NUM_4) {
105         // 0-R 1-G 2-B
106         dst[NUM_0] = src[NUM_0];
107         dst[NUM_1] = src[NUM_1];
108         dst[NUM_2] = src[NUM_2];
109         src += NUM_4;
110         dst += NUM_3;
111     }
112 }
113 
RGBToRGBx(const uint8_t * srcPixels,uint8_t * dstPixels,uint32_t byteCount)114 static void RGBToRGBx(const uint8_t* srcPixels, uint8_t* dstPixels, uint32_t byteCount)
115 {
116     if (byteCount % NUM_3 != NUM_0) {
117         HiLog::Error(LABEL, "Pixel count must multiple of 3.");
118         return;
119     }
120     const uint8_t *src = srcPixels;
121     uint8_t *dst = dstPixels;
122     for (uint32_t i = NUM_0 ; i < byteCount; i += NUM_3) {
123         // 0-R 1-G 2-B
124         dst[NUM_0] = src[NUM_0];
125         dst[NUM_1] = src[NUM_1];
126         dst[NUM_2] = src[NUM_2];
127         dst[NUM_3] = 0;
128         src += NUM_3;
129         dst += NUM_4;
130     }
131 }
132 
GetRGBxRowBytes(const ImageInfo & imgInfo)133 static int32_t GetRGBxRowBytes(const ImageInfo &imgInfo)
134 {
135     return imgInfo.size.width * NUM_4;
136 }
137 
GetRGBxSize(const ImageInfo & imgInfo)138 static int32_t GetRGBxSize(const ImageInfo &imgInfo)
139 {
140     return imgInfo.size.height * GetRGBxRowBytes(imgInfo);
141 }
142 
WritePixelsConvert(const void * srcPixels,uint32_t srcRowBytes,const ImageInfo & srcInfo,void * dstPixels,const Position & dstPos,uint32_t dstRowBytes,const ImageInfo & dstInfo)143 bool PixelConvertAdapter::WritePixelsConvert(const void *srcPixels, uint32_t srcRowBytes, const ImageInfo &srcInfo,
144                                              void *dstPixels, const Position &dstPos, uint32_t dstRowBytes,
145                                              const ImageInfo &dstInfo)
146 {
147     // basic valid check, other parameters valid check in writePixels method
148     if (srcPixels == nullptr || dstPixels == nullptr) {
149         HiLog::Error(LABEL, "src or dst pixels invalid.");
150         return false;
151     }
152 
153     SkAlphaType srcAlphaType = static_cast<SkAlphaType>(srcInfo.alphaType);
154     SkAlphaType dstAlphaType = static_cast<SkAlphaType>(dstInfo.alphaType);
155     SkColorType srcColorType = PixelFormatConvert(srcInfo.pixelFormat);
156     SkColorType dstColorType = PixelFormatConvert(dstInfo.pixelFormat);
157     SkImageInfo srcImageInfo = SkImageInfo::Make(srcInfo.size.width, srcInfo.size.height, srcColorType, srcAlphaType);
158     SkImageInfo dstImageInfo = SkImageInfo::Make(dstInfo.size.width, dstInfo.size.height, dstColorType, dstAlphaType);
159 
160     int32_t dstRGBxSize = (dstInfo.pixelFormat == PixelFormat::RGB_888) ? GetRGBxSize(dstInfo) : NUM_1;
161     auto dstRGBxPixels = std::make_unique<uint8_t[]>(dstRGBxSize);
162     auto keepDstPixels = dstPixels;
163     dstPixels = (dstInfo.pixelFormat == PixelFormat::RGB_888) ? &dstRGBxPixels[0] : dstPixels;
164     dstRowBytes = (dstInfo.pixelFormat == PixelFormat::RGB_888) ? GetRGBxRowBytes(dstInfo) : dstRowBytes;
165 
166     int32_t srcRGBxSize = (srcInfo.pixelFormat == PixelFormat::RGB_888) ? GetRGBxSize(srcInfo) : NUM_1;
167     auto srcRGBxPixels = std::make_unique<uint8_t[]>(srcRGBxSize);
168     if (srcInfo.pixelFormat == PixelFormat::RGB_888) {
169         RGBToRGBx(static_cast<const uint8_t*>(srcPixels), &srcRGBxPixels[0], srcRowBytes * srcInfo.size.height);
170         srcPixels = &srcRGBxPixels[0];
171         srcRowBytes = GetRGBxRowBytes(srcInfo);
172     }
173     SkPixmap srcPixmap(srcImageInfo, srcPixels, srcRowBytes);
174     if (srcInfo.pixelFormat == PixelFormat::ARGB_8888) {
175         uint8_t* src = static_cast<uint8_t*>(srcPixmap.writable_addr());
176         ARGBToRGBA(src, src, srcRowBytes * srcInfo.size.height);
177     }
178 
179     SkBitmap dstBitmap;
180     if (!dstBitmap.installPixels(dstImageInfo, dstPixels, dstRowBytes)) {
181         HiLog::Error(LABEL, "WritePixelsConvert dst bitmap install pixels failed.");
182         return false;
183     }
184     if (!dstBitmap.writePixels(srcPixmap, dstPos.x, dstPos.y)) {
185         HiLog::Error(LABEL, "WritePixelsConvert dst bitmap write pixels by source failed.");
186         return false;
187     }
188 
189     if (dstInfo.pixelFormat == PixelFormat::ARGB_8888) {
190         uint32_t dstSize = dstRowBytes * dstInfo.size.height;
191         RGBAToARGB(static_cast<uint8_t*>(dstPixels), static_cast<uint8_t*>(dstPixels), dstSize);
192     } else if (dstInfo.pixelFormat == PixelFormat::RGB_888) {
193         RGBxToRGB(&dstRGBxPixels[0], static_cast<uint8_t*>(keepDstPixels), dstRGBxSize);
194     }
195 
196     return true;
197 }
198 
ReadPixelsConvert(const void * srcPixels,const Position & srcPos,uint32_t srcRowBytes,const ImageInfo & srcInfo,void * dstPixels,uint32_t dstRowBytes,const ImageInfo & dstInfo)199 bool PixelConvertAdapter::ReadPixelsConvert(const void *srcPixels, const Position &srcPos, uint32_t srcRowBytes,
200                                             const ImageInfo &srcInfo, void *dstPixels, uint32_t dstRowBytes,
201                                             const ImageInfo &dstInfo)
202 {
203     // basic valid check, other parameters valid check in readPixels method
204     if (srcPixels == nullptr || dstPixels == nullptr) {
205         HiLog::Error(LABEL, "src or dst pixels invalid.");
206         return false;
207     }
208     SkAlphaType srcAlphaType = static_cast<SkAlphaType>(srcInfo.alphaType);
209     SkAlphaType dstAlphaType = static_cast<SkAlphaType>(dstInfo.alphaType);
210     SkColorType srcColorType = PixelFormatConvert(srcInfo.pixelFormat);
211     SkColorType dstColorType = PixelFormatConvert(dstInfo.pixelFormat);
212     SkImageInfo srcImageInfo = SkImageInfo::Make(srcInfo.size.width, srcInfo.size.height, srcColorType, srcAlphaType);
213     SkImageInfo dstImageInfo = SkImageInfo::Make(dstInfo.size.width, dstInfo.size.height, dstColorType, dstAlphaType);
214 
215     SkBitmap srcBitmap;
216     if (!srcBitmap.installPixels(srcImageInfo, const_cast<void *>(srcPixels), srcRowBytes)) {
217         HiLog::Error(LABEL, "ReadPixelsConvert src bitmap install pixels failed.");
218         return false;
219     }
220     if (!srcBitmap.readPixels(dstImageInfo, dstPixels, dstRowBytes, srcPos.x, srcPos.y)) {
221         HiLog::Error(LABEL, "ReadPixelsConvert read dst pixels from source failed.");
222         return false;
223     }
224     return true;
225 }
226 
EraseBitmap(const void * srcPixels,uint32_t srcRowBytes,const ImageInfo & srcInfo,uint32_t color)227 bool PixelConvertAdapter::EraseBitmap(const void *srcPixels, uint32_t srcRowBytes, const ImageInfo &srcInfo,
228                                       uint32_t color)
229 {
230     if (srcPixels == nullptr) {
231         HiLog::Error(LABEL, "srcPixels is null.");
232         return false;
233     }
234     SkAlphaType srcAlphaType = static_cast<SkAlphaType>(srcInfo.alphaType);
235     SkColorType srcColorType = PixelFormatConvert(srcInfo.pixelFormat);
236     SkImageInfo srcImageInfo = SkImageInfo::Make(srcInfo.size.width, srcInfo.size.height, srcColorType, srcAlphaType);
237     SkBitmap srcBitmap;
238     if (!srcBitmap.installPixels(srcImageInfo, const_cast<void *>(srcPixels), srcRowBytes)) {
239         HiLog::Error(LABEL, "ReadPixelsConvert src bitmap install pixels failed.");
240         return false;
241     }
242     const SkColor4f skColor = SkColor4f::FromColor(color);
243     SkPaint paint;
244     paint.setColor4f(skColor, SkColorSpace::MakeSRGB().get());
245     paint.setBlendMode(SkBlendMode::kSrc);
246     SkCanvas canvas(srcBitmap);
247     canvas.drawPaint(paint);
248     return true;
249 }
250 } // namespace Media
251 } // namespace OHOS
252