xref: /aosp_15_r20/external/skia/src/codec/SkCrabbyAvifCodec.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 SkEncodedImageFormat::kAVIF; }
59 
60     int onGetFrameCount() override;
61     bool onGetFrameInfo(int, FrameInfo*) const override;
62     int onGetRepetitionCount() override;
getFrameHolder()63     const SkFrameHolder* getFrameHolder() const override { return &fFrameHolder; }
64     bool conversionSupported(const SkImageInfo&, bool, bool) override;
65     bool onGetGainmapCodec(SkGainmapInfo* info, std::unique_ptr<SkCodec>* gainmapCodec) override;
66 
67 private:
68     SkCrabbyAvifCodec(SkEncodedInfo&&,
69                       std::unique_ptr<SkStream>,
70                       sk_sp<SkData>,
71                       AvifDecoder,
72                       SkEncodedOrigin,
73                       bool,
74                       bool);
75 
76     static std::unique_ptr<SkCodec> MakeFromData(std::unique_ptr<SkStream>,
77                                                  sk_sp<SkData>,
78                                                  Result*,
79                                                  bool gainmapOnly);
80 
81     // fAvifDecoder has a pointer to this data. This should not be freed until
82     // the decode is completed. To ensure that, we declare this before
83     // fAvifDecoder.
84     sk_sp<SkData> fData;
85 
86     AvifDecoder fAvifDecoder;
87     bool fUseAnimation;
88     bool fGainmapOnly;
89 
90     class Frame : public SkFrame {
91     public:
Frame(int i,SkEncodedInfo::Alpha alpha)92         Frame(int i, SkEncodedInfo::Alpha alpha) : SkFrame(i), fReportedAlpha(alpha) {}
93 
94     protected:
onReportedAlpha()95         SkEncodedInfo::Alpha onReportedAlpha() const override { return fReportedAlpha; }
96 
97     private:
98         const SkEncodedInfo::Alpha fReportedAlpha;
99     };
100 
101     class FrameHolder : public SkFrameHolder {
102     public:
~FrameHolder()103         ~FrameHolder() override {}
setScreenSize(int w,int h)104         void setScreenSize(int w, int h) {
105             fScreenWidth = w;
106             fScreenHeight = h;
107         }
108         Frame* appendNewFrame(bool hasAlpha);
109         const Frame* frame(int i) const;
size()110         int size() const { return static_cast<int>(fFrames.size()); }
reserve(int size)111         void reserve(int size) { fFrames.reserve(size); }
112 
113     protected:
114         const SkFrame* onGetFrame(int i) const override;
115 
116     private:
117         std::vector<Frame> fFrames;
118     };
119 
120     FrameHolder fFrameHolder;
121 };
122 
123 #endif  // SkCrabbyAvifCodec_DEFINED
124