From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- gfx/2d/ConvolutionFilter.cpp | 114 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 gfx/2d/ConvolutionFilter.cpp (limited to 'gfx/2d/ConvolutionFilter.cpp') diff --git a/gfx/2d/ConvolutionFilter.cpp b/gfx/2d/ConvolutionFilter.cpp new file mode 100644 index 0000000000..31ace83dc7 --- /dev/null +++ b/gfx/2d/ConvolutionFilter.cpp @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ConvolutionFilter.h" +#include "HelpersSkia.h" +#include "SkConvolver.h" +#include "skia/include/core/SkBitmap.h" + +namespace mozilla::gfx { + +ConvolutionFilter::ConvolutionFilter() + : mFilter(MakeUnique()) {} + +ConvolutionFilter::~ConvolutionFilter() = default; + +int32_t ConvolutionFilter::MaxFilter() const { return mFilter->maxFilter(); } + +int32_t ConvolutionFilter::NumValues() const { return mFilter->numValues(); } + +bool ConvolutionFilter::GetFilterOffsetAndLength(int32_t aRowIndex, + int32_t* aResultOffset, + int32_t* aResultLength) { + if (aRowIndex >= mFilter->numValues()) { + return false; + } + mFilter->FilterForValue(aRowIndex, aResultOffset, aResultLength); + return true; +} + +void ConvolutionFilter::ConvolveHorizontally(const uint8_t* aSrc, uint8_t* aDst, + bool aHasAlpha) { + skia::convolve_horizontally(aSrc, *mFilter, aDst, aHasAlpha); +} + +void ConvolutionFilter::ConvolveVertically(uint8_t* const* aSrc, uint8_t* aDst, + int32_t aRowIndex, int32_t aRowSize, + bool aHasAlpha) { + MOZ_ASSERT(aRowIndex < mFilter->numValues()); + + int32_t filterOffset; + int32_t filterLength; + auto filterValues = + mFilter->FilterForValue(aRowIndex, &filterOffset, &filterLength); + skia::convolve_vertically(filterValues, filterLength, aSrc, aRowSize, aDst, + aHasAlpha); +} + +bool ConvolutionFilter::ComputeResizeFilter(ResizeMethod aResizeMethod, + int32_t aSrcSize, + int32_t aDstSize) { + if (aSrcSize < 0 || aDstSize < 0) { + return false; + } + + switch (aResizeMethod) { + case ResizeMethod::BOX: + return mFilter->ComputeFilterValues(skia::SkBoxFilter(), aSrcSize, + aDstSize); + case ResizeMethod::LANCZOS3: + return mFilter->ComputeFilterValues(skia::SkLanczosFilter(), aSrcSize, + aDstSize); + default: + return false; + } +} + +bool Scale(uint8_t* srcData, int32_t srcWidth, int32_t srcHeight, + int32_t srcStride, uint8_t* dstData, int32_t dstWidth, + int32_t dstHeight, int32_t dstStride, SurfaceFormat format) { + if (!srcData || !dstData || srcWidth < 1 || srcHeight < 1 || dstWidth < 1 || + dstHeight < 1) { + return false; + } + + SkPixmap srcPixmap(MakeSkiaImageInfo(IntSize(srcWidth, srcHeight), format), + srcData, srcStride); + + // Rescaler is compatible with N32 only. Convert to N32 if needed. + SkBitmap tmpBitmap; + if (srcPixmap.colorType() != kN32_SkColorType) { + if (!tmpBitmap.tryAllocPixels( + SkImageInfo::MakeN32Premul(srcWidth, srcHeight)) || + !tmpBitmap.writePixels(srcPixmap) || + !tmpBitmap.peekPixels(&srcPixmap)) { + return false; + } + } + + ConvolutionFilter xFilter; + ConvolutionFilter yFilter; + ConvolutionFilter* xOrYFilter = &xFilter; + bool isSquare = srcWidth == srcHeight && dstWidth == dstHeight; + if (!xFilter.ComputeResizeFilter(ConvolutionFilter::ResizeMethod::LANCZOS3, + srcWidth, dstWidth)) { + return false; + } + if (!isSquare) { + if (!yFilter.ComputeResizeFilter(ConvolutionFilter::ResizeMethod::LANCZOS3, + srcHeight, dstHeight)) { + return false; + } + xOrYFilter = &yFilter; + } + + return skia::BGRAConvolve2D( + static_cast(srcPixmap.addr()), int(srcPixmap.rowBytes()), + !srcPixmap.isOpaque(), xFilter.GetSkiaFilter(), + xOrYFilter->GetSkiaFilter(), int(dstStride), dstData); +} + +} // namespace mozilla::gfx -- cgit v1.2.3