• 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_image.h"
17 
18 #include "src/core/SkAutoMalloc.h"
19 #include "src/core/SkReadBuffer.h"
20 #include "src/core/SkWriteBuffer.h"
21 #include "src/image/SkImage_Base.h"
22 
23 #include "draw/surface.h"
24 #include "image/bitmap.h"
25 #include "image/image.h"
26 #include "image/picture.h"
27 #include "utils/data.h"
28 #include "utils/log.h"
29 
30 #include "skia_bitmap.h"
31 #include "skia_data.h"
32 #include "skia_image_info.h"
33 #include "skia_pixmap.h"
34 #include "skia_surface.h"
35 #include "skia_texture_info.h"
36 #include "utils/system_properties.h"
37 
38 #ifdef ACE_ENABLE_GPU
39 #include "skia_gpu_context.h"
40 #endif
41 
42 namespace OHOS {
43 namespace Rosen {
44 namespace Drawing {
SkiaImage()45 SkiaImage::SkiaImage() noexcept : skiaImage_(nullptr) {}
46 
SkiaImage(sk_sp<SkImage> skImg)47 SkiaImage::SkiaImage(sk_sp<SkImage> skImg) noexcept : skiaImage_(skImg) {}
48 
MakeFromRaster(const Pixmap & pixmap,RasterReleaseProc rasterReleaseProc,ReleaseContext releaseContext)49 std::shared_ptr<Image> SkiaImage::MakeFromRaster(const Pixmap& pixmap,
50     RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
51 {
52     auto& skPixmap = pixmap.GetImpl<SkiaPixmap>()->ExportSkiaPixmap();
53     sk_sp<SkImage> skImage = SkImage::MakeFromRaster(skPixmap, rasterReleaseProc, releaseContext);
54     if (skImage == nullptr) {
55         LOGD("SkiaImage::MakeFromRaster failed");
56         return nullptr;
57     }
58     std::shared_ptr<ImageImpl> imageImpl = std::make_shared<SkiaImage>(skImage);
59     return std::make_shared<Image>(imageImpl);
60 }
61 
MakeRasterData(const ImageInfo & info,std::shared_ptr<Data> pixels,size_t rowBytes)62 std::shared_ptr<Image> SkiaImage::MakeRasterData(const ImageInfo& info, std::shared_ptr<Data> pixels,
63     size_t rowBytes)
64 {
65     if (pixels == nullptr) {
66         LOGD("SkiaImage::MakeRasterData pixels is nullptr");
67         return nullptr;
68     }
69     SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(info);
70     auto skData = pixels->GetImpl<SkiaData>()->GetSkData();
71 
72     sk_sp<SkImage> skImage = SkImage::MakeRasterData(skImageInfo, skData, rowBytes);
73     if (skImage == nullptr) {
74         LOGD("skImage nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
75         return nullptr;
76     }
77     std::shared_ptr<ImageImpl> imageImpl = std::make_shared<SkiaImage>(skImage);
78     return std::make_shared<Image>(imageImpl);
79 }
80 
BuildFromBitmap(const Bitmap & bitmap)81 bool SkiaImage::BuildFromBitmap(const Bitmap& bitmap)
82 {
83     auto skBitmapImpl = bitmap.GetImpl<SkiaBitmap>();
84     if (skBitmapImpl != nullptr) {
85         const SkBitmap skBitmap = skBitmapImpl->ExportSkiaBitmap();
86         skiaImage_ = SkImage::MakeFromBitmap(skBitmap);
87         return skiaImage_ != nullptr;
88     }
89     return false;
90 }
91 
92 #ifdef ACE_ENABLE_GPU
BuildFromBitmap(GPUContext & gpuContext,const Bitmap & bitmap)93 bool SkiaImage::BuildFromBitmap(GPUContext& gpuContext, const Bitmap& bitmap)
94 {
95     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
96     auto& skBitmap = bitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
97 
98     skiaImage_ = SkImage::MakeCrossContextFromPixmap(grContext_.get(), skBitmap.pixmap(), false);
99 
100     return (skiaImage_ != nullptr) ? true : false;
101 }
102 
MakeFromEncoded(const std::shared_ptr<Data> & data)103 bool SkiaImage::MakeFromEncoded(const std::shared_ptr<Data>& data)
104 {
105     if (data == nullptr) {
106         LOGD("SkiaImage::MakeFromEncoded failed, data is invalid");
107         return false;
108     }
109 
110     auto skData = data->GetImpl<SkiaData>()->GetSkData();
111     skiaImage_ = SkImage::MakeFromEncoded(skData);
112     return (skiaImage_ != nullptr);
113 }
114 
BuildSubset(const std::shared_ptr<Image> image,const RectI & rect,GPUContext & gpuContext)115 bool SkiaImage::BuildSubset(const std::shared_ptr<Image> image, const RectI& rect, GPUContext& gpuContext)
116 {
117     if (image == nullptr) {
118         LOGD("SkiaImage::BuildSubset failed, origin Image is invaild");
119         return false;
120     }
121     auto skiaImage = image->GetImpl<SkiaImage>()->GetImage();
122     auto skiaRect = SkIRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom());
123     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
124     skiaImage_ = skiaImage->makeSubset(skiaRect, grContext_.get());
125     return (skiaImage_ != nullptr) ? true : false;
126 }
127 
BuildFromCompressed(GPUContext & gpuContext,const std::shared_ptr<Data> & data,int width,int height,CompressedType type)128 bool SkiaImage::BuildFromCompressed(GPUContext& gpuContext, const std::shared_ptr<Data>& data, int width, int height,
129     CompressedType type)
130 {
131     if (data == nullptr) {
132         LOGD("SkiaImage::BuildFromCompressed, build failed, data is invalid");
133         return false;
134     }
135 
136     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
137     auto skData = data->GetImpl<SkiaData>()->GetSkData();
138 #ifdef NEW_SKIA
139     skiaImage_ = SkImage::MakeTextureFromCompressed(grContext_.get(),
140         skData, width, height, static_cast<SkImage::CompressionType>(type));
141 #else
142     skiaImage_ = SkImage::MakeFromCompressed(grContext_.get(),
143         skData, width, height, static_cast<SkImage::CompressionType>(type));
144 #endif
145     return (skiaImage_ != nullptr) ? true : false;
146 }
147 
BuildFromTexture(GPUContext & gpuContext,const TextureInfo & info,TextureOrigin origin,BitmapFormat bitmapFormat,const std::shared_ptr<ColorSpace> & colorSpace,void (* deleteFunc)(void *),void * cleanupHelper)148 bool SkiaImage::BuildFromTexture(GPUContext& gpuContext, const TextureInfo& info, TextureOrigin origin,
149     BitmapFormat bitmapFormat, const std::shared_ptr<ColorSpace>& colorSpace,
150     void (*deleteFunc)(void*), void* cleanupHelper)
151 {
152     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
153     if (!grContext_) {
154         LOGD("SkiaImage BuildFromTexture grContext_ is null");
155         return false;
156     }
157 
158     sk_sp<SkColorSpace> skColorSpace = nullptr;
159     if (colorSpace != nullptr) {
160         skColorSpace = colorSpace->GetImpl<SkiaColorSpace>()->GetColorSpace();
161     } else {
162         skColorSpace = SkColorSpace::MakeSRGB();
163     }
164 
165 #ifdef RS_ENABLE_VK
166     if (SystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
167         SystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
168         const auto& backendTexture = SkiaTextureInfo::ConvertToGrBackendTexture(info);
169         if (!backendTexture.isValid()) {
170             LOGD("SkiaImage BuildFromTexture backend texture is not valid!!!!");
171             return false;
172         }
173 
174         skiaImage_ = SkImage::MakeFromTexture(grContext_.get(), backendTexture,
175             SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin),
176             SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
177             SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace, deleteFunc, cleanupHelper);
178     } else {
179         skiaImage_ = SkImage::MakeFromTexture(grContext_.get(),  SkiaTextureInfo::ConvertToGrBackendTexture(info),
180             SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin),
181             SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
182             SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
183     }
184 #else
185     skiaImage_ = SkImage::MakeFromTexture(grContext_.get(),  SkiaTextureInfo::ConvertToGrBackendTexture(info),
186         SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin), SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
187         SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
188 #endif
189 
190     return (skiaImage_ != nullptr) ? true : false;
191 }
192 
BuildFromSurface(GPUContext & gpuContext,Surface & surface,TextureOrigin origin,BitmapFormat bitmapFormat,const std::shared_ptr<ColorSpace> & colorSpace)193 bool SkiaImage::BuildFromSurface(GPUContext& gpuContext, Surface& surface, TextureOrigin origin,
194     BitmapFormat bitmapFormat, const std::shared_ptr<ColorSpace>& colorSpace)
195 {
196     auto skSurface = surface.GetImpl<SkiaSurface>()->GetSkSurface();
197     if (!skSurface) {
198         LOGD("SkiaImage::BuildFromSurface skSurface is null");
199         return false;
200     }
201 
202     GrBackendTexture grBackendTexture
203             = skSurface->getBackendTexture(SkSurface::BackendHandleAccess::kFlushRead_BackendHandleAccess);
204     if (!grBackendTexture.isValid()) {
205         LOGD("SkiaImage::BuildFromSurface grBackendTexture is invalid");
206         return false;
207     }
208 
209     grContext_ = gpuContext.GetImpl<SkiaGPUContext>()->GetGrContext();
210 
211     sk_sp<SkColorSpace> skColorSpace = nullptr;
212     if (colorSpace != nullptr) {
213         skColorSpace = colorSpace->GetImpl<SkiaColorSpace>()->GetColorSpace();
214     }
215 
216     skiaImage_ = SkImage::MakeFromTexture(grContext_.get(), grBackendTexture,
217         SkiaTextureInfo::ConvertToGrSurfaceOrigin(origin), SkiaImageInfo::ConvertToSkColorType(bitmapFormat.colorType),
218         SkiaImageInfo::ConvertToSkAlphaType(bitmapFormat.alphaType), skColorSpace);
219     return (skiaImage_ != nullptr) ? true : false;
220 }
221 
SetGrBackendTexture(const GrBackendTexture & grBackendTexture)222 void SkiaImage::SetGrBackendTexture(const GrBackendTexture& grBackendTexture)
223 {
224     grBackendTexture_ = grBackendTexture;
225 }
226 
GetBackendTexture(bool flushPendingGrContextIO,TextureOrigin * origin)227 BackendTexture SkiaImage::GetBackendTexture(bool flushPendingGrContextIO, TextureOrigin* origin)
228 {
229     if (skiaImage_ == nullptr) {
230         LOGD("SkiaImage::GetBackendTexture, SkImage is nullptr!");
231         return BackendTexture(false); // invalid
232     }
233     GrBackendTexture skBackendTexture;
234     if (origin == nullptr) {
235         skBackendTexture =
236             skiaImage_->getBackendTexture(flushPendingGrContextIO);
237     } else {
238         GrSurfaceOrigin grOrigin = SkiaTextureInfo::ConvertToGrSurfaceOrigin(*origin);
239         skBackendTexture =
240             skiaImage_->getBackendTexture(flushPendingGrContextIO, &grOrigin);
241     }
242     if (!skBackendTexture.isValid()) {
243         LOGD("SkiaImage::GetBackendTexture, skBackendTexture is nullptr!");
244         return BackendTexture(false); // invalid
245     }
246     auto backendTexture = BackendTexture(true);
247     SetGrBackendTexture(skBackendTexture);
248 #ifdef RS_ENABLE_VK
249     if (SystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
250         SystemProperties::GetGpuApiType() == GpuApiType::DDGR) {
251         TextureInfo info;
252         SkiaTextureInfo::ConvertToVKTexture(skBackendTexture, info);
253         backendTexture.SetTextureInfo(info);
254     } else {
255         backendTexture.SetTextureInfo(SkiaTextureInfo::ConvertToTextureInfo(skBackendTexture));
256     }
257 #else
258     backendTexture.SetTextureInfo(SkiaTextureInfo::ConvertToTextureInfo(skBackendTexture));
259 #endif
260     return backendTexture;
261 }
262 
IsValid(GPUContext * context) const263 bool SkiaImage::IsValid(GPUContext* context) const
264 {
265     if (skiaImage_ == nullptr) {
266         LOGD("SkiaImage::IsValid, skiaImage_ is nullptr!");
267         return false;
268     }
269     if (context == nullptr) {
270         return skiaImage_->isValid(nullptr);
271     }
272     return skiaImage_->isValid(context->GetImpl<SkiaGPUContext>()->GetGrContext().get());
273 }
274 #endif
275 
AsLegacyBitmap(Bitmap & bitmap) const276 bool SkiaImage::AsLegacyBitmap(Bitmap& bitmap) const
277 {
278     if (skiaImage_ == nullptr) {
279         LOGD("SkiaImage::IsValid, skiaImage_ is nullptr!");
280         return false;
281     }
282     SkBitmap newBitmap;
283     if (!skiaImage_->asLegacyBitmap(&newBitmap)) {
284         LOGD("SkiaImage::AsLegacyBitmap failed!");
285         return false;
286     }
287     bitmap.GetImpl<SkiaBitmap>()->SetSkBitmap(newBitmap);
288     return true;
289 }
290 
GetWidth() const291 int SkiaImage::GetWidth() const
292 {
293     return (skiaImage_ == nullptr) ? 0 : skiaImage_->width();
294 }
295 
GetHeight() const296 int SkiaImage::GetHeight() const
297 {
298     return (skiaImage_ == nullptr) ? 0 : skiaImage_->height();
299 }
300 
GetColorType() const301 ColorType SkiaImage::GetColorType() const
302 {
303     return (skiaImage_ == nullptr) ? ColorType::COLORTYPE_UNKNOWN :
304                                      SkiaImageInfo::ConvertToColorType(skiaImage_->colorType());
305 }
306 
GetAlphaType() const307 AlphaType SkiaImage::GetAlphaType() const
308 {
309     return (skiaImage_ == nullptr) ? AlphaType::ALPHATYPE_UNKNOWN :
310                                      SkiaImageInfo::ConvertToAlphaType(skiaImage_->alphaType());
311 }
312 
GetColorSpace() const313 std::shared_ptr<ColorSpace> SkiaImage::GetColorSpace() const
314 {
315     if (skiaImage_ == nullptr) {
316         return nullptr;
317     }
318     sk_sp<SkColorSpace> skColorSpace = skiaImage_->refColorSpace();
319     if (skColorSpace == nullptr) {
320         return nullptr;
321     }
322     std::shared_ptr<ColorSpace> colorSpace = std::make_shared<ColorSpace>();
323     colorSpace->GetImpl<SkiaColorSpace>()->SetColorSpace(skColorSpace);
324     return colorSpace;
325 }
326 
GetUniqueID() const327 uint32_t SkiaImage::GetUniqueID() const
328 {
329     return (skiaImage_ == nullptr) ? 0 : skiaImage_->uniqueID();
330 }
331 
GetImageInfo()332 ImageInfo SkiaImage::GetImageInfo()
333 {
334     if (skiaImage_ == nullptr) {
335         return {};
336     }
337     return SkiaImageInfo::ConvertToRSImageInfo(skiaImage_->imageInfo());
338 }
339 
ReadPixels(Bitmap & bitmap,int x,int y)340 bool SkiaImage::ReadPixels(Bitmap& bitmap, int x, int y)
341 {
342     const auto& skBitmap = bitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
343     const auto& skPixmap = skBitmap.pixmap();
344 
345     return (skiaImage_ == nullptr) ? false : skiaImage_->readPixels(skPixmap, x, y);
346 }
347 
ReadPixels(Pixmap & pixmap,int x,int y)348 bool SkiaImage::ReadPixels(Pixmap& pixmap, int x, int y)
349 {
350     auto& skPixmap = pixmap.GetImpl<SkiaPixmap>()->ExportSkiaPixmap();
351     return (skiaImage_ == nullptr) ? false : skiaImage_->readPixels(skPixmap, x, y);
352 }
353 
ReadPixels(const ImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int32_t srcX,int32_t srcY) const354 bool SkiaImage::ReadPixels(const ImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
355     int32_t srcX, int32_t srcY) const
356 {
357     SkImageInfo skImageInfo = SkiaImageInfo::ConvertToSkImageInfo(dstInfo);
358     return (skiaImage_ == nullptr) ? false : skiaImage_->readPixels(skImageInfo, dstPixels, dstRowBytes, srcX, srcY);
359 }
360 
IsTextureBacked() const361 bool SkiaImage::IsTextureBacked() const
362 {
363     return (skiaImage_ == nullptr) ? false : skiaImage_->isTextureBacked();
364 }
365 
ScalePixels(const Bitmap & bitmap,const SamplingOptions & sampling,bool allowCachingHint) const366 bool SkiaImage::ScalePixels(const Bitmap& bitmap, const SamplingOptions& sampling, bool allowCachingHint) const
367 {
368     const auto& skBitmap = bitmap.GetImpl<SkiaBitmap>()->ExportSkiaBitmap();
369     const auto& skPixmap = skBitmap.pixmap();
370 
371     SkSamplingOptions samplingOptions;
372     if (sampling.GetUseCubic()) {
373         samplingOptions = SkSamplingOptions({ sampling.GetCubicCoffB(), sampling.GetCubicCoffC() });
374     } else {
375         samplingOptions = SkSamplingOptions(static_cast<SkFilterMode>(sampling.GetFilterMode()),
376             static_cast<SkMipmapMode>(sampling.GetMipmapMode()));
377     }
378 
379     SkImage::CachingHint skCachingHint;
380     if (allowCachingHint) {
381         skCachingHint = SkImage::CachingHint::kAllow_CachingHint;
382     } else {
383         skCachingHint = SkImage::CachingHint::kDisallow_CachingHint;
384     }
385 
386     return (skiaImage_ == nullptr) ? false : skiaImage_->scalePixels(skPixmap, samplingOptions, skCachingHint);
387 }
388 
EncodeToData(EncodedImageFormat encodedImageFormat,int quality) const389 std::shared_ptr<Data> SkiaImage::EncodeToData(EncodedImageFormat encodedImageFormat, int quality) const
390 {
391     if (skiaImage_ == nullptr) {
392         LOGD("SkiaImage::EncodeToData, skiaImage_ is null!");
393         return nullptr;
394     }
395     SkEncodedImageFormat skEncodedImageFormat = SkiaImageInfo::ConvertToSkEncodedImageFormat(encodedImageFormat);
396     auto skData = skiaImage_->encodeToData(skEncodedImageFormat, quality);
397     if (skData == nullptr) {
398         LOGD("SkiaImage::EncodeToData, skData null!");
399         return nullptr;
400     }
401     std::shared_ptr<Data> data = std::make_shared<Data>();
402     data->GetImpl<SkiaData>()->SetSkData(skData);
403     return data;
404 }
405 
IsLazyGenerated() const406 bool SkiaImage::IsLazyGenerated() const
407 {
408     return (skiaImage_ == nullptr) ? false : skiaImage_->isLazyGenerated();
409 }
410 
GetROPixels(Bitmap & bitmap) const411 bool SkiaImage::GetROPixels(Bitmap& bitmap) const
412 {
413     if (skiaImage_ == nullptr) {
414         LOGD("SkiaImage::GetROPixels, skiaImage_ is null!");
415         return false;
416     }
417     auto context = as_IB(skiaImage_.get())->directContext();
418     SkBitmap skiaBitmap;
419     if (!as_IB(skiaImage_.get())->getROPixels(context, &skiaBitmap)) {
420         LOGD("skiaImge getROPixels failed");
421         return false;
422     }
423     bitmap.GetImpl<SkiaBitmap>()->SetSkBitmap(skiaBitmap);
424     return true;
425 }
426 
MakeRasterImage() const427 std::shared_ptr<Image> SkiaImage::MakeRasterImage() const
428 {
429     if (skiaImage_ == nullptr) {
430         return nullptr;
431     }
432     sk_sp<SkImage> skImage = skiaImage_->makeRasterImage();
433     if (skImage == nullptr) {
434         LOGD("skImage nullptr, %{public}s, %{public}d", __FUNCTION__, __LINE__);
435         return nullptr;
436     }
437     std::shared_ptr<ImageImpl> imageImpl = std::make_shared<SkiaImage>(skImage);
438     return std::make_shared<Image>(imageImpl);
439 }
440 
CanPeekPixels() const441 bool SkiaImage::CanPeekPixels() const
442 {
443     SkPixmap pixmap;
444     if (skiaImage_ == nullptr || !skiaImage_->peekPixels(&pixmap)) {
445         return false;
446     }
447     return true;
448 }
449 
IsOpaque() const450 bool SkiaImage::IsOpaque() const
451 {
452     return (skiaImage_ == nullptr) ? false : skiaImage_->isOpaque();
453 }
454 
GetImage() const455 const sk_sp<SkImage> SkiaImage::GetImage() const
456 {
457     return skiaImage_;
458 }
459 
SetSkImage(const sk_sp<SkImage> & skImage)460 void SkiaImage::SetSkImage(const sk_sp<SkImage>& skImage)
461 {
462     skiaImage_ = skImage;
463 }
464 
465 #ifdef ACE_ENABLE_GPU
466 #ifdef NEW_SKIA
GetGrContext() const467 sk_sp<GrDirectContext> SkiaImage::GetGrContext() const
468 #else
469 sk_sp<GrContext> SkiaImage::GetGrContext() const
470 #endif
471 {
472     return grContext_;
473 }
474 #endif
475 
Serialize() const476 std::shared_ptr<Data> SkiaImage::Serialize() const
477 {
478     if (skiaImage_ == nullptr) {
479         LOGD("SkiaImage::Serialize, SkImage is nullptr!");
480         return nullptr;
481     }
482 
483     SkBinaryWriteBuffer writer;
484     bool type = skiaImage_->isLazyGenerated();
485     writer.writeBool(type);
486     if (type) {
487         writer.writeImage(skiaImage_.get());
488         size_t length = writer.bytesWritten();
489         std::shared_ptr<Data> data = std::make_shared<Data>();
490         data->BuildUninitialized(length);
491         writer.writeToMemory(data->WritableData());
492         return data;
493     } else {
494         SkBitmap bitmap;
495 
496         auto context = as_IB(skiaImage_.get())->directContext();
497         if (!as_IB(skiaImage_.get())->getROPixels(context, &bitmap)) {
498             LOGD("SkiaImage::SerializeNoLazyImage SkImage getROPixels failed");
499             return nullptr;
500         }
501         SkPixmap pixmap;
502         if (!bitmap.peekPixels(&pixmap)) {
503             LOGD("SkiaImage::SerializeNoLazyImage SkImage peekPixels failed");
504             return nullptr;
505         }
506         size_t rb = pixmap.rowBytes();
507         int32_t width = pixmap.width();
508         int32_t height = pixmap.height();
509         const void* addr = pixmap.addr();
510         size_t size = rb * static_cast<size_t>(height);
511 
512         writer.writeUInt(size);
513         writer.writeByteArray(addr, size);
514         writer.writeUInt(rb);
515         writer.write32(width);
516         writer.write32(height);
517 
518         writer.writeUInt(pixmap.colorType());
519         writer.writeUInt(pixmap.alphaType());
520 
521         if (pixmap.colorSpace() == nullptr) {
522             writer.writeUInt(0);
523         } else {
524             auto data = pixmap.colorSpace()->serialize();
525             writer.writeUInt(data->size());
526             writer.writeByteArray(data->data(), data->size());
527         }
528         size_t length = writer.bytesWritten();
529         std::shared_ptr<Data> data = std::make_shared<Data>();
530         data->BuildUninitialized(length);
531         writer.writeToMemory(data->WritableData());
532         return data;
533     }
534 }
535 
Deserialize(std::shared_ptr<Data> data)536 bool SkiaImage::Deserialize(std::shared_ptr<Data> data)
537 {
538     if (data == nullptr) {
539         LOGD("SkiaImage::Deserialize, data is invalid!");
540         return false;
541     }
542 
543     SkReadBuffer reader(data->GetData(), data->GetSize());
544     bool type = reader.readBool();
545 
546     if (type) {
547         skiaImage_ = reader.readImage();
548         return skiaImage_ != nullptr;
549     } else {
550         size_t pixmapSize = reader.readUInt();
551         SkAutoMalloc pixBuffer(pixmapSize);
552         if (!reader.readByteArray(pixBuffer.get(), pixmapSize)) {
553             return false;
554         }
555 
556         size_t rb = reader.readUInt();
557         int32_t width = reader.read32();
558         int32_t height = reader.read32();
559 
560         SkColorType colorType = static_cast<SkColorType>(reader.readUInt());
561         SkAlphaType alphaType = static_cast<SkAlphaType>(reader.readUInt());
562         sk_sp<SkColorSpace> colorSpace;
563 
564         size_t size = reader.readUInt();
565         if (size == 0) {
566             colorSpace = nullptr;
567         } else {
568             SkAutoMalloc colorBuffer(size);
569             if (!reader.readByteArray(colorBuffer.get(), size)) {
570                 return false;
571             }
572             colorSpace = SkColorSpace::Deserialize(colorBuffer.get(), size);
573         }
574 
575         SkImageInfo imageInfo = SkImageInfo::Make(width, height, colorType, alphaType, colorSpace);
576         auto skData = SkData::MakeWithCopy(const_cast<void*>(pixBuffer.get()), pixmapSize);
577         skiaImage_ = SkImage::MakeRasterData(imageInfo, skData, rb);
578         return true;
579     }
580 }
581 } // namespace Drawing
582 } // namespace Rosen
583 } // namespace OHOS
584