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 blink { 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. 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) | ((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 isInICO); 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 ProcessingResult { 98 Success, 99 Failure, 100 InsufficientData, 101 }; 102 103 // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE 104 // structs, but with unnecessary entries removed. 105 struct BitmapInfoHeader { 106 uint32_t biSize; 107 int32_t biWidth; 108 int32_t biHeight; 109 uint16_t biBitCount; 110 CompressionType biCompression; 111 uint32_t biClrUsed; 112 }; 113 struct RGBTriple { 114 uint8_t rgbBlue; 115 uint8_t rgbGreen; 116 uint8_t rgbRed; 117 }; 118 119 inline uint16_t readUint16(int offset) const 120 { 121 return readUint16(m_data.get(), m_decodedOffset + offset); 122 } 123 124 inline uint32_t readUint32(int offset) const 125 { 126 return readUint32(m_data.get(), m_decodedOffset + offset); 127 } 128 129 // Determines the size of the BMP info header. Returns true if the size 130 // is valid. 131 bool readInfoHeaderSize(); 132 133 // Processes the BMP info header. Returns true if the info header could 134 // be decoded. 135 bool processInfoHeader(); 136 137 // Helper function for processInfoHeader() which does the actual reading 138 // of header values from the byte stream. Returns false on error. 139 bool readInfoHeader(); 140 141 // Returns true if this is a Windows V4+ BMP. 142 inline bool isWindowsV4Plus() const 143 { 144 // Windows V4 info header is 108 bytes. V5 is 124 bytes. 145 return (m_infoHeader.biSize == 108) || (m_infoHeader.biSize == 124); 146 } 147 148 // Returns false if consistency errors are found in the info header. 149 bool isInfoHeaderValid() const; 150 151 // For BI_BITFIELDS images, initializes the m_bitMasks[] and 152 // m_bitOffsets[] arrays. processInfoHeader() will initialize these for 153 // other compression types where needed. 154 bool processBitmasks(); 155 156 // For paletted images, allocates and initializes the m_colorTable[] 157 // array. 158 bool processColorTable(); 159 160 // Processes an RLE-encoded image. Returns true if the entire image was 161 // decoded. 162 bool processRLEData(); 163 164 // Processes a set of non-RLE-compressed pixels. Two cases: 165 // * inRLE = true: the data is inside an RLE-encoded bitmap. Tries to 166 // process |numPixels| pixels on the current row. 167 // * inRLE = false: the data is inside a non-RLE-encoded bitmap. 168 // |numPixels| is ignored. Expects |m_coord| to point at the 169 // beginning of the next row to be decoded. Tries to process as 170 // many complete rows as possible. Returns InsufficientData if 171 // there wasn't enough data to decode the whole image. 172 // 173 // This function returns a ProcessingResult instead of a bool so that it 174 // can avoid calling m_parent->setFailed(), which could lead to memory 175 // corruption since that will delete |this| but some callers still want 176 // to access member variables after this returns. 177 ProcessingResult processNonRLEData(bool inRLE, int numPixels); 178 179 // Returns true if the current y-coordinate plus |numRows| would be past 180 // the end of the image. Here "plus" means "toward the end of the 181 // image", so downwards for m_isTopDown images and upwards otherwise. 182 inline bool pastEndOfImage(int numRows) 183 { 184 return m_isTopDown ? ((m_coord.y() + numRows) >= m_parent->size().height()) : ((m_coord.y() - numRows) < 0); 185 } 186 187 // Returns the pixel data for the current X coordinate in a uint32_t. 188 // Assumes m_decodedOffset has been set to the beginning of the current 189 // row. 190 // NOTE: Only as many bytes of the return value as are needed to hold 191 // the pixel data will actually be set. 192 inline uint32_t readCurrentPixel(int bytesPerPixel) const 193 { 194 const int offset = m_coord.x() * bytesPerPixel; 195 switch (bytesPerPixel) { 196 case 2: 197 return readUint16(offset); 198 199 case 3: { 200 // It doesn't matter that we never set the most significant byte 201 // of the return value here in little-endian mode, the caller 202 // won't read it. 203 uint32_t pixel; 204 memcpy(&pixel, &m_data->data()[m_decodedOffset + offset], 3); 205 #if CPU(BIG_ENDIAN) 206 pixel = ((pixel & 0xff00) << 8) | ((pixel & 0xff0000) >> 8) | ((pixel & 0xff000000) >> 24); 207 #endif 208 return pixel; 209 } 210 211 case 4: 212 return readUint32(offset); 213 214 default: 215 ASSERT_NOT_REACHED(); 216 return 0; 217 } 218 } 219 220 // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A) 221 // in the given pixel data. 222 inline unsigned getComponent(uint32_t pixel, int component) const 223 { 224 uint8_t value = (pixel & m_bitMasks[component]) >> m_bitShiftsRight[component]; 225 return m_lookupTableAddresses[component] ? m_lookupTableAddresses[component][value] : value; 226 } 227 228 inline unsigned getAlpha(uint32_t pixel) const 229 { 230 // For images without alpha, return alpha of 0xff. 231 return m_bitMasks[3] ? getComponent(pixel, 3) : 0xff; 232 } 233 234 // Sets the current pixel to the color given by |colorIndex|. This also 235 // increments the relevant local variables to move the current pixel 236 // right by one. 237 inline void setI(size_t colorIndex) 238 { 239 setRGBA(m_colorTable[colorIndex].rgbRed, m_colorTable[colorIndex].rgbGreen, m_colorTable[colorIndex].rgbBlue, 0xff); 240 } 241 242 // Like setI(), but with the individual component values specified. 243 inline void setRGBA(unsigned red, 244 unsigned green, 245 unsigned blue, 246 unsigned alpha) 247 { 248 m_buffer->setRGBA(m_coord.x(), m_coord.y(), red, green, blue, alpha); 249 m_coord.move(1, 0); 250 } 251 252 // Fills pixels from the current X-coordinate up to, but not including, 253 // |endCoord| with the color given by the individual components. This 254 // also increments the relevant local variables to move the current 255 // pixel right to |endCoord|. 256 inline void fillRGBA(int endCoord, 257 unsigned red, 258 unsigned green, 259 unsigned blue, 260 unsigned alpha) 261 { 262 while (m_coord.x() < endCoord) 263 setRGBA(red, green, blue, alpha); 264 } 265 266 // Resets the relevant local variables to start drawing at the left edge 267 // of the "next" row, where "next" is above or below the current row 268 // depending on the value of |m_isTopDown|. 269 void moveBufferToNextRow(); 270 271 // The decoder that owns us. 272 ImageDecoder* m_parent; 273 274 // The destination for the pixel data. 275 ImageFrame* m_buffer; 276 277 // The file to decode. 278 RefPtr<SharedBuffer> m_data; 279 280 // An index into |m_data| representing how much we've already decoded. 281 size_t m_decodedOffset; 282 283 // The file offset at which the BMP info header starts. 284 size_t m_headerOffset; 285 286 // The file offset at which the actual image bits start. When decoding 287 // ICO files, this is set to 0, since it's not stored anywhere in a 288 // header; the reader functions expect the image data to start 289 // immediately after the header and (if necessary) color table. 290 size_t m_imgDataOffset; 291 292 // The BMP info header. 293 BitmapInfoHeader m_infoHeader; 294 295 // True if this is an OS/2 1.x (aka Windows 2.x) BMP. The struct 296 // layouts for this type of BMP are slightly different from the later, 297 // more common formats. 298 bool m_isOS21x; 299 300 // True if this is an OS/2 2.x BMP. The meanings of compression types 3 301 // and 4 for this type of BMP differ from Windows V3+ BMPs. 302 // 303 // This will be falsely negative in some cases, but only ones where the 304 // way we misinterpret the data is irrelevant. 305 bool m_isOS22x; 306 307 // True if the BMP is not vertically flipped, that is, the first line of 308 // raster data in the file is the top line of the image. 309 bool m_isTopDown; 310 311 // These flags get set to false as we finish each processing stage. 312 bool m_needToProcessBitmasks; 313 bool m_needToProcessColorTable; 314 315 // Masks/offsets for the color values for non-palette formats. These are 316 // bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B, A. 317 uint32_t m_bitMasks[4]; 318 319 // Right shift values, meant to be applied after the masks. We need to shift 320 // the bitfield values down from their offsets into the 32 bits of pixel 321 // data, as well as truncate the least significant bits of > 8-bit fields. 322 int m_bitShiftsRight[4]; 323 324 // We use a lookup table to convert < 8-bit values into 8-bit values. The 325 // values in the table are "round(val * 255.0 / ((1 << n) - 1))" for an 326 // n-bit source value. These elements are set to 0 for 8-bit sources. 327 const uint8_t* m_lookupTableAddresses[4]; 328 329 // The color palette, for paletted formats. 330 Vector<RGBTriple> m_colorTable; 331 332 // The coordinate to which we've decoded the image. 333 IntPoint m_coord; 334 335 // Variables that track whether we've seen pixels with alpha values != 0 336 // and == 0, respectively. See comments in processNonRLEData() on how 337 // these are used. 338 bool m_seenNonZeroAlphaPixel; 339 bool m_seenZeroAlphaPixel; 340 341 // BMPs-in-ICOs have a few differences from standalone BMPs, so we need to 342 // know if we're in an ICO container. 343 bool m_isInICO; 344 345 // ICOs store a 1bpp "mask" immediately after the main bitmap image data 346 // (and, confusingly, add its height to the biHeight value in the info 347 // header, thus doubling it). If |m_isInICO| is true, this variable tracks 348 // whether we've begun decoding this mask yet. 349 bool m_decodingAndMask; 350 }; 351 352 } // namespace blink 353 354 #endif 355