• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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