xref: /aosp_15_r20/external/skia/src/codec/SkBmpRLECodec.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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