summaryrefslogtreecommitdiffstats
path: root/gfx/2d/SkConvolver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/2d/SkConvolver.cpp')
-rw-r--r--gfx/2d/SkConvolver.cpp47
1 files changed, 33 insertions, 14 deletions
diff --git a/gfx/2d/SkConvolver.cpp b/gfx/2d/SkConvolver.cpp
index befe8da30b..b89a486d48 100644
--- a/gfx/2d/SkConvolver.cpp
+++ b/gfx/2d/SkConvolver.cpp
@@ -5,7 +5,6 @@
// found in the gfx/skia/LICENSE file.
#include "SkConvolver.h"
-#include "mozilla/Vector.h"
#ifdef USE_SSE2
# include "mozilla/SSE.h"
@@ -235,9 +234,11 @@ class CircularRowBuffer {
: fRowByteWidth(destRowPixelWidth * 4),
fNumRows(maxYFilterSize),
fNextRow(0),
- fNextRowCoordinate(firstInputRow) {
- fBuffer.resize(fRowByteWidth * maxYFilterSize);
- fRowAddresses.resize(fNumRows);
+ fNextRowCoordinate(firstInputRow) {}
+
+ bool AllocBuffer() {
+ return fBuffer.resize(fRowByteWidth * fNumRows) &&
+ fRowAddresses.resize(fNumRows);
}
// Moves to the next row in the buffer, returning a pointer to the beginning
@@ -288,7 +289,7 @@ class CircularRowBuffer {
private:
// The buffer storing the rows. They are packed, each one fRowByteWidth.
- std::vector<unsigned char> fBuffer;
+ mozilla::Vector<unsigned char> fBuffer;
// Number of bytes per row in the |buffer|.
int fRowByteWidth;
@@ -305,14 +306,14 @@ class CircularRowBuffer {
int fNextRowCoordinate;
// Buffer used by GetRowAddresses().
- std::vector<unsigned char*> fRowAddresses;
+ mozilla::Vector<unsigned char*> fRowAddresses;
};
SkConvolutionFilter1D::SkConvolutionFilter1D() : fMaxFilter(0) {}
SkConvolutionFilter1D::~SkConvolutionFilter1D() = default;
-void SkConvolutionFilter1D::AddFilter(int filterOffset,
+bool SkConvolutionFilter1D::AddFilter(int filterOffset,
const ConvolutionFixed* filterValues,
int filterLength) {
// It is common for leading/trailing filter values to be zeros. In such
@@ -336,8 +337,9 @@ void SkConvolutionFilter1D::AddFilter(int filterOffset,
filterLength = lastNonZero + 1 - firstNonZero;
MOZ_ASSERT(filterLength > 0);
- fFilterValues.insert(fFilterValues.end(), &filterValues[firstNonZero],
- &filterValues[lastNonZero + 1]);
+ if (!fFilterValues.append(&filterValues[firstNonZero], filterLength)) {
+ return false;
+ }
} else {
// Here all the factors were zeroes.
filterLength = 0;
@@ -345,11 +347,17 @@ void SkConvolutionFilter1D::AddFilter(int filterOffset,
FilterInstance instance = {
// We pushed filterLength elements onto fFilterValues
- int(fFilterValues.size()) - filterLength, filterOffset, filterLength,
+ int(fFilterValues.length()) - filterLength, filterOffset, filterLength,
filterSize};
- fFilters.push_back(instance);
+ if (!fFilters.append(instance)) {
+ if (filterLength > 0) {
+ fFilterValues.shrinkBy(filterLength);
+ }
+ return false;
+ }
fMaxFilter = std::max(fMaxFilter, filterLength);
+ return true;
}
bool SkConvolutionFilter1D::ComputeFilterValues(
@@ -383,10 +391,13 @@ bool SkConvolutionFilter1D::ComputeFilterValues(
int32_t filterValueCount = int32_t(ceilf(aDstSize * srcSupport * 2));
if (aDstSize > maxToPassToReserveAdditional || filterValueCount < 0 ||
- filterValueCount > maxToPassToReserveAdditional) {
+ filterValueCount > maxToPassToReserveAdditional ||
+ !reserveAdditional(aDstSize, filterValueCount)) {
return false;
}
- reserveAdditional(aDstSize, filterValueCount);
+ size_t oldFiltersLength = fFilters.length();
+ size_t oldFilterValuesLength = fFilterValues.length();
+ int oldMaxFilter = fMaxFilter;
for (int32_t destI = 0; destI < aDstSize; destI++) {
// This is the pixel in the source directly under the pixel in the dest.
// Note that we base computations on the "center" of the pixels. To see
@@ -443,7 +454,12 @@ bool SkConvolutionFilter1D::ComputeFilterValues(
ConvolutionFixed leftovers = ToFixed(1) - fixedSum;
fixedFilterValues[filterCount / 2] += leftovers;
- AddFilter(int32_t(srcBegin), fixedFilterValues.begin(), filterCount);
+ if (!AddFilter(int32_t(srcBegin), fixedFilterValues.begin(), filterCount)) {
+ fFilters.shrinkTo(oldFiltersLength);
+ fFilterValues.shrinkTo(oldFilterValuesLength);
+ fMaxFilter = oldMaxFilter;
+ return false;
+ }
}
return maxFilter() > 0 && numValues() == aDstSize;
@@ -515,6 +531,9 @@ bool BGRAConvolve2D(const unsigned char* sourceData, int sourceByteRowStride,
}
CircularRowBuffer rowBuffer(rowBufferWidth, rowBufferHeight, filterOffset);
+ if (!rowBuffer.AllocBuffer()) {
+ return false;
+ }
// Loop over every possible output row, processing just enough horizontal
// convolutions to run each subsequent vertical convolution.