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