Changeset 47529 in webkit


Ignore:
Timestamp:
Aug 19, 2009 3:33:54 PM (15 years ago)
Author:
eric@webkit.org
Message:

2009-08-19 Dirk Schulze <krit@webkit.org>

Reviewed by Oliver Hunt.

SVG feComponentTransfer needs to be implemented
https://bugs.webkit.org/show_bug.cgi?id=27768

Implementation of SVG Filter feComponentTransfer.

There is already a test case
Test: svg/W3C-SVG-1.1/filters-comptran-01-b.svg

  • platform/graphics/filters/FEComponentTransfer.cpp: (WebCore::identity): (WebCore::table): (WebCore::discrete): (WebCore::linear): (WebCore::gamma): (WebCore::FEComponentTransfer::apply):
Location:
trunk/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r47528 r47529  
     12009-08-19  Dirk Schulze  <krit@webkit.org>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        SVG feComponentTransfer needs to be implemented
     6        [https://bugs.webkit.org/show_bug.cgi?id=27768]
     7
     8        Implementation of SVG Filter feComponentTransfer.
     9
     10        There is already a test case
     11        Test: svg/W3C-SVG-1.1/filters-comptran-01-b.svg
     12
     13        * platform/graphics/filters/FEComponentTransfer.cpp:
     14        (WebCore::identity):
     15        (WebCore::table):
     16        (WebCore::discrete):
     17        (WebCore::linear):
     18        (WebCore::gamma):
     19        (WebCore::FEComponentTransfer::apply):
     20
    1212009-08-19  Dan Bernstein  <mitz@apple.com>
    222
  • trunk/WebCore/platform/graphics/filters/FEComponentTransfer.cpp

    r44296 r47529  
    33                  2004, 2005 Rob Buis <buis@kde.org>
    44                  2005 Eric Seidel <eric@webkit.org>
     5                  2009 Dirk Schulze <krit@webkit.org>
    56
    67    This library is free software; you can redistribute it and/or
     
    2526#include "FEComponentTransfer.h"
    2627
     28#include "CanvasPixelArray.h"
    2729#include "Filter.h"
     30#include "GraphicsContext.h"
     31#include "ImageData.h"
     32#include <math.h>
    2833
    2934namespace WebCore {
     35
     36typedef void (*TransferType)(unsigned char*, const ComponentTransferFunction&);
    3037
    3138FEComponentTransfer::FEComponentTransfer(FilterEffect* in, const ComponentTransferFunction& redFunc,
     
    8693}
    8794
    88 void FEComponentTransfer::apply(Filter*)
     95void identity(unsigned char*, const ComponentTransferFunction&)
    8996{
     97}
     98
     99void table(unsigned char* values, const ComponentTransferFunction& transferFunction)
     100{
     101    const Vector<float>& tableValues = transferFunction.tableValues;
     102    unsigned n = tableValues.size();
     103    if (n < 1)
     104        return;           
     105    for (unsigned i = 0; i < 256; ++i) {
     106        double c = i / 255.0;               
     107        unsigned k = static_cast<unsigned>(c * (n - 1));
     108        double v1 = tableValues[k];
     109        double v2 = tableValues[std::min((k + 1), (n - 1))];
     110        double val = 255.0 * (v1 + (c * (n - 1) - k) * (v2 - v1));
     111        val = std::max(0.0, std::min(255.0, val));
     112        values[i] = static_cast<unsigned char>(val);
     113    }
     114}
     115
     116void discrete(unsigned char* values, const ComponentTransferFunction& transferFunction)
     117{
     118    const Vector<float>& tableValues = transferFunction.tableValues;
     119    unsigned n = tableValues.size();
     120    if (n < 1)
     121        return;
     122    for (unsigned i = 0; i < 256; ++i) {
     123        unsigned k = static_cast<unsigned>((i * n) / 255.0);
     124        k = std::min(k, n - 1);
     125        double val = 255 * tableValues[k];
     126        val = std::max(0.0, std::min(255.0, val));
     127        values[i] = static_cast<unsigned char>(val);
     128    }
     129}
     130
     131void linear(unsigned char* values, const ComponentTransferFunction& transferFunction)
     132{
     133    for (unsigned i = 0; i < 256; ++i) {
     134        double val = transferFunction.slope * i + 255 * transferFunction.intercept;
     135        val = std::max(0.0, std::min(255.0, val));
     136        values[i] = static_cast<unsigned char>(val);
     137    }
     138}
     139
     140void gamma(unsigned char* values, const ComponentTransferFunction& transferFunction)
     141{
     142    for (unsigned i = 0; i < 256; ++i) {
     143        double val = 255.0 * (transferFunction.amplitude * pow((i / 255.0), transferFunction.exponent) + transferFunction.offset);
     144        val = std::max(0.0, std::min(255.0, val));
     145        values[i] = static_cast<unsigned char>(val);
     146    }
     147}
     148
     149void FEComponentTransfer::apply(Filter* filter)
     150{
     151    m_in->apply(filter);
     152    if (!m_in->resultImage())
     153        return;
     154
     155    if (!getEffectContext())
     156        return;
     157
     158    unsigned char rValues[256], gValues[256], bValues[256], aValues[256];
     159    for (unsigned i = 0; i < 256; ++i)
     160        rValues[i] = gValues[i] = bValues[i] = aValues[i] = i;
     161    unsigned char* tables[] = { rValues, gValues, bValues, aValues };
     162    ComponentTransferFunction transferFunction[] = {m_redFunc, m_greenFunc, m_blueFunc, m_alphaFunc};
     163    TransferType callEffect[] = {identity, identity, table, discrete, linear, gamma};
     164
     165    for (unsigned channel = 0; channel < 4; channel++)
     166        (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]);
     167
     168    IntRect drawingRect = calculateDrawingIntRect(m_in->subRegion());
     169    RefPtr<ImageData> imageData(m_in->resultImage()->getUnmultipliedImageData(drawingRect));
     170    CanvasPixelArray* srcPixelArray(imageData->data());
     171
     172    for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset += 4) {
     173        for (unsigned channel = 0; channel < 4; ++channel) {
     174            unsigned char c = srcPixelArray->get(pixelOffset + channel);
     175            imageData->data()->set(pixelOffset + channel, tables[channel][c]);
     176        }
     177    }
     178
     179    resultImage()->putUnmultipliedImageData(imageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint());
    90180}
    91181
Note: See TracChangeset for help on using the changeset viewer.