aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/codec/SkCodec_libbmp.h
blob: 4dda117d5a1e6529d4504bdfdb693997d7259984 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkCodec.h"
#include "SkColorTable.h"
#include "SkImageInfo.h"
#include "SkMaskSwizzler.h"
#include "SkStream.h"
#include "SkSwizzler.h"
#include "SkTypes.h"

// TODO: rename SkCodec_libbmp files to SkBmpCodec
// TODO: define a wrapper for SkDebugf that doesn't always print
/*
 *
 * This class implements the decoding for bmp images
 *
 */
class SkBmpCodec : public SkCodec {
public:

    /*
     *
     * Describes if rows of the input start at the top or bottom of the image
     *
     */
    enum RowOrder {
        kTopDown_RowOrder,
        kBottomUp_RowOrder
    };

    /*
     *
     * Checks the start of the stream to see if the image is a bmp
     *
     */
    static bool IsBmp(SkStream*);

    /*
     *
     * Assumes IsBmp was called and returned true
     * Creates a bmp decoder
     * Reads enough of the stream to determine the image format
     *
     */
    static SkCodec* NewFromStream(SkStream*);

    /*
     *
     * Creates a bmp decoder for a bmp embedded in ico
     * Reads enough of the stream to determine the image format
     *
     */
    static SkCodec* NewFromIco(SkStream*);

protected:

    /*
     *
     * Initiates the bmp decode
     *
     */
    virtual Result onGetPixels(const SkImageInfo& dstInfo, void* dst,
                               size_t dstRowBytes, const Options&, SkPMColor*,
                               int*) SK_OVERRIDE;

    SkEncodedFormat onGetEncodedFormat() const SK_OVERRIDE { return kBMP_SkEncodedFormat; }

private:

    /*
     *
     * Used to define the input format of the bmp
     *
     */
    enum BitmapInputFormat {
        kStandard_BitmapInputFormat,
        kRLE_BitmapInputFormat,
        kBitMask_BitmapInputFormat,
        kUnknown_BitmapInputFormat
    };

    /*
     *
     * Creates the color table
     *
     */
     bool createColorTable(SkAlphaType alphaType);

    /*
     *
     * Creates a bmp decoder
     * Reads enough of the stream to determine the image format
     *
     */
    static SkCodec* NewFromStream(SkStream*, bool isIco);

    /*
     *
     * Performs the bitmap decoding for bit masks input format
     *
     */
    Result decodeMask(const SkImageInfo& dstInfo, void* dst,
                      size_t dstRowBytes);

    /*
     *
     * Set an RLE pixel using the color table
     *
     */
    void setRLEPixel(SkPMColor* dst, size_t dstRowBytes,
                     const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
                     uint8_t index);
    /*
     *
     * Set an RLE24 pixel from R, G, B values
     *
     */
    void setRLE24Pixel(SkPMColor* dst, size_t dstRowBytes,
                       const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
                       uint8_t red, uint8_t green, uint8_t blue);

    /*
     *
     * Performs the bitmap decoding for RLE input format
     *
     */
    Result decodeRLE(const SkImageInfo& dstInfo, void* dst,
                     size_t dstRowBytes);

    /*
     *
     * Performs the bitmap decoding for standard input format
     *
     */
    Result decode(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes);

    /*
     *
     * Creates an instance of the decoder
     * Called only by NewFromStream
     *
     * @param srcInfo contains the source width and height
     * @param stream the stream of image data
     * @param bitsPerPixel the number of bits used to store each pixel
     * @param format the format of the bmp file
     * @param masks optional color masks for certain bmp formats, passes
                    ownership to SkBmpCodec
     * @param numColors the number of colors in the color table
     * @param bytesPerColor the number of bytes in the stream used to represent
                            each color in the color table
     * @param offset the offset of the image pixel data from the end of the
     *               headers
     * @param rowOrder indicates whether rows are ordered top-down or bottom-up
     * @param RLEBytes used only for RLE decodes, as we must decode all
     *                  of the data at once rather than row by row
     *                  it indicates the amount of data left in the stream
     *                  after decoding the headers
     *
     */
    SkBmpCodec(const SkImageInfo& srcInfo, SkStream* stream,
               uint16_t bitsPerPixel, BitmapInputFormat format,
               SkMasks* masks, uint32_t numColors, uint32_t bytesPerColor,
               uint32_t offset, RowOrder rowOrder, size_t RLEBytes,
               bool isIco);

    // Fields
    const uint16_t                      fBitsPerPixel;
    const BitmapInputFormat             fInputFormat;
    SkAutoTDelete<SkMasks>              fMasks;          // owned
    SkAutoTDelete<SkColorTable>         fColorTable;     // owned
    uint32_t                            fNumColors;
    const uint32_t                      fBytesPerColor;
    const uint32_t                      fOffset;
    const RowOrder                      fRowOrder;
    const size_t                        fRLEBytes;
    const bool                          fIsIco;

    typedef SkCodec INHERITED;
};