void FEGaussianBlur::platformApplySoftware() { FilterEffect* in = inputEffect(0); Uint8ClampedArray* srcPixelArray = createPremultipliedImageResult(); if (!srcPixelArray) return; setIsAlphaImage(in->isAlphaImage()); IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); in->copyPremultipliedImage(srcPixelArray, effectDrawingRect); if (!m_stdX && !m_stdY) return; unsigned kernelSizeX = 0; unsigned kernelSizeY = 0; calculateKernelSize(filter(), kernelSizeX, kernelSizeY, m_stdX, m_stdY); IntSize paintSize = absolutePaintRect().size(); RefPtr<Uint8ClampedArray> tmpImageData = Uint8ClampedArray::createUninitialized(paintSize.width() * paintSize.height() * 4); Uint8ClampedArray* tmpPixelArray = tmpImageData.get(); platformApply(srcPixelArray, tmpPixelArray, kernelSizeX, kernelSizeY, paintSize); }
void FEGaussianBlur::platformApplySoftware() { FilterEffect* in = inputEffect(0); Uint8ClampedArray* srcPixelArray = createPremultipliedImageResult(); if (!srcPixelArray) return; setIsAlphaImage(in->isAlphaImage()); IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); in->copyPremultipliedImage(srcPixelArray, effectDrawingRect); if (!m_stdX && !m_stdY) return; IntSize kernelSize = calculateKernelSize(filter(), FloatPoint(m_stdX, m_stdY)); kernelSize.scale(filter().filterScale()); IntSize paintSize = absolutePaintRect().size(); paintSize.scale(filter().filterScale()); RefPtr<Uint8ClampedArray> tmpImageData = Uint8ClampedArray::createUninitialized((paintSize.area() * 4).unsafeGet()); if (!tmpImageData) { WTFLogAlways("FEGaussianBlur::platformApplySoftware Unable to create buffer. Requested size was %d x %d\n", paintSize.width(), paintSize.height()); return; } platformApply(srcPixelArray, tmpImageData.get(), kernelSize.width(), kernelSize.height(), paintSize); }
void FEMorphology::platformApplySoftware() { FilterEffect* in = inputEffect(0); Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); if (!dstPixelArray) return; setIsAlphaImage(in->isAlphaImage()); if (m_radiusX <= 0 || m_radiusY <= 0) { dstPixelArray->zeroFill(); return; } Filter& filter = this->filter(); int radiusX = static_cast<int>(floorf(filter.applyHorizontalScale(m_radiusX))); int radiusY = static_cast<int>(floorf(filter.applyVerticalScale(m_radiusY))); IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); RefPtr<Uint8ClampedArray> srcPixelArray = in->asPremultipliedImage(effectDrawingRect); PaintingData paintingData; paintingData.srcPixelArray = srcPixelArray.get(); paintingData.dstPixelArray = dstPixelArray; paintingData.width = effectDrawingRect.width(); paintingData.height = effectDrawingRect.height(); paintingData.radiusX = std::min(effectDrawingRect.width() - 1, radiusX); paintingData.radiusY = std::min(effectDrawingRect.height() - 1, radiusY); platformApply(&paintingData); }
bool FELighting::drawLighting(Uint8ClampedArray* pixels, int width, int height) { LightSource::PaintingData paintingData; LightingData data; if (!m_lightSource) return false; // FIXME: do something if width or height (or both) is 1 pixel. // The W3 spec does not define this case. Now the filter just returns. if (width <= 2 || height <= 2) return false; data.pixels = pixels; data.surfaceScale = m_surfaceScale / 255.0f; data.widthMultipliedByPixelSize = width * cPixelSize; data.widthDecreasedByOne = width - 1; data.heightDecreasedByOne = height - 1; paintingData.colorVector = FloatPoint3D(m_lightingColor.red(), m_lightingColor.green(), m_lightingColor.blue()); m_lightSource->initPaintingData(paintingData); // Top/Left corner. IntPoint normalVector; int offset = 0; data.topLeft(offset, normalVector); setPixel(offset, data, paintingData, 0, 0, cFactor2div3, cFactor2div3, normalVector); // Top/Right pixel. offset = data.widthMultipliedByPixelSize - cPixelSize; data.topRight(offset, normalVector); setPixel(offset, data, paintingData, data.widthDecreasedByOne, 0, cFactor2div3, cFactor2div3, normalVector); // Bottom/Left pixel. offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize; data.bottomLeft(offset, normalVector); setPixel(offset, data, paintingData, 0, data.heightDecreasedByOne, cFactor2div3, cFactor2div3, normalVector); // Bottom/Right pixel. offset = height * data.widthMultipliedByPixelSize - cPixelSize; data.bottomRight(offset, normalVector); setPixel(offset, data, paintingData, data.widthDecreasedByOne, data.heightDecreasedByOne, cFactor2div3, cFactor2div3, normalVector); if (width >= 3) { // Top row. offset = cPixelSize; for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) { data.topRow(offset, normalVector); inlineSetPixel(offset, data, paintingData, x, 0, cFactor1div3, cFactor1div2, normalVector); } // Bottom row. offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize + cPixelSize; for (int x = 1; x < data.widthDecreasedByOne; ++x, offset += cPixelSize) { data.bottomRow(offset, normalVector); inlineSetPixel(offset, data, paintingData, x, data.heightDecreasedByOne, cFactor1div3, cFactor1div2, normalVector); } } if (height >= 3) { // Left column. offset = data.widthMultipliedByPixelSize; for (int y = 1; y < data.heightDecreasedByOne; ++y, offset += data.widthMultipliedByPixelSize) { data.leftColumn(offset, normalVector); inlineSetPixel(offset, data, paintingData, 0, y, cFactor1div2, cFactor1div3, normalVector); } // Right column. offset = (data.widthMultipliedByPixelSize << 1) - cPixelSize; for (int y = 1; y < data.heightDecreasedByOne; ++y, offset += data.widthMultipliedByPixelSize) { data.rightColumn(offset, normalVector); inlineSetPixel(offset, data, paintingData, data.widthDecreasedByOne, y, cFactor1div2, cFactor1div3, normalVector); } } if (width >= 3 && height >= 3) { // Interior pixels. platformApply(data, paintingData); } int lastPixel = data.widthMultipliedByPixelSize * height; if (m_lightingType == DiffuseLighting) { for (int i = cAlphaChannelOffset; i < lastPixel; i += cPixelSize) data.pixels->set(i, cOpaqueAlpha); } else { for (int i = 0; i < lastPixel; i += cPixelSize) { unsigned char a1 = data.pixels->item(i); unsigned char a2 = data.pixels->item(i + 1); unsigned char a3 = data.pixels->item(i + 2); // alpha set to set to max(a1, a2, a3) data.pixels->set(i + 3, a1 >= a2 ? (a1 >= a3 ? a1 : a3) : (a2 >= a3 ? a2 : a3)); } } return true; }