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)38 static inline SkImageInfo MakeSkImageInfo(const int width, const int height, const BitmapFormat& format)
39 {
40 auto imageInfo = SkImageInfo::Make(width, height,
41 SkiaImageInfo::ConvertToSkColorType(format.colorType),
42 SkiaImageInfo::ConvertToSkAlphaType(format.alphaType));
43 return imageInfo;
44 }
45
Build(int32_t width,int32_t height,const BitmapFormat & format,int32_t stride)46 bool SkiaBitmap::Build(int32_t width, int32_t height, const BitmapFormat& format, int32_t stride)
47 {
48 auto imageInfo = MakeSkImageInfo(width, height, format);
49 bool isBuildSuccess = skiaBitmap_.setInfo(imageInfo, stride) && skiaBitmap_.tryAllocPixels();
50 if (!isBuildSuccess) {
51 LOGE("SkiaBitmap::Build failed, the format is incorrect");
52 return false;
53 }
54 return true;
55 }
56
Build(const ImageInfo & imageInfo,int32_t stride)57 bool SkiaBitmap::Build(const ImageInfo& imageInfo, int32_t stride)
58 {
59 auto skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(imageInfo);
60 bool isBuildSuccess = skiaBitmap_.setInfo(skImageInfo, stride) && skiaBitmap_.tryAllocPixels();
61 if (!isBuildSuccess) {
62 LOGE("SkiaBitmap::Build failed, the format is incorrect");
63 return false;
64 }
65 return true;
66 }
67
GetWidth() const68 int SkiaBitmap::GetWidth() const
69 {
70 return skiaBitmap_.width();
71 }
72
GetHeight() const73 int SkiaBitmap::GetHeight() const
74 {
75 return skiaBitmap_.height();
76 }
77
GetRowBytes() const78 int SkiaBitmap::GetRowBytes() const
79 {
80 return skiaBitmap_.rowBytes();
81 }
82
GetColorType() const83 ColorType SkiaBitmap::GetColorType() const
84 {
85 return SkiaImageInfo::ConvertToColorType(skiaBitmap_.colorType());
86 }
87
GetAlphaType() const88 AlphaType SkiaBitmap::GetAlphaType() const
89 {
90 return SkiaImageInfo::ConvertToAlphaType(skiaBitmap_.alphaType());
91 }
92
ExtractSubset(Bitmap & dst,const Rect & subset) const93 bool SkiaBitmap::ExtractSubset(Bitmap& dst, const Rect& subset) const
94 {
95 const SkBitmap& subBitmap = dst.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
96 SkIRect subRect = SkIRect::MakeLTRB(subset.GetLeft(), subset.GetTop(), subset.GetRight(), subset.GetBottom());
97 return skiaBitmap_.extractSubset(const_cast<SkBitmap*>(&subBitmap), subRect);
98 }
99
ReadPixels(const ImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int32_t srcX,int32_t srcY) const100 bool SkiaBitmap::ReadPixels(const ImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
101 int32_t srcX, int32_t srcY) const
102 {
103 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(dstInfo);
104 return skiaBitmap_.readPixels(skImageInfo, dstPixels, dstRowBytes, srcX, srcY);
105 }
106
GetPixels() const107 void* SkiaBitmap::GetPixels() const
108 {
109 return skiaBitmap_.getPixels();
110 }
111
SetPixels(void * pixels)112 void SkiaBitmap::SetPixels(void* pixels)
113 {
114 skiaBitmap_.setPixels(pixels);
115 }
116
InstallPixels(const ImageInfo & info,void * pixels,size_t rowBytes,ReleaseProc releaseProc,void * context)117 bool SkiaBitmap::InstallPixels(const ImageInfo& info, void* pixels, size_t rowBytes,
118 ReleaseProc releaseProc, void* context)
119 {
120 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(info);
121 return skiaBitmap_.installPixels(skImageInfo, pixels, rowBytes, releaseProc, context);
122 }
123
PeekPixels(Pixmap & pixmap) const124 bool SkiaBitmap::PeekPixels(Pixmap& pixmap) const
125 {
126 const SkPixmap& skiaPixmap = pixmap.GetImpl<SkiaPixmap>()->ExportSkiaPixmap();
127 return skiaBitmap_.peekPixels(const_cast<SkPixmap*>(&skiaPixmap));
128 }
129
ComputeByteSize() const130 size_t SkiaBitmap::ComputeByteSize() const
131 {
132 return skiaBitmap_.computeByteSize();
133 }
134
ExportSkiaBitmap() const135 const SkBitmap& SkiaBitmap::ExportSkiaBitmap() const
136 {
137 return skiaBitmap_;
138 }
139
CopyPixels(Bitmap & dst,int srcLeft,int srcTop) const140 void SkiaBitmap::CopyPixels(Bitmap& dst, int srcLeft, int srcTop) const
141 {
142 ImageInfo imageInfo = dst.GetImageInfo();
143 void* dstPixels = dst.GetPixels();
144
145 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(imageInfo);
146 int srcX = srcLeft;
147 int srcY = srcTop;
148
149 skiaBitmap_.readPixels(skImageInfo, dstPixels, dst.GetRowBytes(), srcX, srcY);
150 }
151
IsImmutable()152 bool SkiaBitmap::IsImmutable()
153 {
154 return skiaBitmap_.isImmutable();
155 }
156
SetImmutable()157 void SkiaBitmap::SetImmutable()
158 {
159 skiaBitmap_.setImmutable();
160 }
161
ClearWithColor(const ColorQuad & color) const162 void SkiaBitmap::ClearWithColor(const ColorQuad& color) const
163 {
164 SkColor skColor = static_cast<SkColor>(color);
165 skiaBitmap_.eraseColor(skColor);
166 }
167
GetColor(int x,int y) const168 ColorQuad SkiaBitmap::GetColor(int x, int y) const
169 {
170 SkColor color = skiaBitmap_.getColor(x, y);
171 return static_cast<ColorQuad>(color);
172 }
173
Free()174 void SkiaBitmap::Free()
175 {
176 skiaBitmap_.reset();
177 }
178
IsValid() const179 bool SkiaBitmap::IsValid() const
180 {
181 return skiaBitmap_.drawsNothing();
182 }
183
IsEmpty() const184 bool SkiaBitmap::IsEmpty() const
185 {
186 return skiaBitmap_.empty();
187 }
188
GetPixmap() const189 Pixmap SkiaBitmap::GetPixmap() const
190 {
191 SkPixmap skPixmap = skiaBitmap_.pixmap();
192 Pixmap pixmap;
193 pixmap.GetImpl<SkiaPixmap>()->ImportSkiaPixmap(skPixmap);
194 return pixmap;
195 }
196
MakeImage() const197 std::shared_ptr<Image> SkiaBitmap::MakeImage() const
198 {
199 SkBitmap skiaBitmap(skiaBitmap_);
200 sk_sp<SkImage> skiaImage = SkMakeImageFromRasterBitmap(skiaBitmap, kNever_SkCopyPixelsMode);
201 if (!skiaImage) {
202 return nullptr;
203 }
204 std::shared_ptr<Image> image = std::make_shared<Image>();
205 image->GetImpl<SkiaImage>()->SetSkImage(skiaImage);
206 return image;
207 }
208
SetInfo(const ImageInfo & info)209 void SkiaBitmap::SetInfo(const ImageInfo& info)
210 {
211 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(info);
212 skiaBitmap_.setInfo(skImageInfo);
213 }
214
TryAllocPixels(const ImageInfo & info)215 bool SkiaBitmap::TryAllocPixels(const ImageInfo& info)
216 {
217 SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(info);
218 return skiaBitmap_.tryAllocPixels(skImageInfo);
219 }
220
SetSkBitmap(const SkBitmap & skBitmap)221 void SkiaBitmap::SetSkBitmap(const SkBitmap& skBitmap)
222 {
223 skiaBitmap_ = skBitmap;
224 }
225
GetSkBitmap()226 SkBitmap& SkiaBitmap::GetSkBitmap()
227 {
228 return skiaBitmap_;
229 }
230
Serialize() const231 std::shared_ptr<Data> SkiaBitmap::Serialize() const
232 {
233 SkBinaryWriteBuffer writer;
234 size_t rb = skiaBitmap_.rowBytes();
235 int width = skiaBitmap_.width();
236 int height = skiaBitmap_.height();
237 const void *addr = skiaBitmap_.pixmap().addr();
238 size_t pixmapSize = skiaBitmap_.computeByteSize();
239
240 writer.writeUInt(pixmapSize);
241 if (addr == nullptr) {
242 return nullptr;
243 }
244 writer.writeByteArray(addr, pixmapSize);
245
246 writer.writeUInt(rb);
247 writer.writeInt(width);
248 writer.writeInt(height);
249
250 writer.writeUInt(skiaBitmap_.colorType());
251 writer.writeUInt(skiaBitmap_.alphaType());
252
253 if (skiaBitmap_.colorSpace() == nullptr) {
254 writer.writeUInt(0);
255 } else {
256 auto skBitmapData = skiaBitmap_.colorSpace()->serialize();
257 if (skBitmapData == nullptr) {
258 writer.writeUInt(0);
259 } else {
260 writer.writeUInt(skBitmapData->size());
261 writer.writeByteArray(skBitmapData->data(), skBitmapData->size());
262 }
263 }
264 size_t length = writer.bytesWritten();
265 std::shared_ptr<Data> data = std::make_shared<Data>();
266 data->BuildUninitialized(length);
267 writer.writeToMemory(data->WritableData());
268 return data;
269 }
270
Deserialize(std::shared_ptr<Data> data)271 bool SkiaBitmap::Deserialize(std::shared_ptr<Data> data)
272 {
273 if (data == nullptr) {
274 return false;
275 }
276 SkReadBuffer reader(data->GetData(), data->GetSize());
277
278 size_t pixmapSize = reader.readUInt();
279 if (pixmapSize == 0) {
280 return false;
281 }
282 SkAutoMalloc pixBuffer(pixmapSize);
283 if (!reader.readByteArray(pixBuffer.get(), pixmapSize)) {
284 return false;
285 }
286
287 size_t rb = reader.readUInt();
288 int width = reader.readInt();
289 int height = reader.readInt();
290
291 SkColorType colorType = static_cast<SkColorType>(reader.readUInt());
292 SkAlphaType alphaType = static_cast<SkAlphaType>(reader.readUInt());
293 sk_sp<SkColorSpace> colorSpace;
294
295 size_t size = reader.readUInt();
296 if (size == 0) {
297 colorSpace = nullptr;
298 } else {
299 SkAutoMalloc colorBuffer(size);
300 if (!reader.readByteArray(colorBuffer.get(), size)) {
301 return false;
302 }
303 colorSpace = SkColorSpace::Deserialize(colorBuffer.get(), size);
304 }
305
306 SkImageInfo imageInfo = SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
307 auto releaseProc = [] (void* addr, void* context) -> void {
308 free(addr);
309 addr = nullptr;
310 };
311 skiaBitmap_.installPixels(imageInfo, const_cast<void*>(pixBuffer.release()), rb, releaseProc, nullptr);
312 return true;
313 }
314
GetImageInfo()315 ImageInfo SkiaBitmap::GetImageInfo()
316 {
317 return SkiaImageInfo::ConvertToRSImageInfo(skiaBitmap_.info());
318 }
319
320 } // namespace Drawing
321 } // namespace Rosen
322 } // namespace OHOS
323