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