2 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public License
18 * along with this library; see the file COPYING.LIB. If not, write to
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 #include "FEColorMatrix.h"
27 #include "GraphicsContext.h"
28 #include "TextStream.h"
30 #include <runtime/Uint8ClampedArray.h>
31 #include <wtf/MathExtras.h>
35 FEColorMatrix::FEColorMatrix(Filter& filter, ColorMatrixType type, const Vector<float>& values)
36 : FilterEffect(filter)
42 Ref<FEColorMatrix> FEColorMatrix::create(Filter& filter, ColorMatrixType type, const Vector<float>& values)
44 return adoptRef(*new FEColorMatrix(filter, type, values));
47 ColorMatrixType FEColorMatrix::type() const
52 bool FEColorMatrix::setType(ColorMatrixType type)
60 const Vector<float>& FEColorMatrix::values() const
65 bool FEColorMatrix::setValues(const Vector<float> &values)
67 if (m_values == values)
73 inline void matrix(float& red, float& green, float& blue, float& alpha, const Vector<float>& values)
75 float r = values[0] * red + values[1] * green + values[2] * blue + values[3] * alpha + values[4] * 255;
76 float g = values[5] * red + values[6] * green + values[7] * blue + values[8] * alpha + values[9] * 255;
77 float b = values[10] * red + values[11] * green + values[12] * blue + values[13] * alpha + values[14] * 255;
78 float a = values[15] * red + values[16] * green + values[17] * blue + values[18] * alpha + values[19] * 255;
86 inline void saturateAndHueRotate(float& red, float& green, float& blue, const float* components)
88 float r = red * components[0] + green * components[1] + blue * components[2];
89 float g = red * components[3] + green * components[4] + blue * components[5];
90 float b = red * components[6] + green * components[7] + blue * components[8];
97 inline void luminance(float& red, float& green, float& blue, float& alpha)
99 alpha = 0.2125 * red + 0.7154 * green + 0.0721 * blue;
105 template<ColorMatrixType filterType>
106 void effectType(Uint8ClampedArray* pixelArray, const Vector<float>& values)
108 unsigned pixelArrayLength = pixelArray->length();
111 if (filterType == FECOLORMATRIX_TYPE_SATURATE)
112 FEColorMatrix::calculateSaturateComponents(components, values[0]);
113 else if (filterType == FECOLORMATRIX_TYPE_HUEROTATE)
114 FEColorMatrix::calculateHueRotateComponents(components, values[0]);
116 for (unsigned pixelByteOffset = 0; pixelByteOffset < pixelArrayLength; pixelByteOffset += 4) {
117 float red = pixelArray->item(pixelByteOffset);
118 float green = pixelArray->item(pixelByteOffset + 1);
119 float blue = pixelArray->item(pixelByteOffset + 2);
120 float alpha = pixelArray->item(pixelByteOffset + 3);
122 switch (filterType) {
123 case FECOLORMATRIX_TYPE_MATRIX:
124 matrix(red, green, blue, alpha, values);
126 case FECOLORMATRIX_TYPE_SATURATE:
127 case FECOLORMATRIX_TYPE_HUEROTATE:
128 saturateAndHueRotate(red, green, blue, components);
130 case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
131 luminance(red, green, blue, alpha);
135 pixelArray->set(pixelByteOffset, red);
136 pixelArray->set(pixelByteOffset + 1, green);
137 pixelArray->set(pixelByteOffset + 2, blue);
138 pixelArray->set(pixelByteOffset + 3, alpha);
142 void FEColorMatrix::platformApplySoftware()
144 FilterEffect* in = inputEffect(0);
146 ImageBuffer* resultImage = createImageBufferResult();
150 resultImage->context()->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
152 IntRect imageRect(IntPoint(), resultImage->logicalSize());
153 RefPtr<Uint8ClampedArray> pixelArray = resultImage->getUnmultipliedImageData(imageRect);
156 case FECOLORMATRIX_TYPE_UNKNOWN:
158 case FECOLORMATRIX_TYPE_MATRIX:
159 effectType<FECOLORMATRIX_TYPE_MATRIX>(pixelArray.get(), m_values);
161 case FECOLORMATRIX_TYPE_SATURATE:
162 effectType<FECOLORMATRIX_TYPE_SATURATE>(pixelArray.get(), m_values);
164 case FECOLORMATRIX_TYPE_HUEROTATE:
165 effectType<FECOLORMATRIX_TYPE_HUEROTATE>(pixelArray.get(), m_values);
167 case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
168 effectType<FECOLORMATRIX_TYPE_LUMINANCETOALPHA>(pixelArray.get(), m_values);
169 setIsAlphaImage(true);
173 resultImage->putByteArray(Unmultiplied, pixelArray.get(), imageRect.size(), imageRect, IntPoint());
176 void FEColorMatrix::dump()
180 static TextStream& operator<<(TextStream& ts, const ColorMatrixType& type)
183 case FECOLORMATRIX_TYPE_UNKNOWN:
186 case FECOLORMATRIX_TYPE_MATRIX:
189 case FECOLORMATRIX_TYPE_SATURATE:
192 case FECOLORMATRIX_TYPE_HUEROTATE:
195 case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
196 ts << "LUMINANCETOALPHA";
202 TextStream& FEColorMatrix::externalRepresentation(TextStream& ts, int indent) const
204 writeIndent(ts, indent);
205 ts << "[feColorMatrix";
206 FilterEffect::externalRepresentation(ts);
207 ts << " type=\"" << m_type << "\"";
208 if (!m_values.isEmpty()) {
210 Vector<float>::const_iterator ptr = m_values.begin();
211 const Vector<float>::const_iterator end = m_values.end();
221 inputEffect(0)->externalRepresentation(ts, indent + 1);
225 } // namespace WebCore