OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBitmapScaler.h" | 8 #include "SkBitmapScaler.h" |
9 #include "SkBitmapFilter.h" | 9 #include "SkBitmapFilter.h" |
10 #include "SkRect.h" | 10 #include "SkRect.h" |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 return SkBitmapScaler::RESIZE_HAMMING; | 241 return SkBitmapScaler::RESIZE_HAMMING; |
242 default: | 242 default: |
243 #ifdef SK_HIGH_QUALITY_IS_LANCZOS | 243 #ifdef SK_HIGH_QUALITY_IS_LANCZOS |
244 return SkBitmapScaler::RESIZE_LANCZOS3; | 244 return SkBitmapScaler::RESIZE_LANCZOS3; |
245 #else | 245 #else |
246 return SkBitmapScaler::RESIZE_MITCHELL; | 246 return SkBitmapScaler::RESIZE_MITCHELL; |
247 #endif | 247 #endif |
248 } | 248 } |
249 } | 249 } |
250 | 250 |
251 // static | 251 bool SkBitmapScaler::Resize(SkBitmap* resultPtr, const SkPixmap& source, ResizeM
ethod method, |
252 bool SkBitmapScaler::Resize(SkBitmap* resultPtr, | |
253 const SkBitmap& source, | |
254 ResizeMethod method, | |
255 float destWidth, float destHeight, | 252 float destWidth, float destHeight, |
256 SkBitmap::Allocator* allocator) { | 253 SkBitmap::Allocator* allocator) { |
| 254 if (NULL == source.addr() || source.colorType() != kN32_SkColorType || |
| 255 source.width() < 1 || source.height() < 1) |
| 256 { |
| 257 return false; |
| 258 } |
257 | 259 |
258 SkConvolutionProcs convolveProcs= { 0, NULL, NULL, NULL, NULL }; | 260 if (destWidth < 1 || destHeight < 1) { |
259 PlatformConvolutionProcs(&convolveProcs); | 261 // todo: seems like we could handle negative dstWidth/Height, since that |
| 262 // is just a negative scale (flip) |
| 263 return false; |
| 264 } |
260 | 265 |
261 SkRect destSubset = { 0, 0, destWidth, destHeight }; | 266 SkConvolutionProcs convolveProcs= { 0, NULL, NULL, NULL, NULL }; |
| 267 PlatformConvolutionProcs(&convolveProcs); |
262 | 268 |
263 // Ensure that the ResizeMethod enumeration is sound. | 269 SkRect destSubset = { 0, 0, destWidth, destHeight }; |
264 SkASSERT(((RESIZE_FIRST_QUALITY_METHOD <= method) && | 270 |
| 271 // Ensure that the ResizeMethod enumeration is sound. |
| 272 SkASSERT(((RESIZE_FIRST_QUALITY_METHOD <= method) && |
265 (method <= RESIZE_LAST_QUALITY_METHOD)) || | 273 (method <= RESIZE_LAST_QUALITY_METHOD)) || |
266 ((RESIZE_FIRST_ALGORITHM_METHOD <= method) && | 274 ((RESIZE_FIRST_ALGORITHM_METHOD <= method) && |
267 (method <= RESIZE_LAST_ALGORITHM_METHOD))); | 275 (method <= RESIZE_LAST_ALGORITHM_METHOD))); |
268 | 276 |
269 // If the size of source or destination is 0, i.e. 0x0, 0xN or Nx0, just | 277 method = ResizeMethodToAlgorithmMethod(method); |
270 // return empty. | |
271 if (source.width() < 1 || source.height() < 1 || | |
272 destWidth < 1 || destHeight < 1) { | |
273 // todo: seems like we could handle negative dstWidth/Height, since that | |
274 // is just a negative scale (flip) | |
275 return false; | |
276 } | |
277 | 278 |
278 method = ResizeMethodToAlgorithmMethod(method); | 279 // Check that we deal with an "algorithm methods" from this point onward. |
279 | 280 SkASSERT((SkBitmapScaler::RESIZE_FIRST_ALGORITHM_METHOD <= method) && |
280 // Check that we deal with an "algorithm methods" from this point onward. | |
281 SkASSERT((SkBitmapScaler::RESIZE_FIRST_ALGORITHM_METHOD <= method) && | |
282 (method <= SkBitmapScaler::RESIZE_LAST_ALGORITHM_METHOD)); | 281 (method <= SkBitmapScaler::RESIZE_LAST_ALGORITHM_METHOD)); |
283 | 282 |
284 SkAutoLockPixels locker(source); | 283 SkResizeFilter filter(method, source.width(), source.height(), |
285 if (!source.readyToDraw() || | |
286 source.colorType() != kN32_SkColorType) { | |
287 return false; | |
288 } | |
289 | |
290 SkResizeFilter filter(method, source.width(), source.height(), | |
291 destWidth, destHeight, destSubset, convolveProcs); | 284 destWidth, destHeight, destSubset, convolveProcs); |
292 | 285 |
293 // Get a source bitmap encompassing this touched area. We construct the | 286 // Get a subset encompassing this touched area. We construct the |
294 // offsets and row strides such that it looks like a new bitmap, while | 287 // offsets and row strides such that it looks like a new bitmap, while |
295 // referring to the old data. | 288 // referring to the old data. |
296 const unsigned char* sourceSubset = | 289 const uint8_t* sourceSubset = reinterpret_cast<const uint8_t*>(source.addr()
); |
297 reinterpret_cast<const unsigned char*>(source.getPixels()); | |
298 | 290 |
299 // Convolve into the result. | 291 // Convolve into the result. |
300 SkBitmap result; | 292 SkBitmap result; |
301 result.setInfo(SkImageInfo::MakeN32(SkScalarCeilToInt(destSubset.width()), | 293 result.setInfo(SkImageInfo::MakeN32(SkScalarCeilToInt(destSubset.width()), |
302 SkScalarCeilToInt(destSubset.height()), | 294 SkScalarCeilToInt(destSubset.height()), |
303 source.alphaType())); | 295 source.alphaType())); |
304 result.allocPixels(allocator, NULL); | 296 result.allocPixels(allocator, NULL); |
305 if (!result.readyToDraw()) { | 297 if (!result.readyToDraw()) { |
306 return false; | 298 return false; |
307 } | 299 } |
308 | 300 |
309 BGRAConvolve2D(sourceSubset, static_cast<int>(source.rowBytes()), | 301 BGRAConvolve2D(sourceSubset, static_cast<int>(source.rowBytes()), |
310 !source.isOpaque(), filter.xFilter(), filter.yFilter(), | 302 !source.isOpaque(), filter.xFilter(), filter.yFilter(), |
311 static_cast<int>(result.rowBytes()), | 303 static_cast<int>(result.rowBytes()), |
312 static_cast<unsigned char*>(result.getPixels()), | 304 static_cast<unsigned char*>(result.getPixels()), |
313 convolveProcs, true); | 305 convolveProcs, true); |
314 | 306 |
315 *resultPtr = result; | 307 *resultPtr = result; |
316 resultPtr->lockPixels(); | 308 resultPtr->lockPixels(); |
317 SkASSERT(resultPtr->getPixels()); | 309 SkASSERT(resultPtr->getPixels()); |
318 return true; | 310 return true; |
319 } | 311 } |
320 | 312 |
OLD | NEW |