OLD | NEW |
| (Empty) |
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 "core/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 BMPImageReader { | |
43 WTF_MAKE_FAST_ALLOCATED; | |
44 public: | |
45 // Read a value from |data[offset]|, converting from little to native | |
46 // endianness. | |
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 | |
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) | ((resu
lt & 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 | |
73 void setBuffer(ImageFrame* buffer) { m_buffer = buffer; } | |
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 | |
124 inline uint16_t readUint16(int offset) const | |
125 { | |
126 return readUint16(m_data.get(), m_decodedOffset + offset); | |
127 } | |
128 | |
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. | |
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. | |
187 inline bool pastEndOfImage(int numRows) | |
188 { | |
189 return m_isTopDown ? ((m_coord.y() + numRows) >= m_parent->size().he
ight()) : ((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. | |
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. | |
227 inline unsigned getComponent(uint32_t pixel, int component) const | |
228 { | |
229 return ((pixel & m_bitMasks[component]) >> m_bitShiftsRight[componen
t]) << m_bitShiftsLeft[component]; | |
230 } | |
231 | |
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. | |
241 inline void setI(size_t colorIndex) | |
242 { | |
243 setRGBA(m_colorTable[colorIndex].rgbRed, m_colorTable[colorIndex].rg
bGreen, m_colorTable[colorIndex].rgbBlue, 0xff); | |
244 } | |
245 | |
246 // Like setI(), but with the individual component values specified. | |
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|. | |
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 | |
OLD | NEW |