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