Changeset 44833 in webkit
- Timestamp:
- Jun 18, 2009 6:14:27 PM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r44832 r44833 1 2009-06-18 Peter Kasting <pkasting@google.com> 2 3 Reviewed by Eric Seidel. 4 5 https://bugs.webkit.org/show_bug.cgi?id=26460 part two 6 Attempt to minimize diff of following functional change by first landing 7 non-functional change to: 8 * Make readUintX() public and static (since they will need to be once 9 BMPImageReader is included in *ImageDecoder via composition rather 10 than inheritance). Add wrappers in each class so callers can be 11 simpler. In the next patch, these wrappers will be beefed up slightly 12 and the callers will get even simpler. 13 * Change direct setting of m_failed to use setFailed(), since in the 14 next patch much of this code won't even have direct access to m_failed 15 * Add a helper function in ICOImageDecoder to determine the image type 16 instead of simply doing it inline 17 * Rewrap lines that used to be <=80 cols and slipped over it during the 18 original landing of these decoders 19 * Other misc. changes, e.g. adding constructor definitions, reordering 20 functions, changing RGBA32Buffer& to RGBA32Buffer*, etc. that have no 21 functional effect but minimize the subsequent diff for readability 22 23 24 * platform/image-decoders/bmp/BMPImageDecoder.cpp: 25 (WebCore::BMPImageDecoder::BMPImageDecoder): 26 (WebCore::BMPImageDecoder::processFileHeader): 27 * platform/image-decoders/bmp/BMPImageDecoder.h: 28 (WebCore::BMPImageDecoder::readUint32): 29 * platform/image-decoders/bmp/BMPImageReader.cpp: 30 (WebCore::BMPImageReader::decodeBMP): 31 (WebCore::BMPImageReader::getInfoHeaderSize): 32 (WebCore::BMPImageReader::processInfoHeader): 33 (WebCore::BMPImageReader::readInfoHeader): 34 (WebCore::BMPImageReader::processBitmasks): 35 (WebCore::BMPImageReader::processColorTable): 36 (WebCore::BMPImageReader::processRLEData): 37 (WebCore::BMPImageReader::processNonRLEData): 38 * platform/image-decoders/bmp/BMPImageReader.h: 39 (WebCore::BMPImageReader::readUint16Helper): 40 (WebCore::BMPImageReader::readUint32Helper): 41 (WebCore::BMPImageReader::): 42 (WebCore::BMPImageReader::readUint16): 43 (WebCore::BMPImageReader::readUint32): 44 (WebCore::BMPImageReader::readCurrentPixel): 45 (WebCore::BMPImageReader::getComponent): 46 (WebCore::BMPImageReader::setI): 47 (WebCore::BMPImageReader::setRGBA): 48 (WebCore::BMPImageReader::fillRGBA): 49 * platform/image-decoders/ico/ICOImageDecoder.cpp: 50 (WebCore::ICOImageDecoder::ICOImageDecoder): 51 (WebCore::ICOImageDecoder::isSizeAvailable): 52 (WebCore::ICOImageDecoder::size): 53 (WebCore::ICOImageDecoder::decodeImage): 54 (WebCore::ICOImageDecoder::processDirectory): 55 (WebCore::ICOImageDecoder::processDirectoryEntries): 56 (WebCore::ICOImageDecoder::isBetterEntry): 57 (WebCore::ICOImageDecoder::processImageType): 58 * platform/image-decoders/ico/ICOImageDecoder.h: 59 (WebCore::ICOImageDecoder::readUint16): 60 (WebCore::ICOImageDecoder::readUint32): 61 1 62 2009-06-18 Peter Kasting <pkasting@google.com> 2 63 -
trunk/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp
r44634 r44833 39 39 static const size_t sizeOfFileHeader = 14; 40 40 41 BMPImageDecoder::BMPImageDecoder() 42 : BMPImageReader() 43 { 44 } 45 41 46 void BMPImageDecoder::decodeImage(SharedBuffer* data) 42 47 { … … 74 79 */ 75 80 }; 76 if (fileType != BMAP) 77 m_failed = true; 81 if (fileType != BMAP) { 82 setFailed(); 83 return false; 84 } 78 85 79 return !m_failed;86 return true; 80 87 } 81 88 -
trunk/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h
r44634 r44833 39 39 class BMPImageDecoder : public BMPImageReader { 40 40 public: 41 BMPImageDecoder(); 42 41 43 virtual String filenameExtension() const { return "bmp"; } 42 44 … … 45 47 46 48 private: 49 inline uint32_t readUint32(SharedBuffer* data, int offset) const 50 { 51 return readUint32Helper(data, m_decodedOffset + offset); 52 } 53 47 54 // Processes the file header at the beginning of the data. Returns true if 48 55 // the file header could be decoded. -
trunk/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp
r44654 r44833 93 93 } 94 94 95 voidBMPImageReader::decodeBMP(SharedBuffer* data)95 bool BMPImageReader::decodeBMP(SharedBuffer* data) 96 96 { 97 97 // Calculate size of info header. 98 98 if (!m_infoHeader.biSize && !getInfoHeaderSize(data)) 99 return ;99 return false; 100 100 101 101 // Read and process info header. 102 102 if ((m_decodedOffset < (m_headerOffset + m_infoHeader.biSize)) 103 103 && !processInfoHeader(data)) 104 return ;104 return false; 105 105 106 106 // Read and process the bitmasks, if needed. 107 107 if (m_needToProcessBitmasks && !processBitmasks(data)) 108 return ;108 return false; 109 109 110 110 // Read and process the color table, if needed. 111 111 if (m_needToProcessColorTable && !processColorTable(data)) 112 return ;112 return false; 113 113 114 114 // Initialize the framebuffer if needed. 115 RGBA32Buffer & buffer =m_frameBufferCache.first();116 if (buffer .status() == RGBA32Buffer::FrameEmpty) {117 if (!buffer .setSize(size().width(), size().height())) {115 RGBA32Buffer* buffer = &m_frameBufferCache.first(); 116 if (buffer->status() == RGBA32Buffer::FrameEmpty) { 117 if (!buffer->setSize(size().width(), size().height())) { 118 118 // Unable to allocate. 119 m_failed = true;120 return ;121 } 122 buffer .setStatus(RGBA32Buffer::FramePartial);119 setFailed(); 120 return false; 121 } 122 buffer->setStatus(RGBA32Buffer::FramePartial); 123 123 // setSize() calls eraseARGB(), which resets the alpha flag, so we force 124 124 // it back to false here. We'll set it true below in all cases where 125 125 // these 0s could actually show through. 126 buffer .setHasAlpha(false);126 buffer->setHasAlpha(false); 127 127 128 128 // For BMPs, the frame always fills the entire image. 129 buffer .setRect(IntRect(IntPoint(), size()));129 buffer->setRect(IntRect(IntPoint(), size())); 130 130 131 131 if (!m_isTopDown) … … 139 139 || (m_infoHeader.biCompression == RLE24)) { 140 140 if (!processRLEData(data)) 141 return ;141 return false; 142 142 } else if (!processNonRLEData(data, false, 0)) 143 return ;143 return false; 144 144 } 145 145 146 146 // If the image has an AND mask and there was no alpha data, process the 147 147 // mask. 148 if ((m_andMaskState == NotYetDecoded) && !buffer .hasAlpha()) {148 if ((m_andMaskState == NotYetDecoded) && !buffer->hasAlpha()) { 149 149 // Reset decoding coordinates to start of image. 150 150 m_coord.setX(0); … … 157 157 } 158 158 if ((m_andMaskState == Decoding) && !processNonRLEData(data, false, 0)) 159 return ;159 return false; 160 160 161 161 // Done! 162 buffer.setStatus(RGBA32Buffer::FrameComplete); 162 buffer->setStatus(RGBA32Buffer::FrameComplete); 163 return true; 163 164 } 164 165 … … 180 181 || (m_imgDataOffset 181 182 && (m_imgDataOffset < (m_headerOffset + m_infoHeader.biSize)))) { 182 m_failed = true;183 setFailed(); 183 184 return false; 184 185 } … … 196 197 || (m_infoHeader.biSize == 46))) 197 198 m_isOS22x = true; 198 else 199 m_failed = true; 200 201 return !m_failed; 199 else { 200 setFailed(); 201 return false; 202 } 203 204 return true; 202 205 } 203 206 … … 214 217 // Sanity-check header values. 215 218 if (!isInfoHeaderValid()) { 216 m_failed = true;219 setFailed(); 217 220 return false; 218 221 } … … 220 223 // Make our size available to the caller. 221 224 if (!setSize(m_infoHeader.biWidth, m_infoHeader.biHeight)) { 222 m_failed = true;225 setFailed(); 223 226 return false; 224 227 } … … 285 288 } else if (biCompression > 5) { 286 289 // Some type we don't understand. 287 m_failed = true;290 setFailed(); 288 291 return false; 289 292 } else 290 m_infoHeader.biCompression = static_cast<CompressionType>(biCompression); 293 m_infoHeader.biCompression = 294 static_cast<CompressionType>(biCompression); 291 295 } 292 296 … … 472 476 // Fail if we don't have enough file space for the bitmasks. 473 477 static const size_t SIZEOF_BITMASKS = 12; 474 if (((m_headerOffset + m_infoHeader.biSize + SIZEOF_BITMASKS) < (m_headerOffset + m_infoHeader.biSize)) 475 || (m_imgDataOffset && (m_imgDataOffset < (m_headerOffset + m_infoHeader.biSize + SIZEOF_BITMASKS)))) { 476 m_failed = true; 478 if (((m_headerOffset + m_infoHeader.biSize + SIZEOF_BITMASKS) < 479 (m_headerOffset + m_infoHeader.biSize)) 480 || (m_imgDataOffset && (m_imgDataOffset < 481 (m_headerOffset + m_infoHeader.biSize + SIZEOF_BITMASKS)))) { 482 setFailed(); 477 483 return false; 478 484 } … … 502 508 // data (for example, bits 25-31 in a 24-bit RGB format). 503 509 if (m_infoHeader.biBitCount < 32) 504 m_bitMasks[i] &= ((static_cast<uint32_t>(1) << m_infoHeader.biBitCount) - 1); 510 m_bitMasks[i] &= 511 ((static_cast<uint32_t>(1) << m_infoHeader.biBitCount) - 1); 505 512 506 513 // For empty masks (common on the alpha channel, especially after the … … 516 523 for (int j = 0; j < i; ++j) { 517 524 if (tempMask & m_bitMasks[j]) { 518 m_failed = true;525 setFailed(); 519 526 return false; 520 527 } … … 531 538 // Make sure bitmask is contiguous. 532 539 if (tempMask) { 533 m_failed = true;540 setFailed(); 534 541 return false; 535 542 } … … 551 558 552 559 // Fail if we don't have enough file space for the color table. 553 if (((m_headerOffset + m_infoHeader.biSize + m_tableSizeInBytes) < (m_headerOffset + m_infoHeader.biSize)) 554 || (m_imgDataOffset && (m_imgDataOffset < (m_headerOffset + m_infoHeader.biSize + m_tableSizeInBytes)))) { 555 m_failed = true; 560 if (((m_headerOffset + m_infoHeader.biSize + m_tableSizeInBytes) < 561 (m_headerOffset + m_infoHeader.biSize)) 562 || (m_imgDataOffset && (m_imgDataOffset < 563 (m_headerOffset + m_infoHeader.biSize + m_tableSizeInBytes)))) { 564 setFailed(); 556 565 return false; 557 566 } … … 607 616 // Impossible to decode row-at-a-time, so just do things as a stream of 608 617 // bytes. 609 RGBA32Buffer & buffer =m_frameBufferCache.first();618 RGBA32Buffer* buffer = &m_frameBufferCache.first(); 610 619 while (true) { 611 620 // Every entry takes at least two bytes; bail if there isn't enough … … 619 628 const uint8_t code = data->data()[m_decodedOffset + 1]; 620 629 if (((count != 0) || (code != 1)) && pastEndOfImage(0)) { 621 m_failed = true;630 setFailed(); 622 631 return false; 623 632 } … … 629 638 // Skip any remaining pixels in this row. 630 639 if (m_coord.x() < size().width()) 631 buffer .setHasAlpha(true);640 buffer->setHasAlpha(true); 632 641 moveBufferToNextRow(); 633 642 … … 638 647 // Skip any remaining pixels in the image. 639 648 if ((m_coord.x() < size().width()) 640 || (m_isTopDown ? (m_coord.y() < (size().height() - 1)) : (m_coord.y() > 0))) 641 buffer.setHasAlpha(true); 649 || (m_isTopDown 650 ? (m_coord.y() < (size().height() - 1)) 651 : (m_coord.y() > 0))) 652 buffer->setHasAlpha(true); 642 653 return true; 643 654 … … 653 664 const uint8_t dy = data->data()[m_decodedOffset + 3]; 654 665 if ((dx != 0) || (dy != 0)) 655 buffer .setHasAlpha(true);666 buffer->setHasAlpha(true); 656 667 if (((m_coord.x() + dx) > size().width()) || 657 668 pastEndOfImage(dy)) { 658 m_failed = true;669 setFailed(); 659 670 return false; 660 671 } … … 706 717 if ((colorIndexes[0] >= m_infoHeader.biClrUsed) 707 718 || (colorIndexes[1] >= m_infoHeader.biClrUsed)) { 708 m_failed = true;719 setFailed(); 709 720 return false; 710 721 } … … 731 742 const int endX = m_coord.x() + numPixels; 732 743 if (endX > size().width()) { 733 m_failed = true;744 setFailed(); 734 745 return false; 735 746 } … … 749 760 // Decode as many rows as we can. (For RLE, where we only want to decode 750 761 // one row, we've already checked that this condition is true.) 751 RGBA32Buffer & buffer =m_frameBufferCache.first();762 RGBA32Buffer* buffer = &m_frameBufferCache.first(); 752 763 while (!pastEndOfImage(0)) { 753 764 // Bail if we don't have enough data for the desired number of pixels. … … 762 773 for (size_t byte = 0; byte < unpaddedNumBytes; ++byte) { 763 774 uint8_t pixelData = data->data()[m_decodedOffset + byte]; 764 for (size_t pixel = 0; (pixel < pixelsPerByte) && (m_coord.x() < endX); ++pixel) { 775 for (size_t pixel = 0; 776 (pixel < pixelsPerByte) && (m_coord.x() < endX); ++pixel) { 765 777 const size_t colorIndex = 766 778 (pixelData >> (8 - m_infoHeader.biBitCount)) & mask; … … 773 785 if (colorIndex) { 774 786 setRGBA(0, 0, 0, 0); 775 buffer .setHasAlpha(true);787 buffer->setHasAlpha(true); 776 788 } else 777 789 m_coord.move(1, 0); 778 790 } else { 779 791 if (colorIndex >= m_infoHeader.biClrUsed) { 780 m_failed = true;792 setFailed(); 781 793 return false; 782 794 } … … 807 819 m_seenNonZeroAlphaPixel = true; 808 820 if (m_seenZeroAlphaPixel) { 809 buffer .zeroFill();821 buffer->zeroFill(); 810 822 m_seenZeroAlphaPixel = false; 811 823 } else if (alpha != 255) 812 buffer .setHasAlpha(true);824 buffer->setHasAlpha(true); 813 825 } 814 826 -
trunk/WebCore/platform/image-decoders/bmp/BMPImageReader.h
r44634 r44833 51 51 virtual RGBA32Buffer* frameBufferAtIndex(size_t index); 52 52 53 // Read a value from |data[offset]|, converting from little to native 54 // endianness. 55 static inline uint16_t readUint16Helper(SharedBuffer* data, int offset) 56 { 57 uint16_t result; 58 memcpy(&result, &data->data()[offset], 2); 59 #if PLATFORM(BIG_ENDIAN) 60 result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8); 61 #endif 62 return result; 63 } 64 65 static inline uint32_t readUint32Helper(SharedBuffer* data, int offset) 66 { 67 uint32_t result; 68 memcpy(&result, &data->data()[offset], 4); 69 #if PLATFORM(BIG_ENDIAN) 70 result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) | 71 ((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24); 72 #endif 73 return result; 74 } 75 53 76 protected: 54 77 enum AndMaskState { … … 58 81 }; 59 82 60 // Decodes a single BMP, starting with an info header. 61 void decodeBMP(SharedBuffer* data); 62 63 // Read a value from |data[m_decodedOffset + additionalOffset]|, converting 64 // from little to native endianness. 65 inline uint16_t readUint16(SharedBuffer* data, int additionalOffset) const 66 { 67 uint16_t result; 68 memcpy(&result, &data->data()[m_decodedOffset + additionalOffset], 2); 69 #if PLATFORM(BIG_ENDIAN) 70 result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8); 71 #endif 72 return result; 73 } 74 75 inline uint32_t readUint32(SharedBuffer* data, int additionalOffset) const 76 { 77 uint32_t result; 78 memcpy(&result, &data->data()[m_decodedOffset + additionalOffset], 4); 79 #if PLATFORM(BIG_ENDIAN) 80 result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) | 81 ((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24); 82 #endif 83 return result; 84 } 83 // Does the actual decoding. Returns whether decoding succeeded. 84 bool decodeBMP(SharedBuffer* data); 85 85 86 86 // An index into |m_data| representing how much we've already decoded. … … 90 90 size_t m_headerOffset; 91 91 92 // The file offset at which the actual image bits start. When decoding ICO93 // files, this is set to 0, since it's not stored anywhere in a header; the94 // reader functions expect the image data to start immediately after the95 // header and (if necessary) color table.92 // The file offset at which the actual image bits start. When decoding 93 // ICO files, this is set to 0, since it's not stored anywhere in a 94 // header; the reader functions expect the image data to start 95 // immediately after the header and (if necessary) color table. 96 96 size_t m_imgDataOffset; 97 97 98 98 // ICOs store a 1bpp "mask" immediately after the main bitmap image data 99 99 // (and, confusingly, add its height to the biHeight value in the info 100 // header, thus doubling it). This variable tracks whether we have such a101 // mask and if we've started decoding it yet.100 // header, thus doubling it). This variable tracks whether we have such 101 // a mask and if we've started decoding it yet. 102 102 AndMaskState m_andMaskState; 103 103 104 104 private: 105 // The various BMP compression types. We don't currently decode all these. 105 // The various BMP compression types. We don't currently decode all 106 // these. 106 107 enum CompressionType { 107 108 // Universal types … … 118 119 }; 119 120 120 // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE structs,121 // but with unnecessary entries removed.121 // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE 122 // structs, but with unnecessary entries removed. 122 123 struct BitmapInfoHeader { 123 124 uint32_t biSize; … … 134 135 }; 135 136 136 // Determines the size of the BMP info header. Returns true if the size is 137 // valid. 137 inline uint16_t readUint16(SharedBuffer* data, int offset) const 138 { 139 return readUint16Helper(data, m_decodedOffset + offset); 140 } 141 142 inline uint32_t readUint32(SharedBuffer* data, int offset) const 143 { 144 return readUint32Helper(data, m_decodedOffset + offset); 145 } 146 147 // Determines the size of the BMP info header. Returns true if the size 148 // is valid. 138 149 bool getInfoHeaderSize(SharedBuffer* data); 139 150 140 // Processes the BMP info header. Returns true if the info header could be141 // decoded.151 // Processes the BMP info header. Returns true if the info header could 152 // be decoded. 142 153 bool processInfoHeader(SharedBuffer* data); 143 154 144 // Helper function for processInfoHeader() which does the actual reading of145 // header values from the byte stream. Returns false on error.155 // Helper function for processInfoHeader() which does the actual reading 156 // of header values from the byte stream. Returns false on error. 146 157 bool readInfoHeader(SharedBuffer* data); 147 158 … … 156 167 bool isInfoHeaderValid() const; 157 168 158 // For BI_BITFIELDS images, initializes the m_bitMasks[] and m_bitOffsets[]159 // arrays. processInfoHeader() will initialize these for other compression160 // types where needed.169 // For BI_BITFIELDS images, initializes the m_bitMasks[] and 170 // m_bitOffsets[] arrays. processInfoHeader() will initialize these for 171 // other compression types where needed. 161 172 bool processBitmasks(SharedBuffer* data); 162 173 163 // For paletted images, allocates and initializes the m_colorTable[] array. 174 // For paletted images, allocates and initializes the m_colorTable[] 175 // array. 164 176 bool processColorTable(SharedBuffer* data); 165 177 … … 173 185 // success. 174 186 // * inRLE = false: the data is inside a non-RLE-encoded bitmap. 175 // |numPixels| is ignored. Expects |m_coord| to point at the beginning 176 // of the next row to be decoded. Tries to process as many complete 177 // rows as possible. Returns true if the whole image was decoded. 187 // |numPixels| is ignored. Expects |m_coord| to point at the 188 // beginning of the next row to be decoded. Tries to process as 189 // many complete rows as possible. Returns true if the whole image 190 // was decoded. 178 191 bool processNonRLEData(SharedBuffer* data, bool inRLE, int numPixels); 179 192 180 193 // Returns true if the current y-coordinate plus |numRows| would be past 181 // the end of the image. Here "plus" means "toward the end of the image",182 // so downwards for m_isTopDown images and upwards otherwise.194 // the end of the image. Here "plus" means "toward the end of the 195 // image", so downwards for m_isTopDown images and upwards otherwise. 183 196 inline bool pastEndOfImage(int numRows) 184 197 { … … 191 204 // Assumes m_decodedOffset has been set to the beginning of the current 192 205 // row. 193 // NOTE: Only as many bytes of the return value as are needed to hold the194 // pixel data will actually be set.206 // NOTE: Only as many bytes of the return value as are needed to hold 207 // the pixel data will actually be set. 195 208 inline uint32_t readCurrentPixel(SharedBuffer* data, int bytesPerPixel) const 196 209 { … … 201 214 202 215 case 3: { 203 // It doesn't matter that we never set the most significant byte of204 // the return value here in little-endian mode, the caller won't205 // read it.216 // It doesn't matter that we never set the most significant byte 217 // of the return value here in little-endian mode, the caller 218 // won't read it. 206 219 uint32_t pixel; 207 220 memcpy(&pixel, … … 223 236 } 224 237 225 // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A) in226 // the given pixel data.238 // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A) 239 // in the given pixel data. 227 240 inline unsigned getComponent(uint32_t pixel, int component) const 228 241 { 229 return ((pixel & m_bitMasks[component]) >> m_bitShiftsRight[component])230 << m_bitShiftsLeft[component];242 return ((pixel & m_bitMasks[component]) >> 243 m_bitShiftsRight[component]) << m_bitShiftsLeft[component]; 231 244 } 232 245 … … 241 254 242 255 // Sets the current pixel to the color given by |colorIndex|. This also 243 // increments the relevant local variables to move the current pixel right244 // by one.256 // increments the relevant local variables to move the current pixel 257 // right by one. 245 258 inline void setI(size_t colorIndex) 246 259 { 247 setRGBA(m_colorTable[colorIndex].rgbRed, m_colorTable[colorIndex].rgbGreen, 260 setRGBA(m_colorTable[colorIndex].rgbRed, 261 m_colorTable[colorIndex].rgbGreen, 248 262 m_colorTable[colorIndex].rgbBlue, 0xff); 249 263 } 250 264 251 265 // Like setI(), but with the individual component values specified. 252 inline void setRGBA(unsigned red, unsigned green, unsigned blue, unsigned alpha) 266 inline void setRGBA(unsigned red, 267 unsigned green, 268 unsigned blue, 269 unsigned alpha) 253 270 { 254 271 m_frameBufferCache.first().setRGBA(m_coord.x(), m_coord.y(), red, green, blue, alpha); … … 257 274 258 275 // Fills pixels from the current X-coordinate up to, but not including, 259 // |endCoord| with the color given by the individual components. This also 260 // increments the relevant local variables to move the current pixel right 261 // to |endCoord|. 262 inline void fillRGBA(int endCoord, unsigned red, unsigned green, unsigned blue, unsigned alpha) 276 // |endCoord| with the color given by the individual components. This 277 // also increments the relevant local variables to move the current 278 // pixel right to |endCoord|. 279 inline void fillRGBA(int endCoord, 280 unsigned red, 281 unsigned green, 282 unsigned blue, 283 unsigned alpha) 263 284 { 264 285 while (m_coord.x() < endCoord) … … 266 287 } 267 288 268 // Resets the relevant local variables to start drawing at the left edge of269 // the "next" row, where "next" is above or below the current row depending270 // on the value of |m_isTopDown|.289 // Resets the relevant local variables to start drawing at the left edge 290 // of the "next" row, where "next" is above or below the current row 291 // depending on the value of |m_isTopDown|. 271 292 void moveBufferToNextRow(); 272 293 … … 274 295 BitmapInfoHeader m_infoHeader; 275 296 276 // True if this is an OS/2 1.x (aka Windows 2.x) BMP. The struct layouts277 // for this type of BMP are slightly different from the later, more common278 // formats.297 // True if this is an OS/2 1.x (aka Windows 2.x) BMP. The struct 298 // layouts for this type of BMP are slightly different from the later, 299 // more common formats. 279 300 bool m_isOS21x; 280 301 … … 282 303 // and 4 for this type of BMP differ from Windows V3+ BMPs. 283 304 // 284 // This will be falsely negative in some cases, but only ones where the way285 // w e misinterpret the data is irrelevant.305 // This will be falsely negative in some cases, but only ones where the 306 // way we misinterpret the data is irrelevant. 286 307 bool m_isOS22x; 287 308 … … 294 315 bool m_needToProcessColorTable; 295 316 296 // Masks/offsets for the color values for non-palette formats. These are 297 // bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B, A. 317 // Masks/offsets for the color values for non-palette formats. These 318 // are bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B, 319 // A. 298 320 // 299 321 // The right/left shift values are meant to be applied after the masks. 300 // We need to right shift to compensate for the bitfields' offsets into the 301 // 32 bits of pixel data, and left shift to scale the color values up for 302 // fields with less than 8 bits of precision. Sadly, we can't just combine 303 // these into one shift value because the net shift amount could go either 304 // direction. (If only "<< -x" were equivalent to ">> x"...) 322 // We need to right shift to compensate for the bitfields' offsets into 323 // the 32 bits of pixel data, and left shift to scale the color values 324 // up for fields with less than 8 bits of precision. Sadly, we can't 325 // just combine these into one shift value because the net shift amount 326 // could go either direction. (If only "<< -x" were equivalent to 327 // ">> x"...) 305 328 uint32_t m_bitMasks[4]; 306 329 int m_bitShiftsRight[4]; -
trunk/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp
r44825 r44833 40 40 static const size_t sizeOfDirEntry = 16; 41 41 42 ICOImageDecoder::ICOImageDecoder(const IntSize& preferredIconSize) 43 : BMPImageReader() 44 , m_preferredIconSize(preferredIconSize) 45 , m_imageType(Unknown) 46 { 47 m_andMaskState = NotYetDecoded; 48 } 49 50 bool ICOImageDecoder::isSizeAvailable() 51 { 52 return (m_imageType == PNG) ? 53 m_pngDecoder.isSizeAvailable() : BMPImageReader::isSizeAvailable(); 54 } 55 56 IntSize ICOImageDecoder::size() const 57 { 58 return (m_imageType == PNG) ? m_pngDecoder.size() : BMPImageReader::size(); 59 } 60 42 61 void ICOImageDecoder::decodeImage(SharedBuffer* data) 43 62 { … … 47 66 48 67 // Read and process directory entries. 49 if ((m_decodedOffset < (sizeOfDirectory + (m_directory.idCount * sizeOfDirEntry))) 68 if ((m_decodedOffset < 69 (sizeOfDirectory + (m_directory.idCount * sizeOfDirEntry))) 50 70 && !processDirectoryEntries(data)) 51 71 return; 52 72 53 // Check if this entry is a PNG; we need 4 bytes to check the magic number. 54 if (m_imageType == Unknown) { 55 if (data->size() < (m_dirEntry.dwImageOffset + 4)) 56 return; 57 m_imageType = 58 strncmp(&data->data()[m_dirEntry.dwImageOffset], "\x89PNG", 4) ? 59 BMP : PNG; 60 } 73 // Get the image type. 74 if ((m_imageType == Unknown) && !processImageType(data)) 75 return; 61 76 62 77 // Decode selected entry. … … 81 96 } 82 97 83 bool ICOImageDecoder::isSizeAvailable()84 {85 return (m_imageType == PNG) ? m_pngDecoder.isSizeAvailable() :86 BMPImageReader::isSizeAvailable();87 }88 89 IntSize ICOImageDecoder::size() const90 {91 return (m_imageType == PNG) ? m_pngDecoder.size() : BMPImageReader::size();92 }93 94 98 bool ICOImageDecoder::processDirectory(SharedBuffer* data) 95 99 { … … 110 114 if (((fileType != ICON) && (fileType != CURSOR)) || 111 115 (m_directory.idCount == 0)) 112 m_failed = true;113 114 return ! m_failed;116 setFailed(); 117 118 return !failed(); 115 119 } 116 120 … … 119 123 // Read directory entries. 120 124 ASSERT(m_decodedOffset == sizeOfDirectory); 121 if ((m_decodedOffset > data->size()) || (data->size() - m_decodedOffset) < 122 (m_directory.idCount * sizeOfDirEntry)) 125 if ((m_decodedOffset > data->size()) 126 || ((data->size() - m_decodedOffset) < 127 (m_directory.idCount * sizeOfDirEntry))) 123 128 return false; 124 129 for (int i = 0; i < m_directory.idCount; ++i) { … … 134 139 if ((m_dirEntry.dwImageOffset < m_decodedOffset) || 135 140 ((m_dirEntry.dwImageOffset + 4) < m_dirEntry.dwImageOffset)) { 136 m_failed = true;141 setFailed(); 137 142 return false; 138 143 } … … 190 195 // better. 191 196 if (entryArea != dirEntryArea) { 192 return (entryArea < dirEntryArea) 193 && (entryArea >=(m_preferredIconSize.width() * m_preferredIconSize.height()));197 return (entryArea < dirEntryArea) && (entryArea >= 198 (m_preferredIconSize.width() * m_preferredIconSize.height())); 194 199 } 195 200 } … … 201 206 // Higher bit-depth icons are better. 202 207 return (entry.wBitCount > m_dirEntry.wBitCount); 208 } 209 210 bool ICOImageDecoder::processImageType(SharedBuffer* data) 211 { 212 // Check if this entry is a BMP or a PNG; we need 4 bytes to check the magic 213 // number. 214 ASSERT(m_decodedOffset == m_dirEntry.dwImageOffset); 215 if ((m_decodedOffset > data->size()) 216 || ((data->size() - m_decodedOffset) < 4)) 217 return false; 218 m_imageType = 219 strncmp(&data->data()[m_decodedOffset], "\x89PNG", 4) ? BMP : PNG; 220 return true; 203 221 } 204 222 -
trunk/WebCore/platform/image-decoders/ico/ICOImageDecoder.h
r44825 r44833 41 41 public: 42 42 // See comments on |m_preferredIconSize| below. 43 ICOImageDecoder(const IntSize& preferredIconSize) 44 : m_preferredIconSize(preferredIconSize) 45 , m_imageType(Unknown) 46 { 47 m_andMaskState = NotYetDecoded; 48 } 43 ICOImageDecoder(const IntSize& preferredIconSize); 49 44 45 // ImageDecoder 50 46 virtual String filenameExtension() const { return "ico"; } 47 virtual bool isSizeAvailable(); 48 virtual IntSize size() const; 51 49 52 50 // BMPImageReader 53 51 virtual void decodeImage(SharedBuffer* data); 54 52 virtual RGBA32Buffer* frameBufferAtIndex(size_t index); 55 56 // ImageDecoder57 virtual bool isSizeAvailable();58 virtual IntSize size() const;59 53 60 54 private: … … 77 71 }; 78 72 79 // Processes the ICONDIR at the beginning of the data. Returns true if the 80 // directory could be decoded. 73 inline uint16_t readUint16(SharedBuffer* data, int offset) const 74 { 75 return readUint16Helper(data, m_decodedOffset + offset); 76 } 77 78 inline uint32_t readUint32(SharedBuffer* data, int offset) const 79 { 80 return readUint32Helper(data, m_decodedOffset + offset); 81 } 82 83 // Processes the ICONDIR at the beginning of the data. Returns true if 84 // the directory could be decoded. 81 85 bool processDirectory(SharedBuffer*); 82 86 83 87 // Processes the ICONDIRENTRY records after the directory. Keeps the 84 // "best" entry as the one we'll decode. Returns true if the entries could85 // be decoded.88 // "best" entry as the one we'll decode. Returns true if the entries 89 // could be decoded. 86 90 bool processDirectoryEntries(SharedBuffer*); 87 91 88 // Reads and returns a directory entry from the current offset into |data|. 92 // Reads and returns a directory entry from the current offset into 93 // |data|. 89 94 IconDirectoryEntry readDirectoryEntry(SharedBuffer*); 90 95 … … 92 97 // Larger sizes, or greater bitdepths at the same size, are preferable. 93 98 bool isBetterEntry(const IconDirectoryEntry&) const; 99 100 // Determines whether the desired entry is a BMP or PNG. Returns true 101 // if the type could be determined. 102 bool processImageType(SharedBuffer*); 94 103 95 104 // Called when the image to be decoded is a PNG rather than a BMP.
Note: See TracChangeset
for help on using the changeset viewer.