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 "SkCodec.h" 11 #include "SkImageInfo.h" 12 #include "SkStream.h" 13 #include "SkTArray.h" 14 #include "SkTypes.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 SkCodec* NewFromStream(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 45 SkEncodedImageFormat onGetEncodedFormat() const override { 46 return SkEncodedImageFormat::kICO; 47 } 48 49 SkScanlineOrder onGetScanlineOrder() const override; 50 51 private: 52 53 Result onStartScanlineDecode(const SkImageInfo& dstInfo, 54 const SkCodec::Options& options) override; 55 56 int onGetScanlines(void* dst, int count, size_t rowBytes) override; 57 58 bool onSkipScanlines(int count) override; 59 60 Result onStartIncrementalDecode(const SkImageInfo& dstInfo, void* pixels, size_t rowBytes, 61 const SkCodec::Options&) override; 62 63 Result onIncrementalDecode(int* rowsDecoded) override; 64 65 SkSampler* getSampler(bool createIfNecessary) override; 66 67 /* 68 * Searches fEmbeddedCodecs for a codec that matches requestedSize. 69 * The search starts at startIndex and ends when an appropriate codec 70 * is found, or we have reached the end of the array. 71 * 72 * @return the index of the matching codec or -1 if there is no 73 * matching codec between startIndex and the end of 74 * the array. 75 */ 76 int chooseCodec(const SkISize& requestedSize, int startIndex); 77 78 /* 79 * Constructor called by NewFromStream 80 * @param embeddedCodecs codecs for the embedded images, takes ownership 81 */ 82 SkIcoCodec(int width, int height, const SkEncodedInfo& info, 83 SkTArray<std::unique_ptr<SkCodec>, true>* embeddedCodecs, sk_sp<SkColorSpace> colorSpace); 84 85 std::unique_ptr<SkTArray<std::unique_ptr<SkCodec>, true>> fEmbeddedCodecs; 86 87 // Only used by the scanline decoder. onStartScanlineDecode() will set 88 // fCurrScanlineCodec to one of the fEmbeddedCodecs, if it can find a 89 // codec of the appropriate size. We will use fCurrScanlineCodec for 90 // subsequent calls to onGetScanlines() or onSkipScanlines(). 91 // fCurrScanlineCodec is owned by this class, but should not be an 92 // std::unique_ptr. It will be deleted by the destructor of fEmbeddedCodecs. 93 SkCodec* fCurrScanlineCodec; 94 95 // Only used by incremental decoder. onStartIncrementalDecode() will set 96 // fCurrIncrementalCodec to one of the fEmbeddedCodecs, if it can find a 97 // codec of the appropriate size. We will use fCurrIncrementalCodec for 98 // subsequent calls to incrementalDecode(). 99 // fCurrIncrementalCodec is owned by this class, but should not be an 100 // std::unique_ptr. It will be deleted by the destructor of fEmbeddedCodecs. 101 SkCodec* fCurrIncrementalCodec; 102 103 typedef SkCodec INHERITED; 104 }; 105 #endif // SkIcoCodec_DEFINED 106