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