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 #ifndef SkIcoCodec_DEFINED
8 #define SkIcoCodec_DEFINED
9 
10 #include "include/codec/SkCodec.h"
11 #include "include/core/SkImageInfo.h"
12 #include "include/core/SkStream.h"
13 #include "include/core/SkTypes.h"
14 #include "include/private/SkTArray.h"
15 
16 /*
17  * This class implements the decoding for bmp images
18  */
19 class SkIcoCodec : public SkCodec {
20 public:
21     static bool IsIco(const void*, size_t);
22 
23     /*
24      * Assumes IsIco was called and returned true
25      * Creates an Ico decoder
26      * Reads enough of the stream to determine the image format
27      */
28     static std::unique_ptr<SkCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);
29 
30 protected:
31 
32     /*
33      * Chooses the best dimensions given the desired scale
34      */
35     SkISize onGetScaledDimensions(float desiredScale) const override;
36 
37     bool onDimensionsSupported(const SkISize&) override;
38 
39     /*
40      * Initiates the Ico decode
41      */
42     Result onGetPixels(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, const Options&,
43             int*) override;
44 
onGetEncodedFormat()45     SkEncodedImageFormat onGetEncodedFormat() const override {
46         return SkEncodedImageFormat::kICO;
47     }
48 
49     SkScanlineOrder onGetScanlineOrder() const override;
50 
conversionSupported(const SkImageInfo &,bool,bool)51     bool conversionSupported(const SkImageInfo&, bool, bool) override {
52         // This will be checked by the embedded codec.
53         return true;
54     }
55 
56     // Handled by the embedded codec.
usesColorXform()57     bool usesColorXform() const override { return false; }
58 private:
59 
60     Result onStartScanlineDecode(const SkImageInfo& dstInfo,
61             const SkCodec::Options& options) override;
62 
63     int onGetScanlines(void* dst, int count, size_t rowBytes) override;
64 
65     bool onSkipScanlines(int count) override;
66 
67     Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes,
68             const SkCodec::Options&) override;
69 
70     Result onIncrementalDecode(int* rowsDecoded) override;
71 
72     SkSampler* getSampler(bool createIfNecessary) override;
73 
74     /*
75      * Searches fEmbeddedCodecs for a codec that matches requestedSize.
76      * The search starts at startIndex and ends when an appropriate codec
77      * is found, or we have reached the end of the array.
78      *
79      * @return the index of the matching codec or -1 if there is no
80      *         matching codec between startIndex and the end of
81      *         the array.
82      */
83     int chooseCodec(const SkISize& requestedSize, int startIndex);
84 
85     /*
86      * Constructor called by NewFromStream
87      * @param embeddedCodecs codecs for the embedded images, takes ownership
88      */
89     SkIcoCodec(SkEncodedInfo&& info, SkTArray<std::unique_ptr<SkCodec>, true>* embeddedCodecs);
90 
91     std::unique_ptr<SkTArray<std::unique_ptr<SkCodec>, true>> fEmbeddedCodecs;
92 
93     // fCurrCodec is owned by this class, but should not be an
94     // std::unique_ptr.  It will be deleted by the destructor of fEmbeddedCodecs.
95     SkCodec* fCurrCodec;
96 
97     typedef SkCodec INHERITED;
98 };
99 #endif  // SkIcoCodec_DEFINED
100