~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
 
3
 * 
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions are
 
6
 * met:
 
7
 * 
 
8
 *     * Redistributions of source code must retain the above copyright
 
9
 * notice, this list of conditions and the following disclaimer.
 
10
 *     * Redistributions in binary form must reproduce the above
 
11
 * copyright notice, this list of conditions and the following disclaimer
 
12
 * in the documentation and/or other materials provided with the
 
13
 * distribution.
 
14
 *     * Neither the name of Google Inc. nor the names of its
 
15
 * contributors may be used to endorse or promote products derived from
 
16
 * this software without specific prior written permission.
 
17
 * 
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
19
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
20
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
21
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
22
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
23
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
24
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
25
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
26
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
28
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
29
 */
 
30
 
 
31
#ifndef BMPImageReader_h
 
32
#define BMPImageReader_h
 
33
 
 
34
#include <stdint.h>
 
35
#include "ImageDecoder.h"
 
36
 
 
37
namespace WebCore {
 
38
 
 
39
    // This class decodes a BMP image.  It is used in the BMP and ICO decoders,
 
40
    // which wrap it in the appropriate code to read file headers, etc.
 
41
    class BMPImageReader {
 
42
        WTF_MAKE_FAST_ALLOCATED;
 
43
    public:
 
44
        // Read a value from |data[offset]|, converting from little to native
 
45
        // endianness.
 
46
        static inline uint16_t readUint16(SharedBuffer* data, int offset)
 
47
        {
 
48
            uint16_t result;
 
49
            memcpy(&result, &data->data()[offset], 2);
 
50
        #if CPU(BIG_ENDIAN)
 
51
            result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8);
 
52
        #endif
 
53
            return result;
 
54
        }
 
55
 
 
56
        static inline uint32_t readUint32(SharedBuffer* data, int offset)
 
57
        {
 
58
            uint32_t result;
 
59
            memcpy(&result, &data->data()[offset], 4);
 
60
        #if CPU(BIG_ENDIAN)
 
61
            result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) | ((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24);
 
62
        #endif
 
63
            return result;
 
64
        }
 
65
 
 
66
        // |parent| is the decoder that owns us.
 
67
        // |startOffset| points to the start of the BMP within the file.
 
68
        // |buffer| points at an empty ImageFrame that we'll initialize and
 
69
        // fill with decoded data.
 
70
        BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool usesAndMask);
 
71
 
 
72
        void setBuffer(ImageFrame* buffer) { m_buffer = buffer; }
 
73
        void setData(SharedBuffer* data) { m_data = data; }
 
74
 
 
75
        // Does the actual decoding.  If |onlySize| is true, decoding only
 
76
        // progresses as far as necessary to get the image size.  Returns
 
77
        // whether decoding succeeded.
 
78
        bool decodeBMP(bool onlySize);
 
79
 
 
80
    private:
 
81
        // The various BMP compression types.  We don't currently decode all
 
82
        // these.
 
83
        enum CompressionType {
 
84
            // Universal types
 
85
            RGB = 0,
 
86
            RLE8 = 1,
 
87
            RLE4 = 2,
 
88
            // Windows V3+ only
 
89
            BITFIELDS = 3,
 
90
            JPEG = 4,
 
91
            PNG = 5,
 
92
            // OS/2 2.x-only
 
93
            HUFFMAN1D,  // Stored in file as 3
 
94
            RLE24,      // Stored in file as 4
 
95
        };
 
96
        enum AndMaskState {
 
97
            None,
 
98
            NotYetDecoded,
 
99
            Decoding,
 
100
        };
 
101
        enum ProcessingResult {
 
102
            Success,
 
103
            Failure,
 
104
            InsufficientData,
 
105
        };
 
106
 
 
107
        // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE
 
108
        // structs, but with unnecessary entries removed.
 
109
        struct BitmapInfoHeader {
 
110
            uint32_t biSize;
 
111
            int32_t biWidth;
 
112
            int32_t biHeight;
 
113
            uint16_t biBitCount;
 
114
            CompressionType biCompression;
 
115
            uint32_t biClrUsed;
 
116
        };
 
117
        struct RGBTriple {
 
118
            uint8_t rgbBlue;
 
119
            uint8_t rgbGreen;
 
120
            uint8_t rgbRed;
 
121
        };
 
122
 
 
123
        inline uint16_t readUint16(int offset) const
 
124
        {
 
125
            return readUint16(m_data.get(), m_decodedOffset + offset);
 
126
        }
 
127
 
 
128
        inline uint32_t readUint32(int offset) const
 
129
        {
 
130
            return readUint32(m_data.get(), m_decodedOffset + offset);
 
131
        }
 
132
 
 
133
        // Determines the size of the BMP info header.  Returns true if the size
 
134
        // is valid.
 
135
        bool readInfoHeaderSize();
 
136
 
 
137
        // Processes the BMP info header.  Returns true if the info header could
 
138
        // be decoded.
 
139
        bool processInfoHeader();
 
140
 
 
141
        // Helper function for processInfoHeader() which does the actual reading
 
142
        // of header values from the byte stream.  Returns false on error.
 
143
        bool readInfoHeader();
 
144
 
 
145
        // Returns true if this is a Windows V4+ BMP.
 
146
        inline bool isWindowsV4Plus() const
 
147
        {
 
148
            // Windows V4 info header is 108 bytes.  V5 is 124 bytes.
 
149
            return (m_infoHeader.biSize == 108) || (m_infoHeader.biSize == 124);
 
150
        }
 
151
 
 
152
        // Returns false if consistency errors are found in the info header.
 
153
        bool isInfoHeaderValid() const;
 
154
 
 
155
        // For BI_BITFIELDS images, initializes the m_bitMasks[] and
 
156
        // m_bitOffsets[] arrays.  processInfoHeader() will initialize these for
 
157
        // other compression types where needed.
 
158
        bool processBitmasks();
 
159
 
 
160
        // For paletted images, allocates and initializes the m_colorTable[]
 
161
        // array.
 
162
        bool processColorTable();
 
163
 
 
164
        // Processes an RLE-encoded image.  Returns true if the entire image was
 
165
        // decoded.
 
166
        bool processRLEData();
 
167
 
 
168
        // Processes a set of non-RLE-compressed pixels.  Two cases:
 
169
        //   * inRLE = true: the data is inside an RLE-encoded bitmap.  Tries to
 
170
        //     process |numPixels| pixels on the current row.
 
171
        //   * inRLE = false: the data is inside a non-RLE-encoded bitmap.
 
172
        //     |numPixels| is ignored.  Expects |m_coord| to point at the
 
173
        //     beginning of the next row to be decoded.  Tries to process as
 
174
        //     many complete rows as possible.  Returns InsufficientData if
 
175
        //     there wasn't enough data to decode the whole image.
 
176
        //
 
177
        // This function returns a ProcessingResult instead of a bool so that it
 
178
        // can avoid calling m_parent->setFailed(), which could lead to memory
 
179
        // corruption since that will delete |this| but some callers still want
 
180
        // to access member variables after this returns.
 
181
        ProcessingResult processNonRLEData(bool inRLE, int numPixels);
 
182
 
 
183
        // Returns true if the current y-coordinate plus |numRows| would be past
 
184
        // the end of the image.  Here "plus" means "toward the end of the
 
185
        // image", so downwards for m_isTopDown images and upwards otherwise.
 
186
        inline bool pastEndOfImage(int numRows)
 
187
        {
 
188
            return m_isTopDown ? ((m_coord.y() + numRows) >= m_parent->size().height()) : ((m_coord.y() - numRows) < 0);
 
189
        }
 
190
 
 
191
        // Returns the pixel data for the current X coordinate in a uint32_t.
 
192
        // Assumes m_decodedOffset has been set to the beginning of the current
 
193
        // row.
 
194
        // NOTE: Only as many bytes of the return value as are needed to hold
 
195
        // the pixel data will actually be set.
 
196
        inline uint32_t readCurrentPixel(int bytesPerPixel) const
 
197
        {
 
198
            const int offset = m_coord.x() * bytesPerPixel;
 
199
            switch (bytesPerPixel) {
 
200
            case 2:
 
201
                return readUint16(offset);
 
202
 
 
203
            case 3: {
 
204
                // It doesn't matter that we never set the most significant byte
 
205
                // of the return value here in little-endian mode, the caller
 
206
                // won't read it.
 
207
                uint32_t pixel;
 
208
                memcpy(&pixel, &m_data->data()[m_decodedOffset + offset], 3);
 
209
        #if CPU(BIG_ENDIAN)
 
210
                pixel = ((pixel & 0xff00) << 8) | ((pixel & 0xff0000) >> 8) | ((pixel & 0xff000000) >> 24);
 
211
        #endif
 
212
                return pixel;
 
213
            }
 
214
 
 
215
            case 4:
 
216
                return readUint32(offset);
 
217
 
 
218
            default:
 
219
                ASSERT_NOT_REACHED();
 
220
                return 0;
 
221
            }
 
222
        }
 
223
 
 
224
        // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A)
 
225
        // in the given pixel data.
 
226
        inline unsigned getComponent(uint32_t pixel, int component) const
 
227
        {
 
228
            return ((pixel & m_bitMasks[component]) >> m_bitShiftsRight[component]) << m_bitShiftsLeft[component];
 
229
        }
 
230
 
 
231
        inline unsigned getAlpha(uint32_t pixel) const
 
232
        {
 
233
            // For images without alpha, return alpha of 0xff.
 
234
            return m_bitMasks[3] ? getComponent(pixel, 3) : 0xff;
 
235
        }
 
236
 
 
237
        // Sets the current pixel to the color given by |colorIndex|.  This also
 
238
        // increments the relevant local variables to move the current pixel
 
239
        // right by one.
 
240
        inline void setI(size_t colorIndex)
 
241
        {
 
242
            setRGBA(m_colorTable[colorIndex].rgbRed, m_colorTable[colorIndex].rgbGreen, m_colorTable[colorIndex].rgbBlue, 0xff);
 
243
        }
 
244
 
 
245
        // Like setI(), but with the individual component values specified.
 
246
        inline void setRGBA(unsigned red,
 
247
                            unsigned green,
 
248
                            unsigned blue,
 
249
                            unsigned alpha)
 
250
        {
 
251
            m_buffer->setRGBA(m_coord.x(), m_coord.y(), red, green, blue, alpha);
 
252
            m_coord.move(1, 0);
 
253
        }
 
254
 
 
255
        // Fills pixels from the current X-coordinate up to, but not including,
 
256
        // |endCoord| with the color given by the individual components.  This
 
257
        // also increments the relevant local variables to move the current
 
258
        // pixel right to |endCoord|.
 
259
        inline void fillRGBA(int endCoord,
 
260
                             unsigned red,
 
261
                             unsigned green,
 
262
                             unsigned blue,
 
263
                             unsigned alpha)
 
264
        {
 
265
            while (m_coord.x() < endCoord)
 
266
                setRGBA(red, green, blue, alpha);
 
267
        }
 
268
 
 
269
        // Resets the relevant local variables to start drawing at the left edge
 
270
        // of the "next" row, where "next" is above or below the current row
 
271
        // depending on the value of |m_isTopDown|.
 
272
        void moveBufferToNextRow();
 
273
 
 
274
        // The decoder that owns us.
 
275
        ImageDecoder* m_parent;
 
276
 
 
277
        // The destination for the pixel data.
 
278
        ImageFrame* m_buffer;
 
279
 
 
280
        // The file to decode.
 
281
        RefPtr<SharedBuffer> m_data;
 
282
 
 
283
        // An index into |m_data| representing how much we've already decoded.
 
284
        size_t m_decodedOffset;
 
285
 
 
286
        // The file offset at which the BMP info header starts.
 
287
        size_t m_headerOffset;
 
288
 
 
289
        // The file offset at which the actual image bits start.  When decoding
 
290
        // ICO files, this is set to 0, since it's not stored anywhere in a
 
291
        // header; the reader functions expect the image data to start
 
292
        // immediately after the header and (if necessary) color table.
 
293
        size_t m_imgDataOffset;
 
294
 
 
295
        // The BMP info header.
 
296
        BitmapInfoHeader m_infoHeader;
 
297
 
 
298
        // True if this is an OS/2 1.x (aka Windows 2.x) BMP.  The struct
 
299
        // layouts for this type of BMP are slightly different from the later,
 
300
        // more common formats.
 
301
        bool m_isOS21x;
 
302
 
 
303
        // True if this is an OS/2 2.x BMP.  The meanings of compression types 3
 
304
        // and 4 for this type of BMP differ from Windows V3+ BMPs.
 
305
        //
 
306
        // This will be falsely negative in some cases, but only ones where the
 
307
        // way we misinterpret the data is irrelevant.
 
308
        bool m_isOS22x;
 
309
 
 
310
        // True if the BMP is not vertically flipped, that is, the first line of
 
311
        // raster data in the file is the top line of the image.
 
312
        bool m_isTopDown;
 
313
 
 
314
        // These flags get set to false as we finish each processing stage.
 
315
        bool m_needToProcessBitmasks;
 
316
        bool m_needToProcessColorTable;
 
317
 
 
318
        // Masks/offsets for the color values for non-palette formats.  These
 
319
        // are bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B,
 
320
        // A.
 
321
        //
 
322
        // The right/left shift values are meant to be applied after the masks.
 
323
        // We need to right shift to compensate for the bitfields' offsets into
 
324
        // the 32 bits of pixel data, and left shift to scale the color values
 
325
        // up for fields with less than 8 bits of precision.  Sadly, we can't
 
326
        // just combine these into one shift value because the net shift amount
 
327
        // could go either direction.  (If only "<< -x" were equivalent to
 
328
        // ">> x"...)
 
329
        uint32_t m_bitMasks[4];
 
330
        int m_bitShiftsRight[4];
 
331
        int m_bitShiftsLeft[4];
 
332
 
 
333
        // The color palette, for paletted formats.
 
334
        size_t m_tableSizeInBytes;
 
335
        Vector<RGBTriple> m_colorTable;
 
336
 
 
337
        // The coordinate to which we've decoded the image.
 
338
        IntPoint m_coord;
 
339
 
 
340
        // Variables that track whether we've seen pixels with alpha values != 0
 
341
        // and == 0, respectively.  See comments in processNonRLEData() on how
 
342
        // these are used.
 
343
        bool m_seenNonZeroAlphaPixel;
 
344
        bool m_seenZeroAlphaPixel;
 
345
 
 
346
        // ICOs store a 1bpp "mask" immediately after the main bitmap image data
 
347
        // (and, confusingly, add its height to the biHeight value in the info
 
348
        // header, thus doubling it).  This variable tracks whether we have such
 
349
        // a mask and if we've started decoding it yet.
 
350
        AndMaskState m_andMaskState;
 
351
    };
 
352
 
 
353
} // namespace WebCore
 
354
 
 
355
#endif