Home | History | Annotate | Download | only in codec
      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