1 /*
2  * Copyright 2017 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 SkHeifCodec_DEFINED
9 #define SkHeifCodec_DEFINED
10 
11 #include "SkCodec.h"
12 #include "SkColorSpace.h"
13 #include "SkColorSpaceXform.h"
14 #include "SkEncodedOrigin.h"
15 #include "SkImageInfo.h"
16 #include "SkSwizzler.h"
17 #include "SkStream.h"
18 
19 #if !defined(__has_include)
20     #define __has_include(x) 0
21 #endif
22 
23 #if __has_include("HeifDecoderAPI.h")
24     #include "HeifDecoderAPI.h"
25 #else
26     #include "SkStubHeifDecoderAPI.h"
27 #endif
28 
29 class SkHeifCodec : public SkCodec {
30 public:
31     static bool IsHeif(const void*, size_t);
32 
33     /*
34      * Assumes IsHeif was called and returned true.
35      */
36     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
37 
38 protected:
39 
40     Result onGetPixels(
41             const SkImageInfo& dstInfo,
42             void* dst, size_t dstRowBytes,
43             const Options& options,
44             int* rowsDecoded) override;
45 
46     SkEncodedImageFormat onGetEncodedFormat() const override {
47         return SkEncodedImageFormat::kHEIF;
48     }
49 
50     bool conversionSupported(const SkImageInfo&, SkColorType, bool,
51                              const SkColorSpace*) const override {
52         // This class checks for conversion after creating colorXform.
53         return true;
54     }
55 
56 private:
57     /*
58      * Creates an instance of the decoder
59      * Called only by NewFromStream
60      */
61     SkHeifCodec(int width, int height, const SkEncodedInfo&,
62             HeifDecoder*, sk_sp<SkColorSpace>, SkEncodedOrigin);
63 
64     /*
65      * Checks if the conversion between the input image and the requested output
66      * image has been implemented.
67      *
68      * Sets the output color format.
69      */
70     bool setOutputColorFormat(const SkImageInfo& dst);
71 
72     void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
73     void allocateStorage(const SkImageInfo& dstInfo);
74     int readRows(const SkImageInfo& dstInfo, void* dst,
75             size_t rowBytes, int count, const Options&);
76 
77     /*
78      * Scanline decoding.
79      */
80     SkSampler* getSampler(bool createIfNecessary) override;
81     Result onStartScanlineDecode(const SkImageInfo& dstInfo,
82             const Options& options) override;
83     int onGetScanlines(void* dst, int count, size_t rowBytes) override;
84     bool onSkipScanlines(int count) override;
85 
86     std::unique_ptr<HeifDecoder>       fHeifDecoder;
87     HeifFrameInfo                      fFrameInfo;
88     SkAutoTMalloc<uint8_t>             fStorage;
89     uint8_t*                           fSwizzleSrcRow;
90     uint32_t*                          fColorXformSrcRow;
91 
92     std::unique_ptr<SkSwizzler>        fSwizzler;
93 
94     typedef SkCodec INHERITED;
95 };
96 
97 #endif // SkHeifCodec_DEFINED
98