| Index: src/core/SkBitmapScaler.cpp
|
| diff --git a/src/core/SkBitmapScaler.cpp b/src/core/SkBitmapScaler.cpp
|
| index 25fbd1fe78763804221c3226f36f533aa4e115a4..b4ade85a7536bf58eb49c50334973488e465943c 100644
|
| --- a/src/core/SkBitmapScaler.cpp
|
| +++ b/src/core/SkBitmapScaler.cpp
|
| @@ -109,93 +109,92 @@ SkResizeFilter::SkResizeFilter(SkBitmapScaler::ResizeMethod method,
|
| // the coefficients can be shared. For periods of 1 we can consider
|
| // loading the factors only once outside the borders.
|
| void SkResizeFilter::computeFilters(int srcSize,
|
| - float destSubsetLo, float destSubsetSize,
|
| - float scale,
|
| - SkConvolutionFilter1D* output) {
|
| - float destSubsetHi = destSubsetLo + destSubsetSize; // [lo, hi)
|
| -
|
| - // When we're doing a magnification, the scale will be larger than one. This
|
| - // means the destination pixels are much smaller than the source pixels, and
|
| - // that the range covered by the filter won't necessarily cover any source
|
| - // pixel boundaries. Therefore, we use these clamped values (max of 1) for
|
| - // some computations.
|
| - float clampedScale = SkTMin(1.0f, scale);
|
| -
|
| - // This is how many source pixels from the center we need to count
|
| - // to support the filtering function.
|
| - float srcSupport = fBitmapFilter->width() / clampedScale;
|
| -
|
| - float invScale = 1.0f / scale;
|
| -
|
| - SkSTArray<64, float, true> filterValuesArray;
|
| - SkSTArray<64, SkConvolutionFilter1D::ConvolutionFixed, true> fixedFilterValuesArray;
|
| -
|
| - // Loop over all pixels in the output range. We will generate one set of
|
| - // filter values for each one. Those values will tell us how to blend the
|
| - // source pixels to compute the destination pixel.
|
| -
|
| - // 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
|
| - // why, observe that the destination pixel at coordinates (0, 0) in a 5.0x
|
| - // downscale should "cover" the pixels around the pixel with *its center*
|
| - // at coordinates (2.5, 2.5) in the source, not those around (0, 0).
|
| - // Hence we need to scale coordinates (0.5, 0.5), not (0, 0).
|
| - destSubsetLo = SkScalarFloorToScalar(destSubsetLo);
|
| - destSubsetHi = SkScalarCeilToScalar(destSubsetHi);
|
| - float srcPixel = (destSubsetLo + 0.5f) * invScale;
|
| - int destLimit = SkScalarTruncToInt(destSubsetHi - destSubsetLo);
|
| - output->reserveAdditional(destLimit, SkScalarCeilToInt(destLimit * srcSupport * 2));
|
| - for (int destI = 0; destI < destLimit; srcPixel += invScale, destI++)
|
| - {
|
| - // Compute the (inclusive) range of source pixels the filter covers.
|
| - float srcBegin = SkTMax(0.f, SkScalarFloorToScalar(srcPixel - srcSupport));
|
| - float srcEnd = SkTMin(srcSize - 1.f, SkScalarCeilToScalar(srcPixel + srcSupport));
|
| -
|
| - // Compute the unnormalized filter value at each location of the source
|
| - // it covers.
|
| -
|
| - // Sum of the filter values for normalizing.
|
| - // Distance from the center of the filter, this is the filter coordinate
|
| - // in source space. We also need to consider the center of the pixel
|
| - // when comparing distance against 'srcPixel'. In the 5x downscale
|
| - // example used above the distance from the center of the filter to
|
| - // the pixel with coordinates (2, 2) should be 0, because its center
|
| - // is at (2.5, 2.5).
|
| - float destFilterDist = (srcBegin + 0.5f - srcPixel) * clampedScale;
|
| - int filterCount = SkScalarTruncToInt(srcEnd - srcBegin) + 1;
|
| - if (filterCount <= 0) {
|
| - // true when srcSize is equal to srcPixel - srcSupport; this may be a bug
|
| - return;
|
| - }
|
| - filterValuesArray.reset(filterCount);
|
| - float filterSum = fBitmapFilter->evaluate_n(destFilterDist, clampedScale, filterCount,
|
| + float destSubsetLo, float destSubsetSize,
|
| + float scale,
|
| + SkConvolutionFilter1D* output) {
|
| + float destSubsetHi = destSubsetLo + destSubsetSize; // [lo, hi)
|
| +
|
| + // When we're doing a magnification, the scale will be larger than one. This
|
| + // means the destination pixels are much smaller than the source pixels, and
|
| + // that the range covered by the filter won't necessarily cover any source
|
| + // pixel boundaries. Therefore, we use these clamped values (max of 1) for
|
| + // some computations.
|
| + float clampedScale = SkTMin(1.0f, scale);
|
| +
|
| + // This is how many source pixels from the center we need to count
|
| + // to support the filtering function.
|
| + float srcSupport = fBitmapFilter->width() / clampedScale;
|
| +
|
| + float invScale = 1.0f / scale;
|
| +
|
| + SkSTArray<64, float, true> filterValuesArray;
|
| + SkSTArray<64, SkConvolutionFilter1D::ConvolutionFixed, true> fixedFilterValuesArray;
|
| +
|
| + // Loop over all pixels in the output range. We will generate one set of
|
| + // filter values for each one. Those values will tell us how to blend the
|
| + // source pixels to compute the destination pixel.
|
| +
|
| + // 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
|
| + // why, observe that the destination pixel at coordinates (0, 0) in a 5.0x
|
| + // downscale should "cover" the pixels around the pixel with *its center*
|
| + // at coordinates (2.5, 2.5) in the source, not those around (0, 0).
|
| + // Hence we need to scale coordinates (0.5, 0.5), not (0, 0).
|
| + destSubsetLo = SkScalarFloorToScalar(destSubsetLo);
|
| + destSubsetHi = SkScalarCeilToScalar(destSubsetHi);
|
| + float srcPixel = (destSubsetLo + 0.5f) * invScale;
|
| + int destLimit = SkScalarTruncToInt(destSubsetHi - destSubsetLo);
|
| + output->reserveAdditional(destLimit, SkScalarCeilToInt(destLimit * srcSupport * 2));
|
| + for (int destI = 0; destI < destLimit; srcPixel += invScale, destI++) {
|
| + // Compute the (inclusive) range of source pixels the filter covers.
|
| + float srcBegin = SkTMax(0.f, SkScalarFloorToScalar(srcPixel - srcSupport));
|
| + float srcEnd = SkTMin(srcSize - 1.f, SkScalarCeilToScalar(srcPixel + srcSupport));
|
| +
|
| + // Compute the unnormalized filter value at each location of the source
|
| + // it covers.
|
| +
|
| + // Sum of the filter values for normalizing.
|
| + // Distance from the center of the filter, this is the filter coordinate
|
| + // in source space. We also need to consider the center of the pixel
|
| + // when comparing distance against 'srcPixel'. In the 5x downscale
|
| + // example used above the distance from the center of the filter to
|
| + // the pixel with coordinates (2, 2) should be 0, because its center
|
| + // is at (2.5, 2.5).
|
| + float destFilterDist = (srcBegin + 0.5f - srcPixel) * clampedScale;
|
| + int filterCount = SkScalarTruncToInt(srcEnd - srcBegin) + 1;
|
| + if (filterCount <= 0) {
|
| + // true when srcSize is equal to srcPixel - srcSupport; this may be a bug
|
| + return;
|
| + }
|
| + filterValuesArray.reset(filterCount);
|
| + float filterSum = fBitmapFilter->evaluate_n(destFilterDist, clampedScale, filterCount,
|
| filterValuesArray.begin());
|
|
|
| - // The filter must be normalized so that we don't affect the brightness of
|
| - // the image. Convert to normalized fixed point.
|
| - int fixedSum = 0;
|
| - fixedFilterValuesArray.reset(filterCount);
|
| - const float* filterValues = filterValuesArray.begin();
|
| - SkConvolutionFilter1D::ConvolutionFixed* fixedFilterValues = fixedFilterValuesArray.begin();
|
| - float invFilterSum = 1 / filterSum;
|
| - for (int fixedI = 0; fixedI < filterCount; fixedI++) {
|
| - int curFixed = SkConvolutionFilter1D::FloatToFixed(filterValues[fixedI] * invFilterSum);
|
| - fixedSum += curFixed;
|
| - fixedFilterValues[fixedI] = SkToS16(curFixed);
|
| + // The filter must be normalized so that we don't affect the brightness of
|
| + // the image. Convert to normalized fixed point.
|
| + int fixedSum = 0;
|
| + fixedFilterValuesArray.reset(filterCount);
|
| + const float* filterValues = filterValuesArray.begin();
|
| + SkConvolutionFilter1D::ConvolutionFixed* fixedFilterValues = fixedFilterValuesArray.begin();
|
| + float invFilterSum = 1 / filterSum;
|
| + for (int fixedI = 0; fixedI < filterCount; fixedI++) {
|
| + int curFixed = SkConvolutionFilter1D::FloatToFixed(filterValues[fixedI] * invFilterSum);
|
| + fixedSum += curFixed;
|
| + fixedFilterValues[fixedI] = SkToS16(curFixed);
|
| + }
|
| + SkASSERT(fixedSum <= 0x7FFF);
|
| +
|
| + // The conversion to fixed point will leave some rounding errors, which
|
| + // we add back in to avoid affecting the brightness of the image. We
|
| + // arbitrarily add this to the center of the filter array (this won't always
|
| + // be the center of the filter function since it could get clipped on the
|
| + // edges, but it doesn't matter enough to worry about that case).
|
| + int leftovers = SkConvolutionFilter1D::FloatToFixed(1) - fixedSum;
|
| + fixedFilterValues[filterCount / 2] += leftovers;
|
| +
|
| + // Now it's ready to go.
|
| + output->AddFilter(SkScalarFloorToInt(srcBegin), fixedFilterValues, filterCount);
|
| }
|
| - SkASSERT(fixedSum <= 0x7FFF);
|
| -
|
| - // The conversion to fixed point will leave some rounding errors, which
|
| - // we add back in to avoid affecting the brightness of the image. We
|
| - // arbitrarily add this to the center of the filter array (this won't always
|
| - // be the center of the filter function since it could get clipped on the
|
| - // edges, but it doesn't matter enough to worry about that case).
|
| - int leftovers = SkConvolutionFilter1D::FloatToFixed(1) - fixedSum;
|
| - fixedFilterValues[filterCount / 2] += leftovers;
|
| -
|
| - // Now it's ready to go.
|
| - output->AddFilter(SkScalarFloorToInt(srcBegin), fixedFilterValues, filterCount);
|
| - }
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////////////////////////
|
| @@ -214,9 +213,6 @@ bool SkBitmapScaler::Resize(const SkPixmap& result, const SkPixmap& source, Resi
|
| return false;
|
| }
|
|
|
| - SkConvolutionProcs convolveProcs= { nullptr, nullptr, nullptr };
|
| - PlatformConvolutionProcs(&convolveProcs);
|
| -
|
| SkRect destSubset = SkRect::MakeIWH(result.width(), result.height());
|
|
|
| SkResizeFilter filter(method, source.width(), source.height(),
|
| @@ -230,8 +226,7 @@ bool SkBitmapScaler::Resize(const SkPixmap& result, const SkPixmap& source, Resi
|
| return BGRAConvolve2D(sourceSubset, static_cast<int>(source.rowBytes()),
|
| !source.isOpaque(), filter.xFilter(), filter.yFilter(),
|
| static_cast<int>(result.rowBytes()),
|
| - static_cast<unsigned char*>(result.writable_addr()),
|
| - convolveProcs, true);
|
| + static_cast<unsigned char*>(result.writable_addr()));
|
| }
|
|
|
| bool SkBitmapScaler::Resize(SkBitmap* resultPtr, const SkPixmap& source, ResizeMethod method,
|
|
|