blob: 7a23c07a8a4ba38d725fa5c600ae76018e5f63db [file] [log] [blame]
msarettedd2dcf2016-01-14 13:12:26 -08001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/core/SkYUVAIndex.h"
9#include "src/codec/SkCodecImageGenerator.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "src/core/SkPixmapPriv.h"
Mike Reed43798692017-10-17 18:04:32 +000011
Mike Reed185130c2017-02-15 15:14:16 -050012std::unique_ptr<SkImageGenerator> SkCodecImageGenerator::MakeFromEncodedCodec(sk_sp<SkData> data) {
Mike Reedede7bac2017-07-23 15:30:02 -040013 auto codec = SkCodec::MakeFromData(data);
msarettedd2dcf2016-01-14 13:12:26 -080014 if (nullptr == codec) {
15 return nullptr;
16 }
17
Mike Reedede7bac2017-07-23 15:30:02 -040018 return std::unique_ptr<SkImageGenerator>(new SkCodecImageGenerator(std::move(codec), data));
msarettedd2dcf2016-01-14 13:12:26 -080019}
20
Florin Malitaf8776c22018-11-06 19:16:28 -050021std::unique_ptr<SkImageGenerator>
22SkCodecImageGenerator::MakeFromCodec(std::unique_ptr<SkCodec> codec) {
23 return codec
24 ? std::unique_ptr<SkImageGenerator>(new SkCodecImageGenerator(std::move(codec), nullptr))
25 : nullptr;
26}
27
Mike Reed43798692017-10-17 18:04:32 +000028static SkImageInfo adjust_info(SkCodec* codec) {
29 SkImageInfo info = codec->getInfo();
brianosman03707122016-04-21 08:48:18 -070030 if (kUnpremul_SkAlphaType == info.alphaType()) {
Mike Reed43798692017-10-17 18:04:32 +000031 info = info.makeAlphaType(kPremul_SkAlphaType);
herb4d1061c2016-04-15 12:57:42 -070032 }
Leon Scroggins III0cbc10f2017-10-30 09:07:53 -040033 if (SkPixmapPriv::ShouldSwapWidthHeight(codec->getOrigin())) {
34 info = SkPixmapPriv::SwapWidthHeight(info);
Mike Reed43798692017-10-17 18:04:32 +000035 }
36 return info;
msarettb714fb02016-01-22 14:46:42 -080037}
38
Mike Reedede7bac2017-07-23 15:30:02 -040039SkCodecImageGenerator::SkCodecImageGenerator(std::unique_ptr<SkCodec> codec, sk_sp<SkData> data)
Mike Reed43798692017-10-17 18:04:32 +000040 : INHERITED(adjust_info(codec.get()))
Mike Reedede7bac2017-07-23 15:30:02 -040041 , fCodec(std::move(codec))
reed42943c82016-09-12 12:01:44 -070042 , fData(std::move(data))
msarettedd2dcf2016-01-14 13:12:26 -080043{}
44
Ben Wagnerbdf54332018-05-15 14:12:14 -040045sk_sp<SkData> SkCodecImageGenerator::onRefEncodedData() {
46 return fData;
47}
msarettedd2dcf2016-01-14 13:12:26 -080048
Dan Field439709a2020-07-13 10:18:15 -070049bool SkCodecImageGenerator::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const SkCodec::Options* options) {
50 SkPixmap dst(info, pixels, rowBytes);
Mike Reed43798692017-10-17 18:04:32 +000051
Dan Field439709a2020-07-13 10:18:15 -070052 auto decode = [this, options](const SkPixmap& pm) {
53 SkCodec::Result result = fCodec->getPixels(pm, options);
Leon Scroggins III0cbc10f2017-10-30 09:07:53 -040054 switch (result) {
55 case SkCodec::kSuccess:
56 case SkCodec::kIncompleteInput:
57 case SkCodec::kErrorInInput:
58 return true;
59 default:
60 return false;
Mike Reed43798692017-10-17 18:04:32 +000061 }
Leon Scroggins III0cbc10f2017-10-30 09:07:53 -040062 };
Mike Reed43798692017-10-17 18:04:32 +000063
Leon Scroggins III0cbc10f2017-10-30 09:07:53 -040064 return SkPixmapPriv::Orient(dst, fCodec->getOrigin(), decode);
msarettedd2dcf2016-01-14 13:12:26 -080065}
66
Dan Field439709a2020-07-13 10:18:15 -070067bool SkCodecImageGenerator::onGetPixels(const SkImageInfo& requestInfo, void* requestPixels,
68 size_t requestRowBytes, const Options& options) {
69 return this->getPixels(requestInfo, requestPixels, requestRowBytes, nullptr);
70}
71
Jim Van Verthe24b5872018-10-29 16:26:02 -040072bool SkCodecImageGenerator::onQueryYUVA8(SkYUVASizeInfo* sizeInfo,
Jim Van Verth8f11e432018-10-18 14:36:59 -040073 SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
74 SkYUVColorSpace* colorSpace) const {
75 // This image generator always returns 3 separate non-interleaved planes
76 yuvaIndices[SkYUVAIndex::kY_Index].fIndex = 0;
77 yuvaIndices[SkYUVAIndex::kY_Index].fChannel = SkColorChannel::kR;
78 yuvaIndices[SkYUVAIndex::kU_Index].fIndex = 1;
79 yuvaIndices[SkYUVAIndex::kU_Index].fChannel = SkColorChannel::kR;
80 yuvaIndices[SkYUVAIndex::kV_Index].fIndex = 2;
81 yuvaIndices[SkYUVAIndex::kV_Index].fChannel = SkColorChannel::kR;
82 yuvaIndices[SkYUVAIndex::kA_Index].fIndex = -1;
83 yuvaIndices[SkYUVAIndex::kA_Index].fChannel = SkColorChannel::kR;
84
msarett4984c3c2016-03-10 05:44:43 -080085 return fCodec->queryYUV8(sizeInfo, colorSpace);
86}
msarettb714fb02016-01-22 14:46:42 -080087
Jim Van Verthe24b5872018-10-29 16:26:02 -040088bool SkCodecImageGenerator::onGetYUVA8Planes(const SkYUVASizeInfo& sizeInfo,
Jim Van Verth8f11e432018-10-18 14:36:59 -040089 const SkYUVAIndex indices[SkYUVAIndex::kIndexCount],
90 void* planes[]) {
msarettb714fb02016-01-22 14:46:42 -080091 SkCodec::Result result = fCodec->getYUV8Planes(sizeInfo, planes);
Jim Van Verth8f11e432018-10-18 14:36:59 -040092 // TODO: check indices
msarettb714fb02016-01-22 14:46:42 -080093
94 switch (result) {
95 case SkCodec::kSuccess:
96 case SkCodec::kIncompleteInput:
Leon Scroggins III674a1842017-07-06 12:26:09 -040097 case SkCodec::kErrorInInput:
msarettb714fb02016-01-22 14:46:42 -080098 return true;
99 default:
100 return false;
101 }
msarettedd2dcf2016-01-14 13:12:26 -0800102}
Brian Osmand9eb2192020-07-09 15:45:56 -0400103
104SkISize SkCodecImageGenerator::getScaledDimensions(float desiredScale) const {
105 SkISize size = fCodec->getScaledDimensions(desiredScale);
106 if (SkPixmapPriv::ShouldSwapWidthHeight(fCodec->getOrigin())) {
107 std::swap(size.fWidth, size.fHeight);
108 }
109 return size;
110}