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 SkBmpRLECodec_DEFINED
      8 #define SkBmpRLECodec_DEFINED
      9 
     10 #include "SkBmpCodec.h"
     11 #include "SkColorTable.h"
     12 #include "SkImageInfo.h"
     13 #include "SkSampler.h"
     14 #include "SkTypes.h"
     15 
     16 /*
     17  * This class implements the decoding for bmp images that use an RLE encoding
     18  */
     19 class SkBmpRLECodec : public SkBmpCodec {
     20 public:
     21 
     22     /*
     23      * Creates an instance of the decoder
     24      *
     25      * Called only by SkBmpCodec::NewFromStream
     26      * There should be no other callers despite this being public
     27      *
     28      * @param info contains properties of the encoded data
     29      * @param stream the stream of encoded image data
     30      * @param bitsPerPixel the number of bits used to store each pixel
     31      * @param numColors the number of colors in the color table
     32      * @param bytesPerColor the number of bytes in the stream used to represent
     33                             each color in the color table
     34      * @param offset the offset of the image pixel data from the end of the
     35      *               headers
     36      * @param rowOrder indicates whether rows are ordered top-down or bottom-up
     37      */
     38     SkBmpRLECodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
     39             uint16_t bitsPerPixel, uint32_t numColors, uint32_t bytesPerColor,
     40             uint32_t offset, SkCodec::SkScanlineOrder rowOrder);
     41 
     42     int setSampleX(int);
     43 
     44 protected:
     45 
     46     Result onGetPixels(const SkImageInfo& dstInfo, void* dst,
     47                        size_t dstRowBytes, const Options&, SkPMColor*,
     48                        int*, int*) override;
     49 
     50     SkCodec::Result onPrepareToDecode(const SkImageInfo& dstInfo,
     51             const SkCodec::Options& options, SkPMColor inputColorPtr[],
     52             int* inputColorCount) override;
     53 
     54 private:
     55 
     56     /*
     57      * Creates the color table
     58      * Sets colorCount to the new color count if it is non-nullptr
     59      */
     60     bool createColorTable(SkColorType dstColorType, int* colorCount);
     61 
     62     bool initializeStreamBuffer();
     63 
     64     /*
     65      * Before signalling kIncompleteInput, we should attempt to load the
     66      * stream buffer with additional data.
     67      *
     68      * @return the number of bytes remaining in the stream buffer after
     69      *         attempting to read more bytes from the stream
     70      */
     71     size_t checkForMoreData();
     72 
     73     /*
     74      * Set an RLE pixel using the color table
     75      */
     76     void setPixel(void* dst, size_t dstRowBytes,
     77                   const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
     78                   uint8_t index);
     79     /*
     80      * Set an RLE24 pixel from R, G, B values
     81      */
     82     void setRGBPixel(void* dst, size_t dstRowBytes,
     83                      const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
     84                      uint8_t red, uint8_t green, uint8_t blue);
     85 
     86     /*
     87      * If dst is NULL, this is a signal to skip the rows.
     88      */
     89     int decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes,
     90             const Options& opts) override;
     91     int decodeRLE(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes);
     92 
     93     bool skipRows(int count) override;
     94 
     95     SkSampler* getSampler(bool createIfNecessary) override;
     96 
     97     sk_sp<SkColorTable>        fColorTable;
     98     // fNumColors is the number specified in the header, or 0 if not present in the header.
     99     const uint32_t             fNumColors;
    100     const uint32_t             fBytesPerColor;
    101     const uint32_t             fOffset;
    102 
    103     static constexpr size_t    kBufferSize = 4096;
    104     uint8_t                    fStreamBuffer[kBufferSize];
    105     size_t                     fBytesBuffered;
    106 
    107     uint32_t                   fCurrRLEByte;
    108     int                        fSampleX;
    109     std::unique_ptr<SkSampler> fSampler;
    110 
    111     // Scanline decodes allow the client to ask for a single scanline at a time.
    112     // This can be tricky when the RLE encoding instructs the decoder to jump down
    113     // multiple lines.  This field keeps track of lines that need to be skipped
    114     // on subsequent calls to decodeRows().
    115     int                        fLinesToSkip;
    116 
    117     typedef SkBmpCodec INHERITED;
    118 };
    119 #endif  // SkBmpRLECodec_DEFINED
    120