1 /*
2 * Copyright (c) 2021-2023 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 "skia_bitmap.h"
17 #include "skia_pixmap.h"
18
19 #include "include/core/SkImageInfo.h"
20
21 #include "skia_image_info.h"
22
23 #include "image/bitmap.h"
24 #include "image/image.h"
25 #include "SkImagePriv.h"
26 #include "skia_image.h"
27 #include "src/core/SkAutoMalloc.h"
28 #include "src/core/SkReadBuffer.h"
29 #include "src/core/SkWriteBuffer.h"
30 #include "utils/data.h"
31 #include "utils/log.h"
32
33 namespace OHOS {
34 namespace Rosen {
35 namespace Drawing {
SkiaBitmap()36 SkiaBitmap::SkiaBitmap() : skiaBitmap_() {}
37
MakeSkImageInfo(const int width,const int height,const BitmapFormat & format,std::shared_ptr<Drawing::ColorSpace> colorSpace)38 static inline SkImageInfo MakeSkImageInfo(const int width, const int height,
39 const BitmapFormat& format, std::shared_ptr<Drawing::ColorSpace> colorSpace)
40 {
41 sk_sp<SkColorSpace> skColorSpace = nullptr;
42 if (colorSpace != nullptr) {
43 auto colorSpaceImpl = colorSpace->GetImpl<SkiaColorSpace>();
44 skColorSpace = colorSpaceImpl ? colorSpaceImpl->GetColorSpace() : nullptr;
45 }
46
47 auto imageInfo = SkImageInfo::Make(width, height,
48 SkiaImageInfo::ConvertToSkColorType(format.colorType),
49 SkiaImageInfo::ConvertToSkAlphaType(format.alphaType),
50 skColorSpace);
51 return imageInfo;
52 }
53
Build(int32_t width,int32_t height,const BitmapFormat & format,int32_t stride,std::shared_ptr<Drawing::ColorSpace> colorSpace)54 bool SkiaBitmap::Build(int32_t width, int32_t height, const BitmapFormat& format,
55 int32_t stride, std::shared_ptr<Drawing::ColorSpace> colorSpace)
56 {
57 auto imageInfo = MakeSkImageInfo(width, height, format, colorSpace);
58 bool isBuildSuccess = skiaBitmap_.setInfo(imageInfo, stride) && skiaBitmap_.tryAllocPixels();
59 if (!isBuildSuccess) {
60 LOGE("SkiaBitmap::Build failed, the format is incorrect");
61 return false;
62 }
63 return true;
64 }
65
Build(const ImageInfo & imageInfo,int32_t stride)66 bool SkiaBitmap::Build(const ImageInfo& imageInfo, int32_t stride)
67 {
68 auto skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(imageInfo);
69 bool isBuildSuccess = skiaBitmap_.setInfo(skImageInfo, stride) && skiaBitmap_.tryAllocPixels();
70 if (!isBuildSuccess) {
71 LOGE("SkiaBitmap::Build failed, the format is incorrect");
72 return false;
73 }
74 return true;
75 }
76
GetWidth() const77 int SkiaBitmap::GetWidth() const
78 {
79 return skiaBitmap_.width();
80 }
81
GetHeight() const82 int SkiaBitmap::GetHeight() const
83 {
84 return skiaBitmap_.height();
85 }
86
GetRowBytes() const87 int SkiaBitmap::GetRowBytes() const
88 {
89 return skiaBitmap_.rowBytes();
90 }
91
GetColorType() const92 ColorType SkiaBitmap::GetColorType() const
93 {
94 return SkiaImageInfo::ConvertToColorType(skiaBitmap_.colorType());
95 }
96
GetAlphaType() const97 AlphaType SkiaBitmap::GetAlphaType() const
98 {
99 return SkiaImageInfo::ConvertToAlphaType(skiaBitmap_.alphaType());
100 }
101
ExtractSubset(Bitmap & dst,const Rect & subset) const102 bool SkiaBitmap::ExtractSubset(Bitmap& dst, const Rect& subset) const
103 {
104 const SkBitmap& subBitmap = dst.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
105 SkIRect subRect = SkIRect::MakeLTRB(subset.GetLeft(), subset.GetTop(), subset.GetRight(), subset.GetBottom());
106 return skiaBitmap_.extractSubset(const_cast<SkBitmap*>(&subBitmap), subRect);
107 }
108
ReadPixels(const ImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int32_t srcX,int32_t srcY) const109 bool SkiaBitmap::ReadPixels(const ImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
110 int32_t srcX, int32_t srcY) const
111 {
112 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(dstInfo);
113 return skiaBitmap_.readPixels(skImageInfo, dstPixels, dstRowBytes, srcX, srcY);
114 }
115
GetPixels() const116 void* SkiaBitmap::GetPixels() const
117 {
118 return skiaBitmap_.getPixels();
119 }
120
SetPixels(void * pixels)121 void SkiaBitmap::SetPixels(void* pixels)
122 {
123 skiaBitmap_.setPixels(pixels);
124 }
125
InstallPixels(const ImageInfo & info,void * pixels,size_t rowBytes,ReleaseProc releaseProc,void * context)126 bool SkiaBitmap::InstallPixels(const ImageInfo& info, void* pixels, size_t rowBytes,
127 ReleaseProc releaseProc, void* context)
128 {
129 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(info);
130 return skiaBitmap_.installPixels(skImageInfo, pixels, rowBytes, releaseProc, context);
131 }
132
PeekPixels(Pixmap & pixmap) const133 bool SkiaBitmap::PeekPixels(Pixmap& pixmap) const
134 {
135 const SkPixmap& skiaPixmap = pixmap.GetImpl<SkiaPixmap>()->ExportSkiaPixmap();
136 return skiaBitmap_.peekPixels(const_cast<SkPixmap*>(&skiaPixmap));
137 }
138
ComputeByteSize() const139 size_t SkiaBitmap::ComputeByteSize() const
140 {
141 return skiaBitmap_.computeByteSize();
142 }
143
ExportSkiaBitmap() const144 const SkBitmap& SkiaBitmap::ExportSkiaBitmap() const
145 {
146 return skiaBitmap_;
147 }
148
CopyPixels(Bitmap & dst,int srcLeft,int srcTop) const149 void SkiaBitmap::CopyPixels(Bitmap& dst, int srcLeft, int srcTop) const
150 {
151 ImageInfo imageInfo = dst.GetImageInfo();
152 void* dstPixels = dst.GetPixels();
153
154 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(imageInfo);
155 int srcX = srcLeft;
156 int srcY = srcTop;
157
158 skiaBitmap_.readPixels(skImageInfo, dstPixels, dst.GetRowBytes(), srcX, srcY);
159 }
160
IsImmutable()161 bool SkiaBitmap::IsImmutable()
162 {
163 return skiaBitmap_.isImmutable();
164 }
165
SetImmutable()166 void SkiaBitmap::SetImmutable()
167 {
168 skiaBitmap_.setImmutable();
169 }
170
ClearWithColor(const ColorQuad & color) const171 void SkiaBitmap::ClearWithColor(const ColorQuad& color) const
172 {
173 SkColor skColor = static_cast<SkColor>(color);
174 skiaBitmap_.eraseColor(skColor);
175 }
176
GetColor(int x,int y) const177 ColorQuad SkiaBitmap::GetColor(int x, int y) const
178 {
179 SkColor color = skiaBitmap_.getColor(x, y);
180 return static_cast<ColorQuad>(color);
181 }
182
Free()183 void SkiaBitmap::Free()
184 {
185 skiaBitmap_.reset();
186 }
187
IsValid() const188 bool SkiaBitmap::IsValid() const
189 {
190 return skiaBitmap_.drawsNothing();
191 }
192
IsEmpty() const193 bool SkiaBitmap::IsEmpty() const
194 {
195 return skiaBitmap_.empty();
196 }
197
GetPixmap() const198 Pixmap SkiaBitmap::GetPixmap() const
199 {
200 SkPixmap skPixmap = skiaBitmap_.pixmap();
201 Pixmap pixmap;
202 pixmap.GetImpl<SkiaPixmap>()->ImportSkiaPixmap(skPixmap);
203 return pixmap;
204 }
205
MakeImage() const206 std::shared_ptr<Image> SkiaBitmap::MakeImage() const
207 {
208 SkBitmap skiaBitmap(skiaBitmap_);
209 sk_sp<SkImage> skiaImage = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
210 if (!skiaImage) {
211 return nullptr;
212 }
213 std::shared_ptr<Image> image = std::make_shared<Image>();
214 image->GetImpl<SkiaImage>()->SetSkImage(skiaImage);
215 return image;
216 }
217
SetInfo(const ImageInfo & info)218 void SkiaBitmap::SetInfo(const ImageInfo& info)
219 {
220 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(info);
221 skiaBitmap_.setInfo(skImageInfo);
222 }
223
TryAllocPixels(const ImageInfo & info)224 bool SkiaBitmap::TryAllocPixels(const ImageInfo& info)
225 {
226 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(info);
227 return skiaBitmap_.tryAllocPixels(skImageInfo);
228 }
229
SetSkBitmap(const SkBitmap & skBitmap)230 void SkiaBitmap::SetSkBitmap(const SkBitmap& skBitmap)
231 {
232 skiaBitmap_ = skBitmap;
233 }
234
GetSkBitmap()235 SkBitmap& SkiaBitmap::GetSkBitmap()
236 {
237 return skiaBitmap_;
238 }
239
Serialize() const240 std::shared_ptr<Data> SkiaBitmap::Serialize() const
241 {
242 SkBinaryWriteBuffer writer;
243 size_t rb = skiaBitmap_.rowBytes();
244 int width = skiaBitmap_.width();
245 int height = skiaBitmap_.height();
246 const void *addr = skiaBitmap_.pixmap().addr();
247 size_t pixmapSize = skiaBitmap_.computeByteSize();
248
249 writer.writeUInt(pixmapSize);
250 if (addr == nullptr) {
251 return nullptr;
252 }
253 writer.writeByteArray(addr, pixmapSize);
254
255 writer.writeUInt(rb);
256 writer.writeInt(width);
257 writer.writeInt(height);
258
259 writer.writeUInt(skiaBitmap_.colorType());
260 writer.writeUInt(skiaBitmap_.alphaType());
261
262 if (skiaBitmap_.colorSpace() == nullptr) {
263 writer.writeUInt(0);
264 } else {
265 auto skBitmapData = skiaBitmap_.colorSpace()->serialize();
266 if (skBitmapData == nullptr) {
267 writer.writeUInt(0);
268 } else {
269 writer.writeUInt(skBitmapData->size());
270 writer.writeByteArray(skBitmapData->data(), skBitmapData->size());
271 }
272 }
273 size_t length = writer.bytesWritten();
274 std::shared_ptr<Data> data = std::make_shared<Data>();
275 data->BuildUninitialized(length);
276 writer.writeToMemory(data->WritableData());
277 return data;
278 }
279
Deserialize(std::shared_ptr<Data> data)280 bool SkiaBitmap::Deserialize(std::shared_ptr<Data> data)
281 {
282 if (data == nullptr) {
283 return false;
284 }
285 SkReadBuffer reader(data->GetData(), data->GetSize());
286
287 size_t pixmapSize = reader.readUInt();
288 if (pixmapSize == 0) {
289 return false;
290 }
291 SkAutoMalloc pixBuffer(pixmapSize);
292 if (!reader.readByteArray(pixBuffer.get(), pixmapSize)) {
293 return false;
294 }
295
296 size_t rb = reader.readUInt();
297 int width = reader.readInt();
298 int height = reader.readInt();
299
300 SkColorType colorType = static_cast<SkColorType>(reader.readUInt());
301 SkAlphaType alphaType = static_cast<SkAlphaType>(reader.readUInt());
302 sk_sp<SkColorSpace> colorSpace;
303
304 size_t size = reader.readUInt();
305 if (size == 0) {
306 colorSpace = nullptr;
307 } else {
308 SkAutoMalloc colorBuffer(size);
309 if (!reader.readByteArray(colorBuffer.get(), size)) {
310 return false;
311 }
312 colorSpace = SkColorSpace::Deserialize(colorBuffer.get(), size);
313 }
314
315 SkImageInfo imageInfo = SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
316 auto releaseProc = [] (void* addr, void* context) -> void {
317 free(addr);
318 addr = nullptr;
319 };
320 skiaBitmap_.installPixels(imageInfo, const_cast<void*>(pixBuffer.release()), rb, releaseProc, nullptr);
321 return true;
322 }
323
GetImageInfo()324 ImageInfo SkiaBitmap::GetImageInfo()
325 {
326 return SkiaImageInfo::ConvertToRSImageInfo(skiaBitmap_.info());
327 }
328
329 } // namespace Drawing
330 } // namespace Rosen
331 } // namespace OHOS
332