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