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 "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. |
| 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 i
mgDataOffset, 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().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. |
| 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) | ((pixe
l & 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[component])
<< 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].rgbGre
en, 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 |