• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/codec/SkCodecImageGenerator.h"
9 
10 #include "src/core/SkPixmapPriv.h"
11 
MakeFromEncodedCodec(sk_sp<SkData> data,std::optional<SkAlphaType> at)12 std::unique_ptr<SkImageGenerator> SkCodecImageGenerator::MakeFromEncodedCodec(
13         sk_sp<SkData> data, std::optional<SkAlphaType> at) {
14     auto codec = SkCodec::MakeFromData(data);
15     if (nullptr == codec) {
16         return nullptr;
17     }
18 
19     return std::unique_ptr<SkImageGenerator>(new SkCodecImageGenerator(std::move(codec), data, at));
20 }
21 
MakeFromCodec(std::unique_ptr<SkCodec> codec)22 std::unique_ptr<SkImageGenerator> SkCodecImageGenerator::MakeFromCodec(
23         std::unique_ptr<SkCodec> codec) {
24     return codec ? std::unique_ptr<SkImageGenerator>(
25                            new SkCodecImageGenerator(std::move(codec), nullptr, std::nullopt))
26                  : nullptr;
27 }
28 
adjust_info(SkCodec * codec,std::optional<SkAlphaType> at)29 static SkImageInfo adjust_info(SkCodec* codec, std::optional<SkAlphaType> at) {
30     SkASSERT(at != kOpaque_SkAlphaType);
31     SkImageInfo info = codec->getInfo();
32     if (at.has_value()) {
33         // If a specific alpha type was requested, use that.
34         info = info.makeAlphaType(*at);
35     } else if (kUnpremul_SkAlphaType == info.alphaType()) {
36         // Otherwise, prefer premul over unpremul (this produces better filtering in general)
37         info = info.makeAlphaType(kPremul_SkAlphaType);
38     }
39     if (SkEncodedOriginSwapsWidthHeight(codec->getOrigin())) {
40         info = SkPixmapPriv::SwapWidthHeight(info);
41     }
42     return info;
43 }
44 
SkCodecImageGenerator(std::unique_ptr<SkCodec> codec,sk_sp<SkData> data,std::optional<SkAlphaType> at)45 SkCodecImageGenerator::SkCodecImageGenerator(std::unique_ptr<SkCodec> codec,
46                                              sk_sp<SkData> data,
47                                              std::optional<SkAlphaType> at)
48         : INHERITED(adjust_info(codec.get(), at))
49         , fCodec(std::move(codec))
50         , fData(std::move(data)) {}
51 
onRefEncodedData()52 sk_sp<SkData> SkCodecImageGenerator::onRefEncodedData() {
53     return fData;
54 }
55 
getPixels(const SkImageInfo & info,void * pixels,size_t rowBytes,const SkCodec::Options * options)56 bool SkCodecImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const SkCodec::Options* options) {
57     SkPixmap dst(info, pixels, rowBytes);
58 
59     auto decode = [this, options](const SkPixmap& pm) {
60         SkCodec::Result result = fCodec->getPixels(pm, options);
61         switch (result) {
62             case SkCodec::kSuccess:
63             case SkCodec::kIncompleteInput:
64             case SkCodec::kErrorInInput:
65                 return true;
66             default:
67                 return false;
68         }
69     };
70 
71     return SkPixmapPriv::Orient(dst, fCodec->getOrigin(), decode);
72 }
73 
onGetPixels(const SkImageInfo & requestInfo,void * requestPixels,size_t requestRowBytes,const Options & options)74 bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& requestInfo, void* requestPixels,
75                                         size_t requestRowBytes, const Options& options) {
76     return this->getPixels(requestInfo, requestPixels, requestRowBytes, nullptr);
77 }
78 
onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes & supportedDataTypes,SkYUVAPixmapInfo * yuvaPixmapInfo) const79 bool SkCodecImageGenerator::onQueryYUVAInfo(
80         const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
81         SkYUVAPixmapInfo* yuvaPixmapInfo) const {
82     return fCodec->queryYUVAInfo(supportedDataTypes, yuvaPixmapInfo);
83 }
84 
onGetYUVAPlanes(const SkYUVAPixmaps & yuvaPixmaps)85 bool SkCodecImageGenerator::onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) {
86     switch (fCodec->getYUVAPlanes(yuvaPixmaps)) {
87         case SkCodec::kSuccess:
88         case SkCodec::kIncompleteInput:
89         case SkCodec::kErrorInInput:
90             return true;
91         default:
92             return false;
93     }
94 }
95 
getScaledDimensions(float desiredScale) const96 SkISize SkCodecImageGenerator::getScaledDimensions(float desiredScale) const {
97     SkISize size = fCodec->getScaledDimensions(desiredScale);
98     if (SkEncodedOriginSwapsWidthHeight(fCodec->getOrigin())) {
99         std::swap(size.fWidth, size.fHeight);
100     }
101     return size;
102 }
103