/*
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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_IMAGEFRAME_H_
#define SKY_ENGINE_PLATFORM_IMAGE_DECODERS_IMAGEFRAME_H_

#include "sky/engine/platform/geometry/IntRect.h"
#include "sky/engine/platform/graphics/skia/NativeImageSkia.h"
#include "sky/engine/platform/PlatformExport.h"
#include "sky/engine/wtf/Assertions.h"
#include "sky/engine/wtf/PassRefPtr.h"
#include "third_party/skia/include/core/SkColorPriv.h"

namespace blink {

// ImageFrame represents the decoded image data.  This buffer is what all
// decoders write a single frame into.
class PLATFORM_EXPORT ImageFrame {
public:
    enum Status { FrameEmpty, FramePartial, FrameComplete };
    enum DisposalMethod {
        // If you change the numeric values of these, make sure you audit
        // all users, as some users may cast raw values to/from these
        // constants.
        DisposeNotSpecified, // Leave frame in framebuffer
        DisposeKeep, // Leave frame in framebuffer
        DisposeOverwriteBgcolor, // Clear frame to fully transparent
        DisposeOverwritePrevious // Clear frame to previous framebuffer contents
    };
    // Indicates how non-opaque pixels in the current frame rectangle
    // are blended with those in the previous frame.
    // Notes:
    // * GIF always uses 'BlendAtopPreviousFrame'.
    // * WebP also uses the 'BlendAtopBgcolor' option. This is useful for
    //   cases where one wants to transform a few opaque pixels of the
    //   previous frame into non-opaque pixels in the current frame.
    enum AlphaBlendSource {
        // Blend non-opaque pixels atop the corresponding pixels in the
        // initial buffer state (i.e. any previous frame buffer after having
        // been properly disposed).
        BlendAtopPreviousFrame,

        // Blend non-opaque pixels against fully transparent (i.e. simply
        // overwrite the corresponding pixels).
        BlendAtopBgcolor,
    };
    typedef uint32_t PixelData;

    ImageFrame();

    ImageFrame(const ImageFrame& other) { operator=(other); }

    // For backends which refcount their data, this operator doesn't need to
    // create a new copy of the image data, only increase the ref count.
    ImageFrame& operator=(const ImageFrame& other);

    // These do not touch other metadata, only the raw pixel data.
    void clearPixelData();
    void zeroFillPixelData();
    void zeroFillFrameRect(const IntRect&);

    // Makes this frame have an independent copy of the provided image's
    // pixel data, so that modifications in one frame are not reflected in
    // the other.  Returns whether the copy succeeded.
    bool copyBitmapData(const ImageFrame&);

    // Copies the pixel data at [(startX, startY), (endX, startY)) to the
    // same X-coordinates on each subsequent row up to but not including
    // endY.
    void copyRowNTimes(int startX, int endX, int startY, int endY)
    {
        ASSERT(startX < width());
        ASSERT(endX <= width());
        ASSERT(startY < height());
        ASSERT(endY <= height());
        const int rowBytes = (endX - startX) * sizeof(PixelData);
        const PixelData* const startAddr = getAddr(startX, startY);
        for (int destY = startY + 1; destY < endY; ++destY)
            memcpy(getAddr(startX, destY), startAddr, rowBytes);
    }

    // Allocates space for the pixel data.  Must be called before any pixels
    // are written.  Must only be called once.  Returns whether allocation
    // succeeded.
    bool setSize(int newWidth, int newHeight);

    // Returns a caller-owned pointer to the underlying native image data.
    // (Actual use: This pointer will be owned by BitmapImage and freed in
    // FrameData::clear()).
    PassRefPtr<NativeImageSkia> asNewNativeImage() const;

    bool hasAlpha() const;
    const IntRect& originalFrameRect() const { return m_originalFrameRect; }
    Status status() const { return m_status; }
    unsigned duration() const { return m_duration; }
    DisposalMethod disposalMethod() const { return m_disposalMethod; }
    AlphaBlendSource alphaBlendSource() const { return m_alphaBlendSource; }
    bool premultiplyAlpha() const { return m_premultiplyAlpha; }
    SkBitmap::Allocator* allocator() const { return m_allocator; }
    const SkBitmap& getSkBitmap() const { return m_bitmap; }
    // Returns true if the pixels changed, but the bitmap has not yet been notified.
    bool pixelsChanged() const { return m_pixelsChanged; }

    size_t requiredPreviousFrameIndex() const
    {
        ASSERT(m_requiredPreviousFrameIndexValid);
        return m_requiredPreviousFrameIndex;
    }
#if ENABLE(ASSERT)
    bool requiredPreviousFrameIndexValid() const { return m_requiredPreviousFrameIndexValid; }
#endif
    void setHasAlpha(bool alpha);
    void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
    void setStatus(Status);
    void setDuration(unsigned duration) { m_duration = duration; }
    void setDisposalMethod(DisposalMethod disposalMethod) { m_disposalMethod = disposalMethod; }
    void setAlphaBlendSource(AlphaBlendSource alphaBlendSource) { m_alphaBlendSource = alphaBlendSource; }
    void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
    void setMemoryAllocator(SkBitmap::Allocator* allocator) { m_allocator = allocator; }
    void setSkBitmap(const SkBitmap& bitmap) { m_bitmap = bitmap; }
    // The pixelsChanged flag needs to be set when the raw pixel data was directly modified
    // (e.g. through a pointer or setRGBA). The flag is usually set after a batch of changes was made.
    void setPixelsChanged(bool pixelsChanged) { m_pixelsChanged = pixelsChanged; }

    void setRequiredPreviousFrameIndex(size_t previousFrameIndex)
    {
        m_requiredPreviousFrameIndex = previousFrameIndex;
#if ENABLE(ASSERT)
        m_requiredPreviousFrameIndexValid = true;
#endif
    }

    inline PixelData* getAddr(int x, int y)
    {
        return m_bitmap.getAddr32(x, y);
    }

    inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
    {
        setRGBA(getAddr(x, y), r, g, b, a);
    }

    inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
    {
        if (m_premultiplyAlpha)
            setRGBAPremultiply(dest, r, g, b, a);
        else
            *dest = SkPackARGB32NoCheck(a, r, g, b);
    }

    static const unsigned div255 = static_cast<unsigned>(1.0 / 255 * (1 << 24)) + 1;

    static inline void setRGBAPremultiply(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
    {
        if (a < 255) {
            if (!a) {
                *dest = 0;
                return;
            }

            unsigned alpha = a * div255;
            r = (r * alpha) >> 24;
            g = (g * alpha) >> 24;
            b = (b * alpha) >> 24;
        }

        // Call the "NoCheck" version since we may deliberately pass non-premultiplied
        // values, and we don't want an assert.
        *dest = SkPackARGB32NoCheck(a, r, g, b);
    }

    static inline void setRGBARaw(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
    {
        *dest = SkPackARGB32NoCheck(a, r, g, b);
    }

    // Notifies the SkBitmap if any pixels changed and resets the flag.
    inline void notifyBitmapIfPixelsChanged()
    {
        if (m_pixelsChanged)
            m_bitmap.notifyPixelsChanged();
        m_pixelsChanged = false;
    }

private:
    int width() const
    {
        return m_bitmap.width();
    }

    int height() const
    {
        return m_bitmap.height();
    }

    SkBitmap m_bitmap;
    SkBitmap::Allocator* m_allocator;
    bool m_hasAlpha;
    // This will always just be the entire buffer except for GIF or WebP
    // frames whose original rect was smaller than the overall image size.
    IntRect m_originalFrameRect;
    Status m_status;
    unsigned m_duration;
    DisposalMethod m_disposalMethod;
    AlphaBlendSource m_alphaBlendSource;
    bool m_premultiplyAlpha;
    // True if the pixels changed, but the bitmap has not yet been notified.
    bool m_pixelsChanged;

    // The frame that must be decoded before this frame can be decoded.
    // WTF::kNotFound if this frame doesn't require any previous frame.
    // This is used by ImageDecoder::clearCacheExceptFrame(), and will never
    // be read for image formats that do not have multiple frames.
    size_t m_requiredPreviousFrameIndex;
#if ENABLE(ASSERT)
    bool m_requiredPreviousFrameIndexValid;
#endif
};

} // namespace blink

#endif  // SKY_ENGINE_PLATFORM_IMAGE_DECODERS_IMAGEFRAME_H_
