168513a70bcd92384395513322f1b801e7bf9c729Steve Block/*
268513a70bcd92384395513322f1b801e7bf9c729Steve Block * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
368513a70bcd92384395513322f1b801e7bf9c729Steve Block * Copyright (C) 2007-2009 Torch Mobile Inc.
468513a70bcd92384395513322f1b801e7bf9c729Steve Block * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
568513a70bcd92384395513322f1b801e7bf9c729Steve Block *
668513a70bcd92384395513322f1b801e7bf9c729Steve Block * Redistribution and use in source and binary forms, with or without
768513a70bcd92384395513322f1b801e7bf9c729Steve Block * modification, are permitted provided that the following conditions
868513a70bcd92384395513322f1b801e7bf9c729Steve Block * are met:
968513a70bcd92384395513322f1b801e7bf9c729Steve Block * 1. Redistributions of source code must retain the above copyright
1068513a70bcd92384395513322f1b801e7bf9c729Steve Block *    notice, this list of conditions and the following disclaimer.
1168513a70bcd92384395513322f1b801e7bf9c729Steve Block * 2. Redistributions in binary form must reproduce the above copyright
1268513a70bcd92384395513322f1b801e7bf9c729Steve Block *    notice, this list of conditions and the following disclaimer in the
1368513a70bcd92384395513322f1b801e7bf9c729Steve Block *    documentation and/or other materials provided with the distribution.
1468513a70bcd92384395513322f1b801e7bf9c729Steve Block *
1568513a70bcd92384395513322f1b801e7bf9c729Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
1668513a70bcd92384395513322f1b801e7bf9c729Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1768513a70bcd92384395513322f1b801e7bf9c729Steve Block * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1868513a70bcd92384395513322f1b801e7bf9c729Steve Block * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
1968513a70bcd92384395513322f1b801e7bf9c729Steve Block * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2068513a70bcd92384395513322f1b801e7bf9c729Steve Block * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2168513a70bcd92384395513322f1b801e7bf9c729Steve Block * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2268513a70bcd92384395513322f1b801e7bf9c729Steve Block * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2368513a70bcd92384395513322f1b801e7bf9c729Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2468513a70bcd92384395513322f1b801e7bf9c729Steve Block * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2568513a70bcd92384395513322f1b801e7bf9c729Steve Block */
2668513a70bcd92384395513322f1b801e7bf9c729Steve Block
2768513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "config.h"
2868513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "Image.h"
2968513a70bcd92384395513322f1b801e7bf9c729Steve Block
3068513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "BitmapImage.h"
3168513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "GraphicsContext.h"
3268513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "ImageDecoder.h"
3368513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "NotImplemented.h"
3468513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "PlatformString.h"
3568513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "SharedBuffer.h"
3668513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "TransformationMatrix.h"
3768513a70bcd92384395513322f1b801e7bf9c729Steve Block#include "WinceGraphicsExtras.h"
3868513a70bcd92384395513322f1b801e7bf9c729Steve Block#include <wtf/OwnPtr.h>
3968513a70bcd92384395513322f1b801e7bf9c729Steve Block
4068513a70bcd92384395513322f1b801e7bf9c729Steve Block#include <windows.h>
4168513a70bcd92384395513322f1b801e7bf9c729Steve Block
4268513a70bcd92384395513322f1b801e7bf9c729Steve Blocknamespace WebCore {
4368513a70bcd92384395513322f1b801e7bf9c729Steve Block
4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben MurdochNativeImagePtr ImageFrame::asNewNativeImage() const
4568513a70bcd92384395513322f1b801e7bf9c729Steve Block{
4628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu    return SharedBitmap::create(m_backingStore, m_size, hasAlpha());
4768513a70bcd92384395513322f1b801e7bf9c729Steve Block}
4868513a70bcd92384395513322f1b801e7bf9c729Steve Block
4968513a70bcd92384395513322f1b801e7bf9c729Steve Blockbool FrameData::clear(bool clearMetaData)
5068513a70bcd92384395513322f1b801e7bf9c729Steve Block{
5168513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (clearMetaData)
5268513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_haveMetadata = false;
5368513a70bcd92384395513322f1b801e7bf9c729Steve Block
5468513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (m_frame) {
5568513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_frame = 0;
5668513a70bcd92384395513322f1b801e7bf9c729Steve Block        return true;
5768513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
5868513a70bcd92384395513322f1b801e7bf9c729Steve Block
5968513a70bcd92384395513322f1b801e7bf9c729Steve Block    return false;
6068513a70bcd92384395513322f1b801e7bf9c729Steve Block}
6168513a70bcd92384395513322f1b801e7bf9c729Steve Block
6268513a70bcd92384395513322f1b801e7bf9c729Steve Blockbool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size)
6368513a70bcd92384395513322f1b801e7bf9c729Steve Block{
6468513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!bmp)
6568513a70bcd92384395513322f1b801e7bf9c729Steve Block        return false;
6668513a70bcd92384395513322f1b801e7bf9c729Steve Block
6768513a70bcd92384395513322f1b801e7bf9c729Steve Block    BITMAP bmpInfo;
6868513a70bcd92384395513322f1b801e7bf9c729Steve Block    GetObject(bmp, sizeof(BITMAP), &bmpInfo);
6968513a70bcd92384395513322f1b801e7bf9c729Steve Block
7068513a70bcd92384395513322f1b801e7bf9c729Steve Block    ASSERT(bmpInfo.bmBitsPixel == 32);
7168513a70bcd92384395513322f1b801e7bf9c729Steve Block    int bufferSize = bmpInfo.bmWidthBytes * bmpInfo.bmHeight;
7268513a70bcd92384395513322f1b801e7bf9c729Steve Block
7368513a70bcd92384395513322f1b801e7bf9c729Steve Block    OwnPtr<HDC> hdc(CreateCompatibleDC(0));
7468513a70bcd92384395513322f1b801e7bf9c729Steve Block    HGDIOBJ hOldBmp = SelectObject(hdc.get(), bmp);
7568513a70bcd92384395513322f1b801e7bf9c729Steve Block
7668513a70bcd92384395513322f1b801e7bf9c729Steve Block    {
7768513a70bcd92384395513322f1b801e7bf9c729Steve Block        GraphicsContext gc(hdc.get());
7868513a70bcd92384395513322f1b801e7bf9c729Steve Block
7968513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntSize imageSize = BitmapImage::size();
8068513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (size)
81a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            drawFrameMatchingSourceSize(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), IntSize(*size), ColorSpaceDeviceRGB, CompositeCopy);
8268513a70bcd92384395513322f1b801e7bf9c729Steve Block        else
83a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch            draw(&gc, FloatRect(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight), FloatRect(0, 0, imageSize.width(), imageSize.height()), ColorSpaceDeviceRGB, CompositeCopy);
8468513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
8568513a70bcd92384395513322f1b801e7bf9c729Steve Block
8668513a70bcd92384395513322f1b801e7bf9c729Steve Block    SelectObject(hdc.get(), hOldBmp);
8768513a70bcd92384395513322f1b801e7bf9c729Steve Block
8868513a70bcd92384395513322f1b801e7bf9c729Steve Block    return true;
8968513a70bcd92384395513322f1b801e7bf9c729Steve Block}
9068513a70bcd92384395513322f1b801e7bf9c729Steve Block
9168513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid BitmapImage::drawFrameMatchingSourceSize(GraphicsContext* ctxt, const FloatRect& dstRect, const IntSize& srcSize, ColorSpace styleColorSpace, CompositeOperator compositeOp)
9268513a70bcd92384395513322f1b801e7bf9c729Steve Block{
9368513a70bcd92384395513322f1b801e7bf9c729Steve Block    int frames = frameCount();
9468513a70bcd92384395513322f1b801e7bf9c729Steve Block    for (int i = 0; i < frames; ++i) {
9568513a70bcd92384395513322f1b801e7bf9c729Steve Block        RefPtr<SharedBitmap> bmp = frameAtIndex(i);
9668513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (!bmp || bmp->height() != static_cast<unsigned>(srcSize.height()) || bmp->width() != static_cast<unsigned>(srcSize.width()))
9768513a70bcd92384395513322f1b801e7bf9c729Steve Block            continue;
9868513a70bcd92384395513322f1b801e7bf9c729Steve Block
9968513a70bcd92384395513322f1b801e7bf9c729Steve Block        size_t currentFrame = m_currentFrame;
10068513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_currentFrame = i;
10168513a70bcd92384395513322f1b801e7bf9c729Steve Block        draw(ctxt, dstRect, FloatRect(0, 0, srcSize.width(), srcSize.height()), styleColorSpace, compositeOp);
10268513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_currentFrame = currentFrame;
10368513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
10468513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
10568513a70bcd92384395513322f1b801e7bf9c729Steve Block
10668513a70bcd92384395513322f1b801e7bf9c729Steve Block    // No image of the correct size was found, fallback to drawing the current frame
10768513a70bcd92384395513322f1b801e7bf9c729Steve Block    IntSize imageSize = BitmapImage::size();
10868513a70bcd92384395513322f1b801e7bf9c729Steve Block    draw(ctxt, dstRect, FloatRect(0, 0, imageSize.width(), imageSize.height()), styleColorSpace, compositeOp);
10968513a70bcd92384395513322f1b801e7bf9c729Steve Block}
11068513a70bcd92384395513322f1b801e7bf9c729Steve Block
11168513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRectIn, ColorSpace styleColorSpace, CompositeOperator compositeOp)
11268513a70bcd92384395513322f1b801e7bf9c729Steve Block{
11368513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!m_source.initialized())
11468513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
11568513a70bcd92384395513322f1b801e7bf9c729Steve Block
11668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (mayFillWithSolidColor())
11768513a70bcd92384395513322f1b801e7bf9c729Steve Block        fillWithSolidColor(ctxt, dstRect, solidColor(), styleColorSpace, compositeOp);
11868513a70bcd92384395513322f1b801e7bf9c729Steve Block    else {
11968513a70bcd92384395513322f1b801e7bf9c729Steve Block        IntRect intSrcRect(srcRectIn);
12068513a70bcd92384395513322f1b801e7bf9c729Steve Block        RefPtr<SharedBitmap> bmp = frameAtIndex(m_currentFrame);
12168513a70bcd92384395513322f1b801e7bf9c729Steve Block
12268513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (bmp->width() != m_source.size().width()) {
12368513a70bcd92384395513322f1b801e7bf9c729Steve Block            double scaleFactor = static_cast<double>(bmp->width()) / m_source.size().width();
12468513a70bcd92384395513322f1b801e7bf9c729Steve Block
12568513a70bcd92384395513322f1b801e7bf9c729Steve Block            intSrcRect.setX(stableRound(srcRectIn.x() * scaleFactor));
12668513a70bcd92384395513322f1b801e7bf9c729Steve Block            intSrcRect.setWidth(stableRound(srcRectIn.width() * scaleFactor));
12768513a70bcd92384395513322f1b801e7bf9c729Steve Block            intSrcRect.setY(stableRound(srcRectIn.y() * scaleFactor));
12868513a70bcd92384395513322f1b801e7bf9c729Steve Block            intSrcRect.setHeight(stableRound(srcRectIn.height() * scaleFactor));
12968513a70bcd92384395513322f1b801e7bf9c729Steve Block        }
13068513a70bcd92384395513322f1b801e7bf9c729Steve Block        bmp->draw(ctxt, enclosingIntRect(dstRect), intSrcRect, styleColorSpace, compositeOp);
13168513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
13268513a70bcd92384395513322f1b801e7bf9c729Steve Block
13368513a70bcd92384395513322f1b801e7bf9c729Steve Block    startAnimation();
13468513a70bcd92384395513322f1b801e7bf9c729Steve Block}
13568513a70bcd92384395513322f1b801e7bf9c729Steve Block
13668513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform,
13768513a70bcd92384395513322f1b801e7bf9c729Steve Block                        const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
13868513a70bcd92384395513322f1b801e7bf9c729Steve Block{
13968513a70bcd92384395513322f1b801e7bf9c729Steve Block    notImplemented();
14068513a70bcd92384395513322f1b801e7bf9c729Steve Block}
14168513a70bcd92384395513322f1b801e7bf9c729Steve Block
14268513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid BitmapImage::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRectIn, const AffineTransform& patternTransform,
14368513a70bcd92384395513322f1b801e7bf9c729Steve Block                        const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
14468513a70bcd92384395513322f1b801e7bf9c729Steve Block{
14568513a70bcd92384395513322f1b801e7bf9c729Steve Block    RefPtr<SharedBitmap> bmp = nativeImageForCurrentFrame();
14668513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!bmp)
14768513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
14868513a70bcd92384395513322f1b801e7bf9c729Steve Block
14968513a70bcd92384395513322f1b801e7bf9c729Steve Block    bmp->drawPattern(ctxt, tileRectIn, patternTransform, phase, styleColorSpace, op, destRect, m_source.size());
15068513a70bcd92384395513322f1b801e7bf9c729Steve Block}
15168513a70bcd92384395513322f1b801e7bf9c729Steve Block
15268513a70bcd92384395513322f1b801e7bf9c729Steve Blockvoid BitmapImage::checkForSolidColor()
15368513a70bcd92384395513322f1b801e7bf9c729Steve Block{
15468513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (m_checkedForSolidColor)
15568513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
15668513a70bcd92384395513322f1b801e7bf9c729Steve Block
15768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (frameCount() != 1) {
15868513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_isSolidColor = false;
15968513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_checkedForSolidColor = true;
16068513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
16168513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
16268513a70bcd92384395513322f1b801e7bf9c729Steve Block
16368513a70bcd92384395513322f1b801e7bf9c729Steve Block    RefPtr<SharedBitmap> bmp = frameAtIndex(0);
16468513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (!bmp || !bmp->validHeight()) {
16568513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_isSolidColor = false;
16668513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
16768513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
16868513a70bcd92384395513322f1b801e7bf9c729Steve Block
16968513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (bmp->width() != 1 || bmp->validHeight() != 1) {
17068513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_isSolidColor = false;
17168513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_checkedForSolidColor = true;
17268513a70bcd92384395513322f1b801e7bf9c729Steve Block        return;
17368513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
17468513a70bcd92384395513322f1b801e7bf9c729Steve Block
17568513a70bcd92384395513322f1b801e7bf9c729Steve Block    m_isSolidColor = true;
17668513a70bcd92384395513322f1b801e7bf9c729Steve Block
17768513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (bmp->is16bit()) {
17868513a70bcd92384395513322f1b801e7bf9c729Steve Block        unsigned short c = ((unsigned short *)bmp->bytes())[0];
17968513a70bcd92384395513322f1b801e7bf9c729Steve Block        int r = (c >> 7) & 0xF8;
18068513a70bcd92384395513322f1b801e7bf9c729Steve Block        int g = (c >> 2) & 0xF8;
18168513a70bcd92384395513322f1b801e7bf9c729Steve Block        int b = (c << 3) & 0xF8;
18268513a70bcd92384395513322f1b801e7bf9c729Steve Block        if (bmp->usesTransparentColor() && bmp->transparentColor() == RGB(r, g, b))
18368513a70bcd92384395513322f1b801e7bf9c729Steve Block            m_solidColor = Color(r, g, b, 0);
18468513a70bcd92384395513322f1b801e7bf9c729Steve Block        else
18568513a70bcd92384395513322f1b801e7bf9c729Steve Block            m_solidColor = Color(r, g, b);
18668513a70bcd92384395513322f1b801e7bf9c729Steve Block    } else {
18768513a70bcd92384395513322f1b801e7bf9c729Steve Block        unsigned c = ((unsigned *)bmp->bytes())[0];
18868513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_solidColor = Color(c);
18968513a70bcd92384395513322f1b801e7bf9c729Steve Block    }
19068513a70bcd92384395513322f1b801e7bf9c729Steve Block
19168513a70bcd92384395513322f1b801e7bf9c729Steve Block    if (bmp->validHeight() == bmp->height())
19268513a70bcd92384395513322f1b801e7bf9c729Steve Block        m_checkedForSolidColor = true;
19368513a70bcd92384395513322f1b801e7bf9c729Steve Block}
19468513a70bcd92384395513322f1b801e7bf9c729Steve Block
19568513a70bcd92384395513322f1b801e7bf9c729Steve Block} // namespace WebCore
196