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

#ifndef SKY_ENGINE_PLATFORM_IMAGE_DECODERS_BMP_BMPIMAGEREADER_H_
#define SKY_ENGINE_PLATFORM_IMAGE_DECODERS_BMP_BMPIMAGEREADER_H_

#include <stdint.h>
#include "platform/image-decoders/ImageDecoder.h"
#include "sky/engine/wtf/CPU.h"

namespace blink {

// 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 PLATFORM_EXPORT BMPImageReader {
    WTF_MAKE_FAST_ALLOCATED;
public:
    // Read a value from |data[offset]|, converting from little to native
    // endianness.
    static inline uint16_t readUint16(SharedBuffer* 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(SharedBuffer* 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 ImageFrame that we'll initialize and
    // fill with decoded data.
    BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool isInICO);

    void setBuffer(ImageFrame* buffer) { m_buffer = buffer; }
    void setData(SharedBuffer* 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 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.get(), m_decodedOffset + offset);
    }

    inline uint32_t readUint32(int offset) const
    {
        return readUint32(m_data.get(), 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
    {
        uint8_t value = (pixel & m_bitMasks[component]) >> m_bitShiftsRight[component];
        return m_lookupTableAddresses[component] ? m_lookupTableAddresses[component][value] : value;
    }

    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)
    {
        setRGBA(m_colorTable[colorIndex].rgbRed, m_colorTable[colorIndex].rgbGreen, m_colorTable[colorIndex].rgbBlue, 0xff);
    }

    // Like setI(), but with the individual component values specified.
    inline void setRGBA(unsigned red,
                        unsigned green,
                        unsigned blue,
                        unsigned alpha)
    {
        m_buffer->setRGBA(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)
    {
        while (m_coord.x() < endCoord)
            setRGBA(red, green, blue, alpha);
    }

    // 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.
    ImageDecoder* m_parent;

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

    // The file to decode.
    RefPtr<SharedBuffer> 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.
    uint32_t m_bitMasks[4];

    // Right shift values, meant to be applied after the masks. We need to shift
    // the bitfield values down from their offsets into the 32 bits of pixel
    // data, as well as truncate the least significant bits of > 8-bit fields.
    int m_bitShiftsRight[4];

    // We use a lookup table to convert < 8-bit values into 8-bit values. The
    // values in the table are "round(val * 255.0 / ((1 << n) - 1))" for an
    // n-bit source value. These elements are set to 0 for 8-bit sources.
    const uint8_t* m_lookupTableAddresses[4];

    // The color palette, for paletted formats.
    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;

    // BMPs-in-ICOs have a few differences from standalone BMPs, so we need to
    // know if we're in an ICO container.
    bool m_isInICO;

    // 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). If |m_isInICO| is true, this variable tracks
    // whether we've begun decoding this mask yet.
    bool m_decodingAndMask;
};

} // namespace blink

#endif  // SKY_ENGINE_PLATFORM_IMAGE_DECODERS_BMP_BMPIMAGEREADER_H_
