/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenVG module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qpixmapfilter_vg_p.h"
#include "qvgimagepool_p.h"
#include <QtCore/qvarlengtharray.h>
#include <QtGui/qpainter.h>

QT_BEGIN_NAMESPACE

#if !defined(QT_SHIVAVG)

QVGPixmapConvolutionFilter::QVGPixmapConvolutionFilter()
    : QPixmapConvolutionFilter()
{
}

QVGPixmapConvolutionFilter::~QVGPixmapConvolutionFilter()
{
}

extern void qt_vg_drawVGImage
    (QPainter *painter, const QPointF& pos, VGImage vgImg);
extern void qt_vg_drawVGImageStencil
    (QPainter *painter, const QPointF& pos, VGImage vgImg, const QBrush& brush);

void QVGPixmapConvolutionFilter::draw
        (QPainter *painter, const QPointF &dest,
         const QPixmap &src, const QRectF &srcRect) const
{
    if (src.isNull())
        return;

    if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
        // The pixmap data is not an instance of QVGPixmapData, so fall
        // back to the default convolution filter implementation.
        QPixmapConvolutionFilter::draw(painter, dest, src, srcRect);
        return;
    }

    QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());

    VGImage srcImage = pd->toVGImage();
    if (srcImage == VG_INVALID_HANDLE)
        return;

    QSize size = pd->size();
    VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
        (VG_sARGB_8888_PRE, size.width(), size.height(),
         VG_IMAGE_QUALITY_FASTER, pd);
    if (dstImage == VG_INVALID_HANDLE)
        return;

    int kernelWidth = rows();
    int kernelHeight = columns();
    const qreal *kern = convolutionKernel();
    QVarLengthArray<VGshort> kernel;
    for (int i = 0; i < kernelWidth; ++i) {
        for (int j = 0; j < kernelHeight; ++j) {
            kernel.append((VGshort)(kern[j * kernelWidth + i] * 1024.0f));
        }
    }

    VGfloat values[4];
    values[0] = 0.0f;
    values[1] = 0.0f;
    values[2] = 0.0f;
    values[3] = 0.0f;
    vgSetfv(VG_TILE_FILL_COLOR, 4, values);

    vgConvolve(dstImage, srcImage,
               kernelWidth, kernelHeight, 0, 0,
               kernel.constData(), 1.0f / 1024.0f, 0.0f,
               VG_TILE_FILL);

    VGImage child = VG_INVALID_HANDLE;

    if (srcRect.isNull() ||
        (srcRect.topLeft().isNull() && srcRect.size() == size)) {
        child = dstImage;
    } else {
        QRect src = srcRect.toRect();
        child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
    }

    qt_vg_drawVGImage(painter, dest, child);

    if(child != dstImage)
        vgDestroyImage(child);
    QVGImagePool::instance()->releaseImage(0, dstImage);
}

QVGPixmapColorizeFilter::QVGPixmapColorizeFilter()
    : QPixmapColorizeFilter()
{
}

QVGPixmapColorizeFilter::~QVGPixmapColorizeFilter()
{
}

void QVGPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
{
    if (src.isNull())
        return;

    if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
        // The pixmap data is not an instance of QVGPixmapData, so fall
        // back to the default colorize filter implementation.
        QPixmapColorizeFilter::draw(painter, dest, src, srcRect);
        return;
    }

    QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());

    VGImage srcImage = pd->toVGImage();
    if (srcImage == VG_INVALID_HANDLE)
        return;

    QSize size = pd->size();
    VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
        (VG_sARGB_8888_PRE, size.width(), size.height(),
         VG_IMAGE_QUALITY_FASTER, pd);
    if (dstImage == VG_INVALID_HANDLE)
        return;

    // Determine the weights for the matrix from the color and strength.
    QColor c = color();
    VGfloat strength = this->strength();
    VGfloat weights[3];
    VGfloat invweights[3];
    VGfloat alpha = c.alphaF();
    weights[0] = c.redF() * alpha;
    weights[1] = c.greenF() * alpha;
    weights[2] = c.blueF() * alpha;
    invweights[0] = (1.0f - weights[0]) * strength;
    invweights[1] = (1.0f - weights[1]) * strength;
    invweights[2] = (1.0f - weights[2]) * strength;

    // Grayscale weights.
    static const VGfloat redGray = 11.0f / 32.0f;
    static const VGfloat greenGray = 16.0f / 32.0f;
    static const VGfloat blueGray = 1.0f - (redGray + greenGray);

    VGfloat matrix[5][4];
    matrix[0][0] = redGray * invweights[0] + (1.0f - strength);
    matrix[0][1] = redGray * invweights[1];
    matrix[0][2] = redGray * invweights[2];
    matrix[0][3] = 0.0f;
    matrix[1][0] = greenGray * invweights[0];
    matrix[1][1] = greenGray * invweights[1] + (1.0f - strength);
    matrix[1][2] = greenGray * invweights[2];
    matrix[1][3] = 0.0f;
    matrix[2][0] = blueGray * invweights[0];
    matrix[2][1] = blueGray * invweights[1];
    matrix[2][2] = blueGray * invweights[2] + (1.0f - strength);
    matrix[2][3] = 0.0f;
    matrix[3][0] = 0.0f;
    matrix[3][1] = 0.0f;
    matrix[3][2] = 0.0f;
    matrix[3][3] = 1.0f;
    matrix[4][0] = weights[0] * strength;
    matrix[4][1] = weights[1] * strength;
    matrix[4][2] = weights[2] * strength;
    matrix[4][3] = 0.0f;

    vgColorMatrix(dstImage, srcImage, matrix[0]);

    VGImage child = VG_INVALID_HANDLE;

    if (srcRect.isNull() ||
        (srcRect.topLeft().isNull() && srcRect.size() == size)) {
        child = dstImage;
    } else {
        QRect src = srcRect.toRect();
        child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
    }

    qt_vg_drawVGImage(painter, dest, child);

    if(child != dstImage)
        vgDestroyImage(child);
    QVGImagePool::instance()->releaseImage(0, dstImage);
}

QVGPixmapDropShadowFilter::QVGPixmapDropShadowFilter()
    : QPixmapDropShadowFilter()
{
}

QVGPixmapDropShadowFilter::~QVGPixmapDropShadowFilter()
{
}

void QVGPixmapDropShadowFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
{
    if (src.isNull())
        return;

    if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
        // The pixmap data is not an instance of QVGPixmapData, so fall
        // back to the default drop shadow filter implementation.
        QPixmapDropShadowFilter::draw(painter, dest, src, srcRect);
        return;
    }

    QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());

    VGImage srcImage = pd->toVGImage();
    if (srcImage == VG_INVALID_HANDLE)
        return;

    QSize size = pd->size();
    VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
        (VG_A_8, size.width(), size.height(),
         VG_IMAGE_QUALITY_FASTER, pd);
    if (dstImage == VG_INVALID_HANDLE)
        return;

    // Clamp the radius range.  We divide by 2 because the OpenVG blur
    // is "too blurry" compared to the default raster implementation.
    VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
    VGfloat radiusF = VGfloat(blurRadius()) / 2.0f;
    if (radiusF < 0.001f)
        radiusF = 0.001f;
    else if (radiusF > maxRadius)
        radiusF = maxRadius;

    // Blur the blackened source image.
    vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);

    VGImage child = VG_INVALID_HANDLE;

    QRect srect;
    if (srcRect.isNull() ||
        (srcRect.topLeft().isNull() && srcRect.size() == size)) {
        child = dstImage;
        srect = QRect(0, 0, size.width(), size.height());
    } else {
        srect = srcRect.toRect();
        child = vgChildImage(dstImage, srect.x(), srect.y(), srect.width(), srect.height());
    }

    qt_vg_drawVGImageStencil(painter, dest + offset(), child, color());

    if(child != dstImage)
        vgDestroyImage(child);
    QVGImagePool::instance()->releaseImage(0, dstImage);

    // Now draw the actual pixmap over the top.
    painter->drawPixmap(dest, src, srect);
}

QVGPixmapBlurFilter::QVGPixmapBlurFilter(QObject *parent)
    : QPixmapBlurFilter(parent)
{
}

QVGPixmapBlurFilter::~QVGPixmapBlurFilter()
{
}

void QVGPixmapBlurFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const
{
    if (src.isNull())
        return;

    if (src.pixmapData()->classId() != QPixmapData::OpenVGClass) {
        // The pixmap data is not an instance of QVGPixmapData, so fall
        // back to the default blur filter implementation.
        QPixmapBlurFilter::draw(painter, dest, src, srcRect);
        return;
    }

    QVGPixmapData *pd = static_cast<QVGPixmapData *>(src.pixmapData());

    VGImage srcImage = pd->toVGImage();
    if (srcImage == VG_INVALID_HANDLE)
        return;

    QSize size = pd->size();
    VGImage dstImage = QVGImagePool::instance()->createTemporaryImage
        (VG_sARGB_8888_PRE, size.width(), size.height(),
         VG_IMAGE_QUALITY_FASTER, pd);
    if (dstImage == VG_INVALID_HANDLE)
        return;

    // Clamp the radius range.  We divide by 2 because the OpenVG blur
    // is "too blurry" compared to the default raster implementation.
    VGfloat maxRadius = VGfloat(vgGeti(VG_MAX_GAUSSIAN_STD_DEVIATION));
    VGfloat radiusF = VGfloat(radius()) / 2.0f;
    if (radiusF < 0.001f)
        radiusF = 0.001f;
    else if (radiusF > maxRadius)
        radiusF = maxRadius;

    vgGaussianBlur(dstImage, srcImage, radiusF, radiusF, VG_TILE_PAD);

    VGImage child = VG_INVALID_HANDLE;

    if (srcRect.isNull() ||
        (srcRect.topLeft().isNull() && srcRect.size() == size)) {
        child = dstImage;
    } else {
        QRect src = srcRect.toRect();
        child = vgChildImage(dstImage, src.x(), src.y(), src.width(), src.height());
    }

    qt_vg_drawVGImage(painter, dest, child);

    if(child != dstImage)
        vgDestroyImage(child);
    QVGImagePool::instance()->releaseImage(0, dstImage);
}

#endif

QT_END_NAMESPACE
