diff options
Diffstat (limited to 'gfx/2d/SkConvolver.cpp')
-rw-r--r-- | gfx/2d/SkConvolver.cpp | 47 |
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. |