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 "SkCodecImageGenerator.h"
9 #include "SkMakeUnique.h"
10 #include "SkPixmapPriv.h"
11 #include "SkYUVAIndex.h"
12
MakeFromEncodedCodec(sk_sp<SkData> data)13 std::unique_ptr<SkImageGenerator> SkCodecImageGenerator::MakeFromEncodedCodec(sk_sp<SkData> data) {
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));
20 }
21
22 std::unique_ptr<SkImageGenerator>
MakeFromCodec(std::unique_ptr<SkCodec> codec)23 SkCodecImageGenerator::MakeFromCodec(std::unique_ptr<SkCodec> codec) {
24 return codec
25 ? std::unique_ptr<SkImageGenerator>(new SkCodecImageGenerator(std::move(codec), nullptr))
26 : nullptr;
27 }
28
adjust_info(SkCodec * codec)29 static SkImageInfo adjust_info(SkCodec* codec) {
30 SkImageInfo info = codec->getInfo();
31 if (kUnpremul_SkAlphaType == info.alphaType()) {
32 info = info.makeAlphaType(kPremul_SkAlphaType);
33 }
34 if (SkPixmapPriv::ShouldSwapWidthHeight(codec->getOrigin())) {
35 info = SkPixmapPriv::SwapWidthHeight(info);
36 }
37 return info;
38 }
39
SkCodecImageGenerator(std::unique_ptr<SkCodec> codec,sk_sp<SkData> data)40 SkCodecImageGenerator::SkCodecImageGenerator(std::unique_ptr<SkCodec> codec, sk_sp<SkData> data)
41 : INHERITED(adjust_info(codec.get()))
42 , fCodec(std::move(codec))
43 , fData(std::move(data))
44 {}
45
onRefEncodedData()46 sk_sp<SkData> SkCodecImageGenerator::onRefEncodedData() {
47 return fData;
48 }
49
onGetPixels(const SkImageInfo & requestInfo,void * requestPixels,size_t requestRowBytes,const Options &)50 bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& requestInfo, void* requestPixels,
51 size_t requestRowBytes, const Options&) {
52 SkPixmap dst(requestInfo, requestPixels, requestRowBytes);
53
54 auto decode = [this](const SkPixmap& pm) {
55 SkCodec::Result result = fCodec->getPixels(pm);
56 switch (result) {
57 case SkCodec::kSuccess:
58 case SkCodec::kIncompleteInput:
59 case SkCodec::kErrorInInput:
60 return true;
61 default:
62 return false;
63 }
64 };
65
66 return SkPixmapPriv::Orient(dst, fCodec->getOrigin(), decode);
67 }
68
onQueryYUVA8(SkYUVASizeInfo * sizeInfo,SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],SkYUVColorSpace * colorSpace) const69 bool SkCodecImageGenerator::onQueryYUVA8(SkYUVASizeInfo* sizeInfo,
70 SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
71 SkYUVColorSpace* colorSpace) const {
72 // This image generator always returns 3 separate non-interleaved planes
73 yuvaIndices[SkYUVAIndex::kY_Index].fIndex = 0;
74 yuvaIndices[SkYUVAIndex::kY_Index].fChannel = SkColorChannel::kR;
75 yuvaIndices[SkYUVAIndex::kU_Index].fIndex = 1;
76 yuvaIndices[SkYUVAIndex::kU_Index].fChannel = SkColorChannel::kR;
77 yuvaIndices[SkYUVAIndex::kV_Index].fIndex = 2;
78 yuvaIndices[SkYUVAIndex::kV_Index].fChannel = SkColorChannel::kR;
79 yuvaIndices[SkYUVAIndex::kA_Index].fIndex = -1;
80 yuvaIndices[SkYUVAIndex::kA_Index].fChannel = SkColorChannel::kR;
81
82 return fCodec->queryYUV8(sizeInfo, colorSpace);
83 }
84
onGetYUVA8Planes(const SkYUVASizeInfo & sizeInfo,const SkYUVAIndex indices[SkYUVAIndex::kIndexCount],void * planes[])85 bool SkCodecImageGenerator::onGetYUVA8Planes(const SkYUVASizeInfo& sizeInfo,
86 const SkYUVAIndex indices[SkYUVAIndex::kIndexCount],
87 void* planes[]) {
88 SkCodec::Result result = fCodec->getYUV8Planes(sizeInfo, planes);
89 // TODO: check indices
90
91 switch (result) {
92 case SkCodec::kSuccess:
93 case SkCodec::kIncompleteInput:
94 case SkCodec::kErrorInInput:
95 return true;
96 default:
97 return false;
98 }
99 }
100