1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2017 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 SkHeifCodec_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define SkHeifCodec_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkCodec.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkEncodedOrigin.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTemplates.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "src/codec/SkFrameHolder.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "src/codec/SkSwizzler.h" 18*c8dee2aaSAndroid Build Coastguard Worker 19*c8dee2aaSAndroid Build Coastguard Worker #if __has_include("HeifDecoderAPI.h") 20*c8dee2aaSAndroid Build Coastguard Worker #include "HeifDecoderAPI.h" 21*c8dee2aaSAndroid Build Coastguard Worker #else 22*c8dee2aaSAndroid Build Coastguard Worker #include "src/codec/SkStubHeifDecoderAPI.h" 23*c8dee2aaSAndroid Build Coastguard Worker #endif 24*c8dee2aaSAndroid Build Coastguard Worker 25*c8dee2aaSAndroid Build Coastguard Worker class SkHeifCodec : public SkCodec { 26*c8dee2aaSAndroid Build Coastguard Worker public: 27*c8dee2aaSAndroid Build Coastguard Worker /* 28*c8dee2aaSAndroid Build Coastguard Worker * Returns true if one of kHEIF or kAVIF images were detected. If |format| 29*c8dee2aaSAndroid Build Coastguard Worker * is not nullptr, it will contain the detected format. Returns false 30*c8dee2aaSAndroid Build Coastguard Worker * otherwise. 31*c8dee2aaSAndroid Build Coastguard Worker */ 32*c8dee2aaSAndroid Build Coastguard Worker static bool IsSupported(const void*, size_t, SkEncodedImageFormat* format); 33*c8dee2aaSAndroid Build Coastguard Worker 34*c8dee2aaSAndroid Build Coastguard Worker /* 35*c8dee2aaSAndroid Build Coastguard Worker * Assumes IsSupported was called and it returned a non-nullopt value. 36*c8dee2aaSAndroid Build Coastguard Worker */ 37*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkCodec> MakeFromStream( 38*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkStream>, SkCodec::SelectionPolicy selectionPolicy, 39*c8dee2aaSAndroid Build Coastguard Worker Result*); 40*c8dee2aaSAndroid Build Coastguard Worker 41*c8dee2aaSAndroid Build Coastguard Worker protected: 42*c8dee2aaSAndroid Build Coastguard Worker 43*c8dee2aaSAndroid Build Coastguard Worker Result onGetPixels( 44*c8dee2aaSAndroid Build Coastguard Worker const SkImageInfo& dstInfo, 45*c8dee2aaSAndroid Build Coastguard Worker void* dst, size_t dstRowBytes, 46*c8dee2aaSAndroid Build Coastguard Worker const Options& options, 47*c8dee2aaSAndroid Build Coastguard Worker int* rowsDecoded) override; 48*c8dee2aaSAndroid Build Coastguard Worker onGetEncodedFormat()49*c8dee2aaSAndroid Build Coastguard Worker SkEncodedImageFormat onGetEncodedFormat() const override { 50*c8dee2aaSAndroid Build Coastguard Worker return fFormat; 51*c8dee2aaSAndroid Build Coastguard Worker } 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 { 57*c8dee2aaSAndroid Build Coastguard Worker return &fFrameHolder; 58*c8dee2aaSAndroid Build Coastguard Worker } 59*c8dee2aaSAndroid Build Coastguard Worker 60*c8dee2aaSAndroid Build Coastguard Worker bool conversionSupported(const SkImageInfo&, bool, bool) override; 61*c8dee2aaSAndroid Build Coastguard Worker 62*c8dee2aaSAndroid Build Coastguard Worker bool onRewind() override; 63*c8dee2aaSAndroid Build Coastguard Worker 64*c8dee2aaSAndroid Build Coastguard Worker private: 65*c8dee2aaSAndroid Build Coastguard Worker /* 66*c8dee2aaSAndroid Build Coastguard Worker * Creates an instance of the decoder 67*c8dee2aaSAndroid Build Coastguard Worker * Called only by NewFromStream 68*c8dee2aaSAndroid Build Coastguard Worker */ 69*c8dee2aaSAndroid Build Coastguard Worker SkHeifCodec(SkEncodedInfo&&, HeifDecoder*, SkEncodedOrigin, bool animation, 70*c8dee2aaSAndroid Build Coastguard Worker SkEncodedImageFormat); 71*c8dee2aaSAndroid Build Coastguard Worker 72*c8dee2aaSAndroid Build Coastguard Worker void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options); 73*c8dee2aaSAndroid Build Coastguard Worker void allocateStorage(const SkImageInfo& dstInfo); 74*c8dee2aaSAndroid Build Coastguard Worker int readRows(const SkImageInfo& dstInfo, void* dst, 75*c8dee2aaSAndroid Build Coastguard Worker size_t rowBytes, int count, const Options&); 76*c8dee2aaSAndroid Build Coastguard Worker 77*c8dee2aaSAndroid Build Coastguard Worker /* 78*c8dee2aaSAndroid Build Coastguard Worker * Scanline decoding. 79*c8dee2aaSAndroid Build Coastguard Worker */ 80*c8dee2aaSAndroid Build Coastguard Worker SkSampler* getSampler(bool createIfNecessary) override; 81*c8dee2aaSAndroid Build Coastguard Worker Result onStartScanlineDecode(const SkImageInfo& dstInfo, 82*c8dee2aaSAndroid Build Coastguard Worker const Options& options) override; 83*c8dee2aaSAndroid Build Coastguard Worker int onGetScanlines(void* dst, int count, size_t rowBytes) override; 84*c8dee2aaSAndroid Build Coastguard Worker bool onSkipScanlines(int count) override; 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<HeifDecoder> fHeifDecoder; 87*c8dee2aaSAndroid Build Coastguard Worker HeifFrameInfo fFrameInfo; 88*c8dee2aaSAndroid Build Coastguard Worker skia_private::AutoTMalloc<uint8_t> fStorage; 89*c8dee2aaSAndroid Build Coastguard Worker uint8_t* fSwizzleSrcRow; 90*c8dee2aaSAndroid Build Coastguard Worker uint32_t* fColorXformSrcRow; 91*c8dee2aaSAndroid Build Coastguard Worker 92*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkSwizzler> fSwizzler; 93*c8dee2aaSAndroid Build Coastguard Worker bool fUseAnimation; 94*c8dee2aaSAndroid Build Coastguard Worker const SkEncodedImageFormat fFormat; 95*c8dee2aaSAndroid Build Coastguard Worker 96*c8dee2aaSAndroid Build Coastguard Worker class Frame : public SkFrame { 97*c8dee2aaSAndroid Build Coastguard Worker public: Frame(int i)98*c8dee2aaSAndroid Build Coastguard Worker Frame(int i) : INHERITED(i) {} 99*c8dee2aaSAndroid Build Coastguard Worker 100*c8dee2aaSAndroid Build Coastguard Worker protected: onReportedAlpha()101*c8dee2aaSAndroid Build Coastguard Worker SkEncodedInfo::Alpha onReportedAlpha() const override { 102*c8dee2aaSAndroid Build Coastguard Worker return SkEncodedInfo::Alpha::kOpaque_Alpha; 103*c8dee2aaSAndroid Build Coastguard Worker } 104*c8dee2aaSAndroid Build Coastguard Worker 105*c8dee2aaSAndroid Build Coastguard Worker private: 106*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = SkFrame; 107*c8dee2aaSAndroid Build Coastguard Worker }; 108*c8dee2aaSAndroid Build Coastguard Worker 109*c8dee2aaSAndroid Build Coastguard Worker class FrameHolder : public SkFrameHolder { 110*c8dee2aaSAndroid Build Coastguard Worker public: ~FrameHolder()111*c8dee2aaSAndroid Build Coastguard Worker ~FrameHolder() override {} setScreenSize(int w,int h)112*c8dee2aaSAndroid Build Coastguard Worker void setScreenSize(int w, int h) { 113*c8dee2aaSAndroid Build Coastguard Worker fScreenWidth = w; 114*c8dee2aaSAndroid Build Coastguard Worker fScreenHeight = h; 115*c8dee2aaSAndroid Build Coastguard Worker } 116*c8dee2aaSAndroid Build Coastguard Worker Frame* appendNewFrame(); 117*c8dee2aaSAndroid Build Coastguard Worker const Frame* frame(int i) const; 118*c8dee2aaSAndroid Build Coastguard Worker Frame* editFrameAt(int i); size()119*c8dee2aaSAndroid Build Coastguard Worker int size() const { 120*c8dee2aaSAndroid Build Coastguard Worker return static_cast<int>(fFrames.size()); 121*c8dee2aaSAndroid Build Coastguard Worker } reserve(int size)122*c8dee2aaSAndroid Build Coastguard Worker void reserve(int size) { 123*c8dee2aaSAndroid Build Coastguard Worker fFrames.reserve(size); 124*c8dee2aaSAndroid Build Coastguard Worker } 125*c8dee2aaSAndroid Build Coastguard Worker 126*c8dee2aaSAndroid Build Coastguard Worker protected: 127*c8dee2aaSAndroid Build Coastguard Worker const SkFrame* onGetFrame(int i) const override; 128*c8dee2aaSAndroid Build Coastguard Worker 129*c8dee2aaSAndroid Build Coastguard Worker private: 130*c8dee2aaSAndroid Build Coastguard Worker std::vector<Frame> fFrames; 131*c8dee2aaSAndroid Build Coastguard Worker }; 132*c8dee2aaSAndroid Build Coastguard Worker 133*c8dee2aaSAndroid Build Coastguard Worker FrameHolder fFrameHolder; 134*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = SkCodec; 135*c8dee2aaSAndroid Build Coastguard Worker }; 136*c8dee2aaSAndroid Build Coastguard Worker 137*c8dee2aaSAndroid Build Coastguard Worker #endif // SkHeifCodec_DEFINED 138