Changeset 47529 in webkit
- Timestamp:
- Aug 19, 2009 3:33:54 PM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r47528 r47529 1 2009-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 1 21 2009-08-19 Dan Bernstein <mitz@apple.com> 2 22 -
trunk/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
r44296 r47529 3 3 2004, 2005 Rob Buis <buis@kde.org> 4 4 2005 Eric Seidel <eric@webkit.org> 5 2009 Dirk Schulze <krit@webkit.org> 5 6 6 7 This library is free software; you can redistribute it and/or … … 25 26 #include "FEComponentTransfer.h" 26 27 28 #include "CanvasPixelArray.h" 27 29 #include "Filter.h" 30 #include "GraphicsContext.h" 31 #include "ImageData.h" 32 #include <math.h> 28 33 29 34 namespace WebCore { 35 36 typedef void (*TransferType)(unsigned char*, const ComponentTransferFunction&); 30 37 31 38 FEComponentTransfer::FEComponentTransfer(FilterEffect* in, const ComponentTransferFunction& redFunc, … … 86 93 } 87 94 88 void FEComponentTransfer::apply(Filter*)95 void identity(unsigned char*, const ComponentTransferFunction&) 89 96 { 97 } 98 99 void 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 116 void 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 131 void 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 140 void 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 149 void 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()); 90 180 } 91 181
Note: See TracChangeset
for help on using the changeset viewer.