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