| 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 #include "config.h" | |
| 32 #include "core/platform/image-decoders/bmp/BMPImageDecoder.h" | |
| 33 | |
| 34 #include "platform/PlatformInstrumentation.h" | |
| 35 #include "wtf/PassOwnPtr.h" | |
| 36 | |
| 37 namespace WebCore { | |
| 38 | |
| 39 // Number of bits in .BMP used to store the file header (doesn't match | |
| 40 // "sizeof(BMPImageDecoder::BitmapFileHeader)" since we omit some fields and | |
| 41 // don't pack). | |
| 42 static const size_t sizeOfFileHeader = 14; | |
| 43 | |
| 44 BMPImageDecoder::BMPImageDecoder(ImageSource::AlphaOption alphaOption, | |
| 45 ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption, | |
| 46 size_t maxDecodedBytes) | |
| 47 : ImageDecoder(alphaOption, gammaAndColorProfileOption, maxDecodedBytes) | |
| 48 , m_decodedOffset(0) | |
| 49 { | |
| 50 } | |
| 51 | |
| 52 void BMPImageDecoder::setData(SharedBuffer* data, bool allDataReceived) | |
| 53 { | |
| 54 if (failed()) | |
| 55 return; | |
| 56 | |
| 57 ImageDecoder::setData(data, allDataReceived); | |
| 58 if (m_reader) | |
| 59 m_reader->setData(data); | |
| 60 } | |
| 61 | |
| 62 bool BMPImageDecoder::isSizeAvailable() | |
| 63 { | |
| 64 if (!ImageDecoder::isSizeAvailable()) | |
| 65 decode(true); | |
| 66 | |
| 67 return ImageDecoder::isSizeAvailable(); | |
| 68 } | |
| 69 | |
| 70 ImageFrame* BMPImageDecoder::frameBufferAtIndex(size_t index) | |
| 71 { | |
| 72 if (index) | |
| 73 return 0; | |
| 74 | |
| 75 if (m_frameBufferCache.isEmpty()) { | |
| 76 m_frameBufferCache.resize(1); | |
| 77 m_frameBufferCache.first().setPremultiplyAlpha(m_premultiplyAlpha); | |
| 78 } | |
| 79 | |
| 80 ImageFrame* buffer = &m_frameBufferCache.first(); | |
| 81 if (buffer->status() != ImageFrame::FrameComplete) { | |
| 82 PlatformInstrumentation::willDecodeImage("BMP"); | |
| 83 decode(false); | |
| 84 PlatformInstrumentation::didDecodeImage(); | |
| 85 } | |
| 86 return buffer; | |
| 87 } | |
| 88 | |
| 89 bool BMPImageDecoder::setFailed() | |
| 90 { | |
| 91 m_reader.clear(); | |
| 92 return ImageDecoder::setFailed(); | |
| 93 } | |
| 94 | |
| 95 void BMPImageDecoder::decode(bool onlySize) | |
| 96 { | |
| 97 if (failed()) | |
| 98 return; | |
| 99 | |
| 100 // If we couldn't decode the image but we've received all the data, decoding | |
| 101 // has failed. | |
| 102 if (!decodeHelper(onlySize) && isAllDataReceived()) | |
| 103 setFailed(); | |
| 104 // If we're done decoding the image, we don't need the BMPImageReader | |
| 105 // anymore. (If we failed, |m_reader| has already been cleared.) | |
| 106 else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache.first().status
() == ImageFrame::FrameComplete)) | |
| 107 m_reader.clear(); | |
| 108 } | |
| 109 | |
| 110 bool BMPImageDecoder::decodeHelper(bool onlySize) | |
| 111 { | |
| 112 size_t imgDataOffset = 0; | |
| 113 if ((m_decodedOffset < sizeOfFileHeader) && !processFileHeader(&imgDataOffse
t)) | |
| 114 return false; | |
| 115 | |
| 116 if (!m_reader) { | |
| 117 m_reader = adoptPtr(new BMPImageReader(this, m_decodedOffset, imgDataOff
set, false)); | |
| 118 m_reader->setData(m_data.get()); | |
| 119 } | |
| 120 | |
| 121 if (!m_frameBufferCache.isEmpty()) | |
| 122 m_reader->setBuffer(&m_frameBufferCache.first()); | |
| 123 | |
| 124 return m_reader->decodeBMP(onlySize); | |
| 125 } | |
| 126 | |
| 127 bool BMPImageDecoder::processFileHeader(size_t* imgDataOffset) | |
| 128 { | |
| 129 ASSERT(imgDataOffset); | |
| 130 | |
| 131 // Read file header. | |
| 132 ASSERT(!m_decodedOffset); | |
| 133 if (m_data->size() < sizeOfFileHeader) | |
| 134 return false; | |
| 135 const uint16_t fileType = (m_data->data()[0] << 8) | static_cast<uint8_t>(m_
data->data()[1]); | |
| 136 *imgDataOffset = readUint32(10); | |
| 137 m_decodedOffset = sizeOfFileHeader; | |
| 138 | |
| 139 // See if this is a bitmap filetype we understand. | |
| 140 enum { | |
| 141 BMAP = 0x424D, // "BM" | |
| 142 // The following additional OS/2 2.x header values (see | |
| 143 // http://www.fileformat.info/format/os2bmp/egff.htm ) aren't widely | |
| 144 // decoded, and are unlikely to be in much use. | |
| 145 /* | |
| 146 ICON = 0x4943, // "IC" | |
| 147 POINTER = 0x5054, // "PT" | |
| 148 COLORICON = 0x4349, // "CI" | |
| 149 COLORPOINTER = 0x4350, // "CP" | |
| 150 BITMAPARRAY = 0x4241, // "BA" | |
| 151 */ | |
| 152 }; | |
| 153 return (fileType == BMAP) || setFailed(); | |
| 154 } | |
| 155 | |
| 156 } // namespace WebCore | |
| OLD | NEW |