• 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 "include/codec/SkEncodedOrigin.h"
11 #include "include/core/SkAlphaType.h"
12 #include "include/core/SkImageInfo.h"
13 #include "include/core/SkPixmap.h"
14 #include "include/core/SkTypes.h"
15 #include "src/codec/SkPixmapUtils.h"
16 
17 #include <utility>
18 
19 
MakeFromEncodedCodec(sk_sp<SkData> data,std::optional<SkAlphaType> at)20 std::unique_ptr<SkImageGenerator> SkCodecImageGenerator::MakeFromEncodedCodec(
21         sk_sp<SkData> data, std::optional<SkAlphaType> at) {
22     auto codec = SkCodec::MakeFromData(data);
23     if (nullptr == codec) {
24         return nullptr;
25     }
26 
27     return std::unique_ptr<SkImageGenerator>(new SkCodecImageGenerator(std::move(codec), data, at));
28 }
29 
MakeFromCodec(std::unique_ptr<SkCodec> codec)30 std::unique_ptr<SkImageGenerator> SkCodecImageGenerator::MakeFromCodec(
31         std::unique_ptr<SkCodec> codec) {
32     return codec ? std::unique_ptr<SkImageGenerator>(
33                            new SkCodecImageGenerator(std::move(codec), nullptr, std::nullopt))
34                  : nullptr;
35 }
36 
adjust_info(SkCodec * codec,std::optional<SkAlphaType> at)37 static SkImageInfo adjust_info(SkCodec* codec, std::optional<SkAlphaType> at) {
38     SkASSERT(at != kOpaque_SkAlphaType);
39     SkImageInfo info = codec->getInfo();
40     if (at.has_value()) {
41         // If a specific alpha type was requested, use that.
42         info = info.makeAlphaType(*at);
43     } else if (kUnpremul_SkAlphaType == info.alphaType()) {
44         // Otherwise, prefer premul over unpremul (this produces better filtering in general)
45         info = info.makeAlphaType(kPremul_SkAlphaType);
46     }
47     if (SkEncodedOriginSwapsWidthHeight(codec->getOrigin())) {
48         info = SkPixmapUtils::SwapWidthHeight(info);
49     }
50     return info;
51 }
52 
SkCodecImageGenerator(std::unique_ptr<SkCodec> codec,sk_sp<SkData> data,std::optional<SkAlphaType> at)53 SkCodecImageGenerator::SkCodecImageGenerator(std::unique_ptr<SkCodec> codec,
54                                              sk_sp<SkData> data,
55                                              std::optional<SkAlphaType> at)
56         : INHERITED(adjust_info(codec.get(), at))
57         , fCodec(std::move(codec))
58         , fData(std::move(data)) {}
59 
onRefEncodedData()60 sk_sp<SkData> SkCodecImageGenerator::onRefEncodedData() {
61     return fData;
62 }
63 
getPixels(const SkImageInfo & info,void * pixels,size_t rowBytes,const SkCodec::Options * options)64 bool SkCodecImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const SkCodec::Options* options) {
65     SkPixmap dst(info, pixels, rowBytes);
66 
67     auto decode = [this, options](const SkPixmap& pm) {
68         SkCodec::Result result = fCodec->getPixels(pm, options);
69         switch (result) {
70             case SkCodec::kSuccess:
71             case SkCodec::kIncompleteInput:
72             case SkCodec::kErrorInInput:
73                 return true;
74             default:
75                 return false;
76         }
77     };
78 
79     return SkPixmapUtils::Orient(dst, fCodec->getOrigin(), decode);
80 }
81 
onGetPixels(const SkImageInfo & requestInfo,void * requestPixels,size_t requestRowBytes,const Options & options)82 bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& requestInfo, void* requestPixels,
83                                         size_t requestRowBytes, const Options& options) {
84     return this->getPixels(requestInfo, requestPixels, requestRowBytes, nullptr);
85 }
86 
onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes & supportedDataTypes,SkYUVAPixmapInfo * yuvaPixmapInfo) const87 bool SkCodecImageGenerator::onQueryYUVAInfo(
88         const SkYUVAPixmapInfo::SupportedDataTypes& supportedDataTypes,
89         SkYUVAPixmapInfo* yuvaPixmapInfo) const {
90     return fCodec->queryYUVAInfo(supportedDataTypes, yuvaPixmapInfo);
91 }
92 
onGetYUVAPlanes(const SkYUVAPixmaps & yuvaPixmaps)93 bool SkCodecImageGenerator::onGetYUVAPlanes(const SkYUVAPixmaps& yuvaPixmaps) {
94     switch (fCodec->getYUVAPlanes(yuvaPixmaps)) {
95         case SkCodec::kSuccess:
96         case SkCodec::kIncompleteInput:
97         case SkCodec::kErrorInInput:
98             return true;
99         default:
100             return false;
101     }
102 }
103 
getScaledDimensions(float desiredScale) const104 SkISize SkCodecImageGenerator::getScaledDimensions(float desiredScale) const {
105     SkISize size = fCodec->getScaledDimensions(desiredScale);
106     if (SkEncodedOriginSwapsWidthHeight(fCodec->getOrigin())) {
107         std::swap(size.fWidth, size.fHeight);
108     }
109     return size;
110 }
111