/*
 * 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.
 */

#pragma once

#include "ScalableImageDecoder.h"
#include <stdint.h>

namespace WebCore {

// This class decodes a BMP image. It is used in the BMP and ICO decoders,
// which wrap it in the appropriate code to read file headers, etc.
class BMPImageReader {
    WTF_MAKE_FAST_ALLOCATED;
public:
    // Read a value from |data[offset]|, converting from little to native
    // endianness.
    static inline uint16_t readUint16(const SharedBuffer::DataSegment& data, int offset)
    {
        uint16_t result;
        memcpy(&result, &data.data()[offset], 2);
#if CPU(BIG_ENDIAN)
        result = ((result & 0xff) << 8) | ((result & 0xff00) >> 8);
#endif
        return result;
    }

    static inline uint32_t readUint32(const SharedBuffer::DataSegment& data, int offset)
    {
        uint32_t result;
        memcpy(&result, &data.data()[offset], 4);
#if CPU(BIG_ENDIAN)
        result = ((result & 0xff) << 24) | ((result & 0xff00) << 8) | ((result & 0xff0000) >> 8) | ((result & 0xff000000) >> 24);
#endif
        return result;
    }

    // |parent| is the decoder that owns us.
    // |startOffset| points to the start of the BMP within the file.
    // |buffer| points at an empty ScalableImageDecoderFrame that we'll initialize and
    // fill with decoded data.
    BMPImageReader(ScalableImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool usesAndMask);

    void setBuffer(ScalableImageDecoderFrame* buffer) { m_buffer = buffer; }
    void setData(SharedBuffer::DataSegment& data) { m_data = &data; }

    // Does the actual decoding. If |onlySize| is true, decoding only
    // progresses as far as necessary to get the image size. Returns
    // whether decoding succeeded.
    bool decodeBMP(bool onlySize);

private:
    // The various BMP compression types. We don't currently decode all
    // these.
    enum CompressionType {
        // Universal types
        RGB = 0,
        RLE8 = 1,
        RLE4 = 2,
        // Windows V3+ only
        BITFIELDS = 3,
        JPEG = 4,
        PNG = 5,
        // OS/2 2.x-only
        HUFFMAN1D, // Stored in file as 3
        RLE24, // Stored in file as 4
    };
    enum AndMaskState {
        None,
        NotYetDecoded,
        Decoding,
    };
    enum ProcessingResult {
        Success,
        Failure,
        InsufficientData,
    };

    // These are based on the Windows BITMAPINFOHEADER and RGBTRIPLE
    // structs, but with unnecessary entries removed.
    struct BitmapInfoHeader {
        uint32_t biSize;
        int32_t biWidth;
        int32_t biHeight;
        uint16_t biBitCount;
        CompressionType biCompression;
        uint32_t biClrUsed;
    };
    struct RGBTriple {
        uint8_t rgbBlue;
        uint8_t rgbGreen;
        uint8_t rgbRed;
    };

    inline uint16_t readUint16(int offset) const
    {
        return readUint16(*m_data, m_decodedOffset + offset);
    }

    inline uint32_t readUint32(int offset) const
    {
        return readUint32(*m_data, m_decodedOffset + offset);
    }

    // Determines the size of the BMP info header. Returns true if the size
    // is valid.
    bool readInfoHeaderSize();

    // Processes the BMP info header. Returns true if the info header could
    // be decoded.
    bool processInfoHeader();

    // Helper function for processInfoHeader() which does the actual reading
    // of header values from the byte stream. Returns false on error.
    bool readInfoHeader();

    // Returns true if this is a Windows V4+ BMP.
    inline bool isWindowsV4Plus() const
    {
        // Windows V4 info header is 108 bytes. V5 is 124 bytes.
        return (m_infoHeader.biSize == 108) || (m_infoHeader.biSize == 124);
    }

    // Returns false if consistency errors are found in the info header.
    bool isInfoHeaderValid() const;

    // For BI_BITFIELDS images, initializes the m_bitMasks[] and
    // m_bitOffsets[] arrays. processInfoHeader() will initialize these for
    // other compression types where needed.
    bool processBitmasks();

    // For paletted images, allocates and initializes the m_colorTable[]
    // array.
    bool processColorTable();

    // Processes an RLE-encoded image. Returns true if the entire image was
    // decoded.
    bool processRLEData();

    // Processes a set of non-RLE-compressed pixels. Two cases:
    //   * inRLE = true: the data is inside an RLE-encoded bitmap. Tries to
    //     process |numPixels| pixels on the current row.
    //   * inRLE = false: the data is inside a non-RLE-encoded bitmap.
    //     |numPixels| is ignored. Expects |m_coord| to point at the
    //     beginning of the next row to be decoded. Tries to process as
    //     many complete rows as possible. Returns InsufficientData if
    //     there wasn't enough data to decode the whole image.
    //
    // This function returns a ProcessingResult instead of a bool so that it
    // can avoid calling m_parent->setFailed(), which could lead to memory
    // corruption since that will delete |this| but some callers still want
    // to access member variables after this returns.
    ProcessingResult processNonRLEData(bool inRLE, int numPixels);

    // Returns true if the current y-coordinate plus |numRows| would be past
    // the end of the image. Here "plus" means "toward the end of the
    // image", so downwards for m_isTopDown images and upwards otherwise.
    inline bool pastEndOfImage(int numRows)
    {
        return m_isTopDown ? ((m_coord.y() + numRows) >= m_parent->size().height()) : ((m_coord.y() - numRows) < 0);
    }

    // Returns the pixel data for the current X coordinate in a uint32_t.
    // Assumes m_decodedOffset has been set to the beginning of the current
    // row.
    // NOTE: Only as many bytes of the return value as are needed to hold
    // the pixel data will actually be set.
    inline uint32_t readCurrentPixel(int bytesPerPixel) const
    {
        const int offset = m_coord.x() * bytesPerPixel;
        switch (bytesPerPixel) {
        case 2:
            return readUint16(offset);

        case 3: {
            // It doesn't matter that we never set the most significant byte
            // of the return value here in little-endian mode, the caller
            // won't read it.
            uint32_t pixel;
            memcpy(&pixel, &m_data->data()[m_decodedOffset + offset], 3);
#if CPU(BIG_ENDIAN)
            pixel = ((pixel & 0xff00) << 8) | ((pixel & 0xff0000) >> 8) | ((pixel & 0xff000000) >> 24);
#endif
            return pixel;
        }

        case 4:
            return readUint32(offset);

        default:
            ASSERT_NOT_REACHED();
            return 0;
        }
    }

    // Returns the value of the desired component (0, 1, 2, 3 == R, G, B, A)
    // in the given pixel data.
    inline unsigned getComponent(uint32_t pixel, int component) const
    {
        return ((pixel & m_bitMasks[component]) >> m_bitShiftsRight[component]) << m_bitShiftsLeft[component];
    }

    inline unsigned getAlpha(uint32_t pixel) const
    {
        // For images without alpha, return alpha of 0xff.
        return m_bitMasks[3] ? getComponent(pixel, 3) : 0xff;
    }

    // Sets the current pixel to the color given by |colorIndex|. This also
    // increments the relevant local variables to move the current pixel
    // right by one.
    inline void setI(size_t colorIndex)
    {
        setPixel(m_colorTable[colorIndex].rgbRed, m_colorTable[colorIndex].rgbGreen, m_colorTable[colorIndex].rgbBlue, 0xff);
    }

    // Like setI(), but with the individual component values specified.
    inline void setPixel(unsigned red, unsigned green, unsigned blue, unsigned alpha)
    {
        m_buffer->backingStore()->setPixel(m_coord.x(), m_coord.y(), red, green, blue, alpha);
        m_coord.move(1, 0);
    }

    // Fills pixels from the current X-coordinate up to, but not including,
    // |endCoord| with the color given by the individual components. This
    // also increments the relevant local variables to move the current
    // pixel right to |endCoord|.
    inline void fillRGBA(int endCoord, unsigned red, unsigned green, unsigned blue, unsigned alpha)
    {
        if (endCoord <= m_coord.x())
            return;
        m_buffer->backingStore()->fillRect(IntRect(m_coord.x(), m_coord.y(), endCoord - m_coord.x(), 1), red, green, blue, alpha);
        m_coord.setX(endCoord);
    }

    // Resets the relevant local variables to start drawing at the left edge
    // of the "next" row, where "next" is above or below the current row
    // depending on the value of |m_isTopDown|.
    void moveBufferToNextRow();

    // The decoder that owns us.
    ScalableImageDecoder* m_parent;

    // The destination for the pixel data.
    ScalableImageDecoderFrame* m_buffer;

    // The file to decode.
    RefPtr<SharedBuffer::DataSegment> m_data;

    // An index into |m_data| representing how much we've already decoded.
    size_t m_decodedOffset;

    // The file offset at which the BMP info header starts.
    size_t m_headerOffset;

    // The file offset at which the actual image bits start. When decoding
    // ICO files, this is set to 0, since it's not stored anywhere in a
    // header; the reader functions expect the image data to start
    // immediately after the header and (if necessary) color table.
    size_t m_imgDataOffset;

    // The BMP info header.
    BitmapInfoHeader m_infoHeader;

    // True if this is an OS/2 1.x (aka Windows 2.x) BMP. The struct
    // layouts for this type of BMP are slightly different from the later,
    // more common formats.
    bool m_isOS21x;

    // True if this is an OS/2 2.x BMP. The meanings of compression types 3
    // and 4 for this type of BMP differ from Windows V3+ BMPs.
    //
    // This will be falsely negative in some cases, but only ones where the
    // way we misinterpret the data is irrelevant.
    bool m_isOS22x;

    // True if the BMP is not vertically flipped, that is, the first line of
    // raster data in the file is the top line of the image.
    bool m_isTopDown;

    // These flags get set to false as we finish each processing stage.
    bool m_needToProcessBitmasks;
    bool m_needToProcessColorTable;

    // Masks/offsets for the color values for non-palette formats. These
    // are bitwise, with array entries 0, 1, 2, 3 corresponding to R, G, B,
    // A.
    //
    // The right/left shift values are meant to be applied after the masks.
    // We need to right shift to compensate for the bitfields' offsets into
    // the 32 bits of pixel data, and left shift to scale the color values
    // up for fields with less than 8 bits of precision. Sadly, we can't
    // just combine these into one shift value because the net shift amount
    // could go either direction. (If only "<< -x" were equivalent to
    // ">> x"...)
    uint32_t m_bitMasks[4];
    int m_bitShiftsRight[4];
    int m_bitShiftsLeft[4];

    // The color palette, for paletted formats.
    size_t m_tableSizeInBytes;
    Vector<RGBTriple> m_colorTable;

    // The coordinate to which we've decoded the image.
    IntPoint m_coord;

    // Variables that track whether we've seen pixels with alpha values != 0
    // and == 0, respectively. See comments in processNonRLEData() on how
    // these are used.
    bool m_seenNonZeroAlphaPixel;
    bool m_seenZeroAlphaPixel;

    // ICOs store a 1bpp "mask" immediately after the main bitmap image data
    // (and, confusingly, add its height to the biHeight value in the info
    // header, thus doubling it). This variable tracks whether we have such
    // a mask and if we've started decoding it yet.
    AndMaskState m_andMaskState;
};

} // namespace WebCore
