From 92fc2ae58331662ec411a048686cb4801e0a909a Mon Sep 17 00:00:00 2001 From: reed Date: Fri, 22 May 2015 08:06:21 -0700 Subject: add SkPixmap and external locking to bitmaps BUG=skia: Review URL: https://codereview.chromium.org/1074983003 --- src/core/SkBitmapScaler.cpp | 117 ++++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 53 deletions(-) (limited to 'src/core/SkBitmapScaler.cpp') diff --git a/src/core/SkBitmapScaler.cpp b/src/core/SkBitmapScaler.cpp index 4bd3cc732d..9ce4171879 100644 --- a/src/core/SkBitmapScaler.cpp +++ b/src/core/SkBitmapScaler.cpp @@ -1,3 +1,10 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + #include "SkBitmapScaler.h" #include "SkBitmapFilter.h" #include "SkRect.h" @@ -241,74 +248,78 @@ static SkBitmapScaler::ResizeMethod ResizeMethodToAlgorithmMethod( } } -// static +static bool resize(const SkPixmap& pmap, SkBitmap* resultPtr, SkBitmapScaler::ResizeMethod method, + float destWidth, float destHeight, SkBitmap::Allocator* allocator, + const SkConvolutionProcs& convolveProcs) { + const SkRect destSubset = SkRect::MakeWH(destWidth, destHeight); + SkResizeFilter filter(method, pmap.width(), pmap.height(), + destWidth, destHeight, destSubset, convolveProcs); + + // Get a source bitmap encompassing this touched area. We construct the + // offsets and row strides such that it looks like a new bitmap, while + // referring to the old data. + const uint8_t* sourceSubset = reinterpret_cast(pmap.addr()); + + // Convolve into the result. + SkBitmap result; + result.setInfo(SkImageInfo::MakeN32(SkScalarCeilToInt(destSubset.width()), + SkScalarCeilToInt(destSubset.height()), + pmap.alphaType())); + result.allocPixels(allocator, NULL); + if (!result.readyToDraw()) { + return false; + } + + BGRAConvolve2D(sourceSubset, static_cast(pmap.rowBytes()), + !pmap.isOpaque(), filter.xFilter(), filter.yFilter(), + static_cast(result.rowBytes()), + static_cast(result.getPixels()), + convolveProcs, true); + + *resultPtr = result; + resultPtr->lockPixels(); + SkASSERT(resultPtr->getPixels()); + return true; +} + bool SkBitmapScaler::Resize(SkBitmap* resultPtr, const SkBitmap& source, ResizeMethod method, float destWidth, float destHeight, SkBitmap::Allocator* allocator) { + if (source.colorType() != kN32_SkColorType) { + return false; + } - SkConvolutionProcs convolveProcs= { 0, NULL, NULL, NULL, NULL }; - PlatformConvolutionProcs(&convolveProcs); - - SkRect destSubset = { 0, 0, destWidth, destHeight }; + SkConvolutionProcs convolveProcs= { 0, NULL, NULL, NULL, NULL }; + PlatformConvolutionProcs(&convolveProcs); - // Ensure that the ResizeMethod enumeration is sound. - SkASSERT(((RESIZE_FIRST_QUALITY_METHOD <= method) && + // Ensure that the ResizeMethod enumeration is sound. + SkASSERT(((RESIZE_FIRST_QUALITY_METHOD <= method) && (method <= RESIZE_LAST_QUALITY_METHOD)) || ((RESIZE_FIRST_ALGORITHM_METHOD <= method) && (method <= RESIZE_LAST_ALGORITHM_METHOD))); - // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just - // return empty. - if (source.width() < 1 || source.height() < 1 || - destWidth < 1 || destHeight < 1) { - // todo: seems like we could handle negative dstWidth/Height, since that - // is just a negative scale (flip) - return false; - } + // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just + // return empty. + if (source.width() < 1 || source.height() < 1 || destWidth < 1 || destHeight < 1) { + // todo: seems like we could handle negative dstWidth/Height, since that + // is just a negative scale (flip) + return false; + } - method = ResizeMethodToAlgorithmMethod(method); + method = ResizeMethodToAlgorithmMethod(method); - // Check that we deal with an "algorithm methods" from this point onward. - SkASSERT((SkBitmapScaler::RESIZE_FIRST_ALGORITHM_METHOD <= method) && + // Check that we deal with an "algorithm methods" from this point onward. + SkASSERT((SkBitmapScaler::RESIZE_FIRST_ALGORITHM_METHOD <= method) && (method <= SkBitmapScaler::RESIZE_LAST_ALGORITHM_METHOD)); - SkAutoLockPixels locker(source); - if (!source.readyToDraw() || - source.colorType() != kN32_SkColorType) { - return false; - } - - SkResizeFilter filter(method, source.width(), source.height(), - destWidth, destHeight, destSubset, convolveProcs); - - // Get a source bitmap encompassing this touched area. We construct the - // offsets and row strides such that it looks like a new bitmap, while - // referring to the old data. - const unsigned char* sourceSubset = - reinterpret_cast(source.getPixels()); - - // Convolve into the result. - SkBitmap result; - result.setInfo(SkImageInfo::MakeN32(SkScalarCeilToInt(destSubset.width()), - SkScalarCeilToInt(destSubset.height()), - source.alphaType())); - result.allocPixels(allocator, NULL); - if (!result.readyToDraw()) { - return false; - } - - BGRAConvolve2D(sourceSubset, static_cast(source.rowBytes()), - !source.isOpaque(), filter.xFilter(), filter.yFilter(), - static_cast(result.rowBytes()), - static_cast(result.getPixels()), - convolveProcs, true); - - *resultPtr = result; - resultPtr->lockPixels(); - SkASSERT(resultPtr->getPixels()); - return true; + SkAutoPixmapUnlock result; + if (!source.requestLock(&result)) { + return false; + } + return resize(result.pixmap(), resultPtr, method, destWidth, destHeight, allocator, + convolveProcs); } // static -- simpler interface to the resizer; returns a default bitmap if scaling -- cgit v1.2.3