void FEGaussianBlur::apply(Filter* filter) { m_in->apply(filter); if (!m_in->resultImage()) return; if (!getEffectContext()) return; setIsAlphaImage(m_in->isAlphaImage()); if (m_x == 0 || m_y == 0) return; unsigned sdx = static_cast<unsigned>(floor(m_x * 3 * sqrt(2 * M_PI) / 4.f + 0.5f)); unsigned sdy = static_cast<unsigned>(floor(m_y * 3 * sqrt(2 * M_PI) / 4.f + 0.5f)); IntRect effectDrawingRect = calculateDrawingIntRect(m_in->subRegion()); RefPtr<ImageData> srcImageData(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect)); CanvasPixelArray* srcPixelArray(srcImageData->data()); IntRect imageRect(IntPoint(), resultImage()->size()); RefPtr<ImageData> tmpImageData = ImageData::create(imageRect.width(), imageRect.height()); CanvasPixelArray* tmpPixelArray(tmpImageData->data()); int stride = 4 * imageRect.width(); for (int i = 0; i < 3; ++i) { boxBlur(srcPixelArray, tmpPixelArray, sdx, 4, stride, imageRect.width(), imageRect.height(), isAlphaImage()); boxBlur(tmpPixelArray, srcPixelArray, sdy, stride, 4, imageRect.height(), imageRect.width(), isAlphaImage()); } resultImage()->putPremultipliedImageData(srcImageData.get(), imageRect, IntPoint()); }
void FELighting::apply(Filter* filter) { m_in->apply(filter); if (!m_in->resultImage()) return; if (!getEffectContext()) return; setIsAlphaImage(false); IntRect effectDrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); RefPtr<ImageData> srcImageData(m_in->resultImage()->getUnmultipliedImageData(effectDrawingRect)); CanvasPixelArray* srcPixelArray(srcImageData->data()); // FIXME: support kernelUnitLengths other than (1,1). The issue here is that the W3 // standard has no test case for them, and other browsers (like Firefox) has strange // output for various kernelUnitLengths, and I am not sure they are reliable. // Anyway, feConvolveMatrix should also use the implementation if (drawLighting(srcPixelArray, effectDrawingRect.width(), effectDrawingRect.height())) resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint()); }