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