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
29class SkHeifCodec : public SkCodec {
30public:
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
38protected:
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
56private:
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