• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 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 #ifndef SkCrabbyAvifCodec_DEFINED
9 #define SkCrabbyAvifCodec_DEFINED
10 
11 #include "include/codec/SkEncodedImageFormat.h"
12 #include "include/codec/SkEncodedOrigin.h"
13 #include "include/core/SkData.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/private/SkEncodedInfo.h"
16 #include "src/codec/SkFrameHolder.h"
17 #include "src/codec/SkScalingCodec.h"
18 
19 #include <cstddef>
20 #include <memory>
21 #include <vector>
22 
23 namespace crabbyavif {
24 struct avifDecoder;
25 }  // namespace crabbyavif
26 
27 class SkCodec;
28 class SkStream;
29 struct SkImageInfo;
30 struct SkGainmapInfo;
31 
32 struct AvifDecoderDeleter {
33     void operator()(crabbyavif::avifDecoder* decoder) const;
34 };
35 using AvifDecoder = std::unique_ptr<crabbyavif::avifDecoder, AvifDecoderDeleter>;
36 
37 class SkCrabbyAvifCodec : public SkScalingCodec {
38 public:
39     /*
40      * Returns true if an AVIF image is detected. Returns false otherwise.
41      */
42     static bool IsAvif(const void*, size_t);
43 
44     /*
45      * Assumes IsAvif() was called and it returned true.
46      */
47     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>,
48                                                    Result*,
49                                                    bool gainmapOnly = false);
50 
51 protected:
52     Result onGetPixels(const SkImageInfo& dstInfo,
53                        void* dst,
54                        size_t dstRowBytes,
55                        const Options& options,
56                        int* rowsDecoded) override;
57 
onGetEncodedFormat()58     SkEncodedImageFormat onGetEncodedFormat() const override { return fFormat; }
59 
60     int onGetFrameCount() override;
61     bool onGetFrameInfo(int, FrameInfo*) const override;
62     int onGetRepetitionCount() override;
63     IsAnimated onIsAnimated() override;
getFrameHolder()64     const SkFrameHolder* getFrameHolder() const override { return &fFrameHolder; }
65     bool conversionSupported(const SkImageInfo&, bool, bool) override;
66     bool onGetGainmapCodec(SkGainmapInfo* info, std::unique_ptr<SkCodec>* gainmapCodec) override;
onGetValidSubset(SkIRect *)67     bool onGetValidSubset(SkIRect*) const override { return true; }
68 
69 private:
70     SkCrabbyAvifCodec(SkEncodedInfo&&,
71                       std::unique_ptr<SkStream>,
72                       sk_sp<SkData>,
73                       AvifDecoder,
74                       SkEncodedOrigin,
75                       bool,
76                       bool,
77                       SkEncodedImageFormat);
78 
79     static std::unique_ptr<SkCodec> MakeFromData(std::unique_ptr<SkStream>,
80                                                  sk_sp<SkData>,
81                                                  Result*,
82                                                  bool gainmapOnly);
83 
84     // fAvifDecoder has a pointer to this data. This should not be freed until
85     // the decode is completed. To ensure that, we declare this before
86     // fAvifDecoder.
87     sk_sp<SkData> fData;
88 
89     AvifDecoder fAvifDecoder;
90     bool fUseAnimation;
91     bool fGainmapOnly;
92     const SkEncodedImageFormat fFormat;
93 
94     class Frame : public SkFrame {
95     public:
Frame(int i,SkEncodedInfo::Alpha alpha)96         Frame(int i, SkEncodedInfo::Alpha alpha) : SkFrame(i), fReportedAlpha(alpha) {}
97 
98     protected:
onReportedAlpha()99         SkEncodedInfo::Alpha onReportedAlpha() const override { return fReportedAlpha; }
100 
101     private:
102         const SkEncodedInfo::Alpha fReportedAlpha;
103     };
104 
105     class FrameHolder : public SkFrameHolder {
106     public:
~FrameHolder()107         ~FrameHolder() override {}
setScreenSize(int w,int h)108         void setScreenSize(int w, int h) {
109             fScreenWidth = w;
110             fScreenHeight = h;
111         }
112         Frame* appendNewFrame(bool hasAlpha);
113         const Frame* frame(int i) const;
size()114         int size() const { return static_cast<int>(fFrames.size()); }
reserve(int size)115         void reserve(int size) { fFrames.reserve(size); }
116 
117     protected:
118         const SkFrame* onGetFrame(int i) const override;
119 
120     private:
121         std::vector<Frame> fFrames;
122     };
123 
124     FrameHolder fFrameHolder;
125 };
126 
127 #endif  // SkCrabbyAvifCodec_DEFINED
128