15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (c) 2008, 2009, Google Inc. All rights reserved. 302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met: 702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions of source code must retain the above copyright 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer. 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Redistributions in binary form must reproduce the above 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution. 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * * Neither the name of Google Inc. nor the names of its 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission. 1702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 32a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/image-decoders/bmp/BMPImageDecoder.h" 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "platform/PlatformInstrumentation.h" 357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/PassOwnPtr.h" 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Number of bits in .BMP used to store the file header (doesn't match 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// "sizeof(BMPImageDecoder::BitmapFileHeader)" since we omit some fields and 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// don't pack). 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const size_t sizeOfFileHeader = 14; 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)BMPImageDecoder::BMPImageDecoder(ImageSource::AlphaOption alphaOption, 458abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles) ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption, 4606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) size_t maxDecodedBytes) 4706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) : ImageDecoder(alphaOption, gammaAndColorProfileOption, maxDecodedBytes) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_decodedOffset(0) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BMPImageDecoder::setData(SharedBuffer* data, bool allDataReceived) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (failed()) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ImageDecoder::setData(data, allDataReceived); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_reader) 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reader->setData(data); 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool BMPImageDecoder::isSizeAvailable() 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!ImageDecoder::isSizeAvailable()) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) decode(true); 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ImageDecoder::isSizeAvailable(); 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ImageFrame* BMPImageDecoder::frameBufferAtIndex(size_t index) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (index) 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_frameBufferCache.isEmpty()) { 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_frameBufferCache.resize(1); 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_frameBufferCache.first().setPremultiplyAlpha(m_premultiplyAlpha); 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ImageFrame* buffer = &m_frameBufferCache.first(); 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (buffer->status() != ImageFrame::FrameComplete) { 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PlatformInstrumentation::willDecodeImage("BMP"); 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) decode(false); 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PlatformInstrumentation::didDecodeImage(); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return buffer; 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool BMPImageDecoder::setFailed() 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reader.clear(); 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ImageDecoder::setFailed(); 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void BMPImageDecoder::decode(bool onlySize) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (failed()) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we couldn't decode the image but we've received all the data, decoding 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // has failed. 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!decodeHelper(onlySize) && isAllDataReceived()) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) setFailed(); 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we're done decoding the image, we don't need the BMPImageReader 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // anymore. (If we failed, |m_reader| has already been cleared.) 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache.first().status() == ImageFrame::FrameComplete)) 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reader.clear(); 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool BMPImageDecoder::decodeHelper(bool onlySize) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) size_t imgDataOffset = 0; 1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if ((m_decodedOffset < sizeOfFileHeader) && !processFileHeader(imgDataOffset)) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_reader) { 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reader = adoptPtr(new BMPImageReader(this, m_decodedOffset, imgDataOffset, false)); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reader->setData(m_data.get()); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_frameBufferCache.isEmpty()) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_reader->setBuffer(&m_frameBufferCache.first()); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_reader->decodeBMP(onlySize); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool BMPImageDecoder::processFileHeader(size_t& imgDataOffset) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Read file header. 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_decodedOffset); 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_data->size() < sizeOfFileHeader) 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const uint16_t fileType = (m_data->data()[0] << 8) | static_cast<uint8_t>(m_data->data()[1]); 1347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci imgDataOffset = readUint32(10); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_decodedOffset = sizeOfFileHeader; 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See if this is a bitmap filetype we understand. 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) enum { 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BMAP = 0x424D, // "BM" 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The following additional OS/2 2.x header values (see 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // http://www.fileformat.info/format/os2bmp/egff.htm ) aren't widely 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // decoded, and are unlikely to be in much use. 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) /* 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ICON = 0x4943, // "IC" 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) POINTER = 0x5054, // "PT" 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) COLORICON = 0x4349, // "CI" 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) COLORPOINTER = 0x4350, // "CP" 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) BITMAPARRAY = 0x4241, // "BA" 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) }; 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (fileType == BMAP) || setFailed(); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 154c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 155