1 /*
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 
8 #ifndef SkWebpCodec_DEFINED
9 #define SkWebpCodec_DEFINED
10 
11 #include "SkCodec.h"
12 #include "SkColorSpace.h"
13 #include "SkEncodedImageFormat.h"
14 #include "SkFrameHolder.h"
15 #include "SkImageInfo.h"
16 #include "SkTypes.h"
17 
18 #include <vector>
19 
20 class SkStream;
21 extern "C" {
22     struct WebPDemuxer;
23     void WebPDemuxDelete(WebPDemuxer* dmux);
24 }
25 
26 class SkWebpCodec final : public SkCodec {
27 public:
28     // Assumes IsWebp was called and returned true.
29     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
30     static bool IsWebp(const void*, size_t);
31 protected:
32     Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, int*) override;
33     SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kWEBP; }
34 
35     SkISize onGetScaledDimensions(float desiredScale) const override;
36 
37     bool onDimensionsSupported(const SkISize&) override;
38 
39     bool onGetValidSubset(SkIRect* /* desiredSubset */) const override;
40 
41     int onGetFrameCount() override;
42     bool onGetFrameInfo(int, FrameInfo*) const override;
43     int onGetRepetitionCount() override;
44 
45     const SkFrameHolder* getFrameHolder() const override {
46         return &fFrameHolder;
47     }
48 
49 private:
50     SkWebpCodec(int width, int height, const SkEncodedInfo&, sk_sp<SkColorSpace>,
51                 std::unique_ptr<SkStream>, WebPDemuxer*, sk_sp<SkData>, SkEncodedOrigin);
52 
53     SkAutoTCallVProc<WebPDemuxer, WebPDemuxDelete> fDemux;
54 
55     // fDemux has a pointer into this data.
56     // This should not be freed until the decode is completed.
57     sk_sp<SkData> fData;
58 
59     class Frame : public SkFrame {
60     public:
61         Frame(int i, SkEncodedInfo::Alpha alpha)
62             : INHERITED(i)
63             , fReportedAlpha(alpha)
64         {}
65         Frame(Frame&& other)
66             : INHERITED(other.frameId())
67             , fReportedAlpha(other.fReportedAlpha)
68         {}
69 
70     protected:
71         SkEncodedInfo::Alpha onReportedAlpha() const override {
72             return fReportedAlpha;
73         }
74 
75     private:
76         const SkEncodedInfo::Alpha fReportedAlpha;
77 
78         typedef SkFrame INHERITED;
79     };
80 
81     class FrameHolder : public SkFrameHolder {
82     public:
83         ~FrameHolder() override {}
84         void setScreenSize(int w, int h) {
85             fScreenWidth = w;
86             fScreenHeight = h;
87         }
88         Frame* appendNewFrame(bool hasAlpha);
89         const Frame* frame(int i) const;
90         int size() const {
91             return static_cast<int>(fFrames.size());
92         }
93         void reserve(int size) {
94             fFrames.reserve(size);
95         }
96 
97     protected:
98         const SkFrame* onGetFrame(int i) const override;
99 
100     private:
101         std::vector<Frame> fFrames;
102     };
103 
104     FrameHolder fFrameHolder;
105     // Set to true if WebPDemuxGetFrame fails. This only means
106     // that we will cap the frame count to the frames that
107     // succeed.
108     bool        fFailed;
109 
110     typedef SkCodec INHERITED;
111 };
112 #endif // SkWebpCodec_DEFINED
113