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