⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bmpimagereader.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 2008, 2009, Google Inc. All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: *  *     * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. *     * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. *     * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "BMPImageReader.h"namespace WebCore {BMPImageReader::BMPImageReader()    : m_decodedOffset(0)    , m_headerOffset(0)    , m_imgDataOffset(0)    , m_andMaskState(None)    , m_isOS21x(false)    , m_isOS22x(false)    , m_isTopDown(false)    , m_needToProcessBitmasks(false)    , m_needToProcessColorTable(false)    , m_tableSizeInBytes(0)    , m_seenNonZeroAlphaPixel(false)    , m_seenZeroAlphaPixel(false){    m_frameBufferCache.resize(1);    // Clue-in decodeBMP() that we need to detect the correct info header size.    memset(&m_infoHeader, 0, sizeof(m_infoHeader));}void BMPImageReader::setData(SharedBuffer* data, bool allDataReceived){    ImageDecoder::setData(data, allDataReceived);    // NOTE: This function intentionally uses frameBufferAtIndex() instead of    // checking m_frameBufferCache.first() directly, so that it will do the    // right thing for ICOImageDecoder, which needs to override this accessor    // to support ICOs which contain PNGs.    // Return quickly when we can't do any more work.    if (m_failed || data->isEmpty()        || (frameBufferAtIndex(0)->status() == RGBA32Buffer::FrameComplete))        return;    // Decode as much as we can.  This assumes |data| starts at the beginning    // of the image data, rather than containing just the latest chunk.    decodeImage(data);    if (m_failed) {        // Handle failure before getting the framebuffer below.        m_colorTable.clear();        return;    }    // If we got all the data but couldn't finish decoding, fail.    const bool finished =        (frameBufferAtIndex(0)->status() == RGBA32Buffer::FrameComplete);    if (allDataReceived && !finished)        m_failed = true;    // Release the color table when we no longer need it.    if (finished || m_failed)        m_colorTable.clear();}RGBA32Buffer* BMPImageReader::frameBufferAtIndex(size_t index){    return index ? 0 : &m_frameBufferCache.first();}void BMPImageReader::decodeBMP(SharedBuffer* data){    // Calculate size of info header.    if (!m_infoHeader.biSize && !getInfoHeaderSize(data))        return;    // Read and process info header.    if ((m_decodedOffset < (m_headerOffset + m_infoHeader.biSize))        && !processInfoHeader(data))        return;    // Read and process the bitmasks, if needed.    if (m_needToProcessBitmasks && !processBitmasks(data))        return;    // Read and process the color table, if needed.    if (m_needToProcessColorTable && !processColorTable(data))        return;    // Initialize frame buffer state, if needed.    if (m_frameBufferCache.first().status() == RGBA32Buffer::FrameEmpty) {        m_frameBufferCache.first().setRect(IntRect(IntPoint(), size()));        m_frameBufferCache.first().setStatus(RGBA32Buffer::FramePartial);        if (!m_frameBufferCache.first().setSize(m_infoHeader.biWidth,                                                m_infoHeader.biHeight)) {            // Unable to allocate.            m_failed = true;            return;        }        // setSize() calls eraseARGB(), which resets the alpha flag, so we force        // it back to false here.  We'll set it true below in all cases where        // these 0s could actually show through.        m_frameBufferCache.first().setHasAlpha(false);        if (!m_isTopDown)            m_coord.setY(size().height() - 1);    }    // Decode the data.    if ((m_andMaskState != Decoding) && !pastEndOfImage(0)) {        if ((m_infoHeader.biCompression == RLE4)            || (m_infoHeader.biCompression == RLE8)            || (m_infoHeader.biCompression == RLE24)) {            if (!processRLEData(data))                return;        } else if (!processNonRLEData(data, false, 0))            return;    }    // If the image has an AND mask and there was no alpha data, process the    // mask.    if ((m_andMaskState == NotYetDecoded)        && !m_frameBufferCache.first().hasAlpha()) {        // Reset decoding coordinates to start of image.        m_coord.setX(0);        m_coord.setY(m_isTopDown ? 0 : (size().height() - 1));        // The AND mask is stored as 1-bit data.        m_infoHeader.biBitCount = 1;        m_andMaskState = Decoding;    }    if ((m_andMaskState == Decoding) && !processNonRLEData(data, false, 0))        return;    // Done!    m_frameBufferCache.first().setStatus(RGBA32Buffer::FrameComplete);}bool BMPImageReader::getInfoHeaderSize(SharedBuffer* data){    // Get size of info header.    ASSERT(m_decodedOffset == m_headerOffset);    if ((m_decodedOffset > data->size())        || ((data->size() - m_decodedOffset) < 4))        return false;    m_infoHeader.biSize = readUint32(data, 0);    // Don't increment m_decodedOffset here, it just makes the code in    // processInfoHeader() more confusing.    // Don't allow the header to overflow (which would be harmless here, but    // problematic or at least confusing in other places), or to overrun the    // image data.    if (((m_headerOffset + m_infoHeader.biSize) < m_headerOffset)        || (m_imgDataOffset            && (m_imgDataOffset < (m_headerOffset + m_infoHeader.biSize)))) {        m_failed = true;        return false;    }    // See if this is a header size we understand:    // OS/2 1.x: 12    if (m_infoHeader.biSize == 12)        m_isOS21x = true;    // Windows V3: 40    else if ((m_infoHeader.biSize == 40) || isWindowsV4Plus())        ;    // OS/2 2.x: any multiple of 4 between 16 and 64, inclusive, or 42 or 46    else if ((m_infoHeader.biSize >= 16) && (m_infoHeader.biSize <= 64)             && (((m_infoHeader.biSize & 3) == 0) || (m_infoHeader.biSize == 42)                 || (m_infoHeader.biSize == 46)))        m_isOS22x = true;    else        m_failed = true;    return !m_failed;}bool BMPImageReader::processInfoHeader(SharedBuffer* data){    // Read info header.    ASSERT(m_decodedOffset == m_headerOffset);    if ((m_decodedOffset > data->size())        || ((data->size() - m_decodedOffset) < m_infoHeader.biSize)        || !readInfoHeader(data))        return false;    m_decodedOffset += m_infoHeader.biSize;    // Sanity-check header values.    if (!isInfoHeaderValid()) {        m_failed = true;        return false;    }    // Make our size available to the caller.    if (!setSize(m_infoHeader.biWidth, m_infoHeader.biHeight)) {        m_failed = true;        return false;    }    // For paletted images, bitmaps can set biClrUsed to 0 to mean "all    // colors", so set it to the maximum number of colors for this bit depth.    // Also do this for bitmaps that put too large a value here.    if (m_infoHeader.biBitCount < 16) {      const uint32_t maxColors =          static_cast<uint32_t>(1) << m_infoHeader.biBitCount;      if ((m_infoHeader.biClrUsed == 0)          || (m_infoHeader.biClrUsed > maxColors))        m_infoHeader.biClrUsed = maxColors;    }    // For any bitmaps that set their BitCount to the wrong value, reset the    // counts now that we've calculated the number of necessary colors, since    // other code relies on this value being correct.    if (m_infoHeader.biCompression == RLE8)        m_infoHeader.biBitCount = 8;    else if (m_infoHeader.biCompression == RLE4)        m_infoHeader.biBitCount = 4;    // Tell caller what still needs to be processed.    if (m_infoHeader.biBitCount >= 16)        m_needToProcessBitmasks = true;    else if (m_infoHeader.biBitCount > 0)        m_needToProcessColorTable = true;    return true;}bool BMPImageReader::readInfoHeader(SharedBuffer* data){    // Pre-initialize some fields that not all headers set.    m_infoHeader.biCompression = RGB;    m_infoHeader.biClrUsed = 0;    if (m_isOS21x) {        m_infoHeader.biWidth = readUint16(data, 4);        m_infoHeader.biHeight = readUint16(data, 6);        ASSERT(m_andMaskState == None);  // ICO is a Windows format, not OS/2!        m_infoHeader.biBitCount = readUint16(data, 10);        return true;    }    m_infoHeader.biWidth = readUint32(data, 4);    m_infoHeader.biHeight = readUint32(data, 8);    if (m_andMaskState != None)        m_infoHeader.biHeight /= 2;    m_infoHeader.biBitCount = readUint16(data, 14);    // Read compression type, if present.    if (m_infoHeader.biSize >= 20) {        uint32_t biCompression = readUint32(data, 16);        // Detect OS/2 2.x-specific compression types.        if ((biCompression == 3) && (m_infoHeader.biBitCount == 1)) {            m_infoHeader.biCompression = HUFFMAN1D;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -