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 "include/codec/SkCodec.h"
12 #include "include/core/SkEncodedImageFormat.h"
13 #include "include/core/SkImageInfo.h"
14 #include "include/core/SkTypes.h"
15 #include "src/codec/SkFrameHolder.h"
16 #include "src/codec/SkScalingCodec.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 SkScalingCodec {
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;
onGetEncodedFormat()33     SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kWEBP; }
34 
35     bool onGetValidSubset(SkIRect* /* desiredSubset */) const override;
36 
37     int onGetFrameCount() override;
38     bool onGetFrameInfo(int, FrameInfo*) const override;
39     int onGetRepetitionCount() override;
40 
getFrameHolder()41     const SkFrameHolder* getFrameHolder() const override {
42         return &fFrameHolder;
43     }
44 
45 private:
46     SkWebpCodec(SkEncodedInfo&&, std::unique_ptr<SkStream>, WebPDemuxer*, sk_sp<SkData>,
47                 SkEncodedOrigin);
48 
49     SkAutoTCallVProc<WebPDemuxer, WebPDemuxDelete> fDemux;
50 
51     // fDemux has a pointer into this data.
52     // This should not be freed until the decode is completed.
53     sk_sp<SkData> fData;
54 
55     class Frame : public SkFrame {
56     public:
Frame(int i,SkEncodedInfo::Alpha alpha)57         Frame(int i, SkEncodedInfo::Alpha alpha)
58             : INHERITED(i)
59             , fReportedAlpha(alpha)
60         {}
61 
62     protected:
onReportedAlpha()63         SkEncodedInfo::Alpha onReportedAlpha() const override {
64             return fReportedAlpha;
65         }
66 
67     private:
68         const SkEncodedInfo::Alpha fReportedAlpha;
69 
70         typedef SkFrame INHERITED;
71     };
72 
73     class FrameHolder : public SkFrameHolder {
74     public:
~FrameHolder()75         ~FrameHolder() override {}
setScreenSize(int w,int h)76         void setScreenSize(int w, int h) {
77             fScreenWidth = w;
78             fScreenHeight = h;
79         }
80         Frame* appendNewFrame(bool hasAlpha);
81         const Frame* frame(int i) const;
size()82         int size() const {
83             return static_cast<int>(fFrames.size());
84         }
reserve(int size)85         void reserve(int size) {
86             fFrames.reserve(size);
87         }
88 
89     protected:
90         const SkFrame* onGetFrame(int i) const override;
91 
92     private:
93         std::vector<Frame> fFrames;
94     };
95 
96     FrameHolder fFrameHolder;
97     // Set to true if WebPDemuxGetFrame fails. This only means
98     // that we will cap the frame count to the frames that
99     // succeed.
100     bool        fFailed;
101 
102     typedef SkScalingCodec INHERITED;
103 };
104 #endif // SkWebpCodec_DEFINED
105