1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2022 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkAvifCodec_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define SkAvifCodec_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedImageFormat.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedOrigin.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkEncodedInfo.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "src/codec/SkFrameHolder.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "src/codec/SkScalingCodec.h" 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef> 20*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 21*c8dee2aaSAndroid Build Coastguard Worker #include <vector> 22*c8dee2aaSAndroid Build Coastguard Worker 23*c8dee2aaSAndroid Build Coastguard Worker class SkCodec; 24*c8dee2aaSAndroid Build Coastguard Worker class SkStream; 25*c8dee2aaSAndroid Build Coastguard Worker struct SkImageInfo; 26*c8dee2aaSAndroid Build Coastguard Worker struct avifDecoder; 27*c8dee2aaSAndroid Build Coastguard Worker struct AvifDecoderDeleter { 28*c8dee2aaSAndroid Build Coastguard Worker void operator()(avifDecoder* decoder) const; 29*c8dee2aaSAndroid Build Coastguard Worker }; 30*c8dee2aaSAndroid Build Coastguard Worker using AvifDecoder = std::unique_ptr<avifDecoder, AvifDecoderDeleter>; 31*c8dee2aaSAndroid Build Coastguard Worker 32*c8dee2aaSAndroid Build Coastguard Worker class SkAvifCodec : public SkScalingCodec { 33*c8dee2aaSAndroid Build Coastguard Worker public: 34*c8dee2aaSAndroid Build Coastguard Worker /* 35*c8dee2aaSAndroid Build Coastguard Worker * Returns true if an AVIF image is detected. Returns false otherwise. 36*c8dee2aaSAndroid Build Coastguard Worker */ 37*c8dee2aaSAndroid Build Coastguard Worker static bool IsAvif(const void*, size_t); 38*c8dee2aaSAndroid Build Coastguard Worker 39*c8dee2aaSAndroid Build Coastguard Worker /* 40*c8dee2aaSAndroid Build Coastguard Worker * Assumes IsAvif() was called and it returned true. 41*c8dee2aaSAndroid Build Coastguard Worker */ 42*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*); 43*c8dee2aaSAndroid Build Coastguard Worker 44*c8dee2aaSAndroid Build Coastguard Worker protected: 45*c8dee2aaSAndroid Build Coastguard Worker Result onGetPixels(const SkImageInfo& dstInfo, 46*c8dee2aaSAndroid Build Coastguard Worker void* dst, 47*c8dee2aaSAndroid Build Coastguard Worker size_t dstRowBytes, 48*c8dee2aaSAndroid Build Coastguard Worker const Options& options, 49*c8dee2aaSAndroid Build Coastguard Worker int* rowsDecoded) override; 50*c8dee2aaSAndroid Build Coastguard Worker onGetEncodedFormat()51*c8dee2aaSAndroid Build Coastguard Worker SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kAVIF; } 52*c8dee2aaSAndroid Build Coastguard Worker 53*c8dee2aaSAndroid Build Coastguard Worker int onGetFrameCount() override; 54*c8dee2aaSAndroid Build Coastguard Worker bool onGetFrameInfo(int, FrameInfo*) const override; 55*c8dee2aaSAndroid Build Coastguard Worker int onGetRepetitionCount() override; getFrameHolder()56*c8dee2aaSAndroid Build Coastguard Worker const SkFrameHolder* getFrameHolder() const override { return &fFrameHolder; } 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker private: 59*c8dee2aaSAndroid Build Coastguard Worker SkAvifCodec(SkEncodedInfo&&, 60*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStream>, 61*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData>, 62*c8dee2aaSAndroid Build Coastguard Worker AvifDecoder, 63*c8dee2aaSAndroid Build Coastguard Worker SkEncodedOrigin, 64*c8dee2aaSAndroid Build Coastguard Worker bool); 65*c8dee2aaSAndroid Build Coastguard Worker 66*c8dee2aaSAndroid Build Coastguard Worker // fAvifDecoder has a pointer to this data. This should not be freed until 67*c8dee2aaSAndroid Build Coastguard Worker // the decode is completed. To ensure that, we declare this before 68*c8dee2aaSAndroid Build Coastguard Worker // fAvifDecoder. 69*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> fData; 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard Worker AvifDecoder fAvifDecoder; 72*c8dee2aaSAndroid Build Coastguard Worker bool fUseAnimation; 73*c8dee2aaSAndroid Build Coastguard Worker 74*c8dee2aaSAndroid Build Coastguard Worker class Frame : public SkFrame { 75*c8dee2aaSAndroid Build Coastguard Worker public: Frame(int i,SkEncodedInfo::Alpha alpha)76*c8dee2aaSAndroid Build Coastguard Worker Frame(int i, SkEncodedInfo::Alpha alpha) : INHERITED(i), fReportedAlpha(alpha) {} 77*c8dee2aaSAndroid Build Coastguard Worker 78*c8dee2aaSAndroid Build Coastguard Worker protected: onReportedAlpha()79*c8dee2aaSAndroid Build Coastguard Worker SkEncodedInfo::Alpha onReportedAlpha() const override { return fReportedAlpha; } 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker private: 82*c8dee2aaSAndroid Build Coastguard Worker const SkEncodedInfo::Alpha fReportedAlpha; 83*c8dee2aaSAndroid Build Coastguard Worker 84*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = SkFrame; 85*c8dee2aaSAndroid Build Coastguard Worker }; 86*c8dee2aaSAndroid Build Coastguard Worker 87*c8dee2aaSAndroid Build Coastguard Worker class FrameHolder : public SkFrameHolder { 88*c8dee2aaSAndroid Build Coastguard Worker public: ~FrameHolder()89*c8dee2aaSAndroid Build Coastguard Worker ~FrameHolder() override {} setScreenSize(int w,int h)90*c8dee2aaSAndroid Build Coastguard Worker void setScreenSize(int w, int h) { 91*c8dee2aaSAndroid Build Coastguard Worker fScreenWidth = w; 92*c8dee2aaSAndroid Build Coastguard Worker fScreenHeight = h; 93*c8dee2aaSAndroid Build Coastguard Worker } 94*c8dee2aaSAndroid Build Coastguard Worker Frame* appendNewFrame(bool hasAlpha); 95*c8dee2aaSAndroid Build Coastguard Worker const Frame* frame(int i) const; size()96*c8dee2aaSAndroid Build Coastguard Worker int size() const { return static_cast<int>(fFrames.size()); } reserve(int size)97*c8dee2aaSAndroid Build Coastguard Worker void reserve(int size) { fFrames.reserve(size); } 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker protected: 100*c8dee2aaSAndroid Build Coastguard Worker const SkFrame* onGetFrame(int i) const override; 101*c8dee2aaSAndroid Build Coastguard Worker 102*c8dee2aaSAndroid Build Coastguard Worker private: 103*c8dee2aaSAndroid Build Coastguard Worker std::vector<Frame> fFrames; 104*c8dee2aaSAndroid Build Coastguard Worker }; 105*c8dee2aaSAndroid Build Coastguard Worker 106*c8dee2aaSAndroid Build Coastguard Worker FrameHolder fFrameHolder; 107*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = SkScalingCodec; 108*c8dee2aaSAndroid Build Coastguard Worker }; 109*c8dee2aaSAndroid Build Coastguard Worker 110*c8dee2aaSAndroid Build Coastguard Worker #endif // SkAvifCodec_DEFINED 111