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 "SkConvolver.h" | 10 #include "SkConvolver.h" |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 #else | 242 #else |
243 output->AddFilter(SkScalarFloorToInt(srcBegin), fixedFilterValues, filterCou
nt); | 243 output->AddFilter(SkScalarFloorToInt(srcBegin), fixedFilterValues, filterCou
nt); |
244 #endif | 244 #endif |
245 } | 245 } |
246 | 246 |
247 if (convolveProcs.fApplySIMDPadding) { | 247 if (convolveProcs.fApplySIMDPadding) { |
248 convolveProcs.fApplySIMDPadding(output); | 248 convolveProcs.fApplySIMDPadding(output); |
249 } | 249 } |
250 } | 250 } |
251 | 251 |
252 bool SkBitmapScaler::Resize(SkBitmap* resultPtr, const SkPixmap& source, ResizeM
ethod method, | 252 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
253 int destWidth, int destHeight, SkBitmap::Allocator*
allocator) { | 253 |
254 if (nullptr == source.addr() || source.colorType() != kN32_SkColorType || | 254 static bool valid_for_resize(const SkPixmap& source, int dstW, int dstH) { |
255 source.width() < 1 || source.height() < 1) | 255 // TODO: Seems like we shouldn't care about the swizzle of source, just that
it's 8888 |
256 { | 256 return source.addr() && source.colorType() == kN32_SkColorType && |
| 257 source.width() >= 1 && source.height() >= 1 && dstW >= 1 && dstH >= 1
; |
| 258 } |
| 259 |
| 260 bool SkBitmapScaler::Resize(const SkPixmap& result, const SkPixmap& source, Resi
zeMethod method) { |
| 261 if (!valid_for_resize(source, result.width(), result.height())) { |
257 return false; | 262 return false; |
258 } | 263 } |
259 | 264 if (!result.addr() || result.colorType() != source.colorType()) { |
260 if (destWidth < 1 || destHeight < 1) { | |
261 return false; | 265 return false; |
262 } | 266 } |
263 | 267 |
264 SkConvolutionProcs convolveProcs= { 0, nullptr, nullptr, nullptr, nullptr }; | 268 SkConvolutionProcs convolveProcs= { 0, nullptr, nullptr, nullptr, nullptr }; |
265 PlatformConvolutionProcs(&convolveProcs); | 269 PlatformConvolutionProcs(&convolveProcs); |
266 | 270 |
267 SkRect destSubset = SkRect::MakeIWH(destWidth, destHeight); | 271 SkRect destSubset = SkRect::MakeIWH(result.width(), result.height()); |
268 | 272 |
269 SkResizeFilter filter(method, source.width(), source.height(), | 273 SkResizeFilter filter(method, source.width(), source.height(), |
270 destWidth, destHeight, destSubset, convolveProcs); | 274 result.width(), result.height(), destSubset, convolveP
rocs); |
271 | 275 |
272 // Get a subset encompassing this touched area. We construct the | 276 // Get a subset encompassing this touched area. We construct the |
273 // offsets and row strides such that it looks like a new bitmap, while | 277 // offsets and row strides such that it looks like a new bitmap, while |
274 // referring to the old data. | 278 // referring to the old data. |
275 const uint8_t* sourceSubset = reinterpret_cast<const uint8_t*>(source.addr()
); | 279 const uint8_t* sourceSubset = reinterpret_cast<const uint8_t*>(source.addr()
); |
276 | 280 |
277 // Convolve into the result. | 281 return BGRAConvolve2D(sourceSubset, static_cast<int>(source.rowBytes()), |
278 SkBitmap result; | 282 !source.isOpaque(), filter.xFilter(), filter.yFilter()
, |
279 result.setInfo(SkImageInfo::MakeN32(SkScalarCeilToInt(destSubset.width()), | 283 static_cast<int>(result.rowBytes()), |
280 SkScalarCeilToInt(destSubset.height()), | 284 static_cast<unsigned char*>(result.writable_addr()), |
281 source.alphaType())); | 285 convolveProcs, true); |
282 result.allocPixels(allocator, nullptr); | 286 } |
283 if (!result.readyToDraw()) { | |
284 return false; | |
285 } | |
286 | 287 |
287 if (!BGRAConvolve2D(sourceSubset, static_cast<int>(source.rowBytes()), | 288 bool SkBitmapScaler::Resize(SkBitmap* resultPtr, const SkPixmap& source, ResizeM
ethod method, |
288 !source.isOpaque(), filter.xFilter(), filter.yFilter(), | 289 int destWidth, int destHeight, SkBitmap::Allocator*
allocator) { |
289 static_cast<int>(result.rowBytes()), | 290 // Preflight some of the checks, to avoid allocating the result if we don't
need it. |
290 static_cast<unsigned char*>(result.getPixels()), | 291 if (!valid_for_resize(source, destWidth, destHeight)) { |
291 convolveProcs, true)) { | |
292 return false; | 292 return false; |
293 } | 293 } |
294 | 294 |
| 295 SkBitmap result; |
| 296 result.setInfo(SkImageInfo::MakeN32(destWidth, destHeight, source.alphaType(
))); |
| 297 result.allocPixels(allocator, nullptr); |
| 298 |
| 299 SkPixmap resultPM; |
| 300 if (!result.peekPixels(&resultPM) || !Resize(resultPM, source, method)) { |
| 301 return false; |
| 302 } |
| 303 |
295 *resultPtr = result; | 304 *resultPtr = result; |
296 resultPtr->lockPixels(); | 305 resultPtr->lockPixels(); |
297 SkASSERT(resultPtr->getPixels()); | 306 SkASSERT(resultPtr->getPixels()); |
298 return true; | 307 return true; |
299 } | 308 } |
300 | 309 |
OLD | NEW |