OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
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 "SkMatrixConvolutionImageFilter.h" | 8 #include "SkMatrixConvolutionImageFilter.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| 11 #include "SkImagePriv.h" |
| 12 #include "SkImage_Base.h" |
11 #include "SkReadBuffer.h" | 13 #include "SkReadBuffer.h" |
12 #include "SkWriteBuffer.h" | |
13 #include "SkRect.h" | 14 #include "SkRect.h" |
14 #include "SkUnPreMultiply.h" | 15 #include "SkUnPreMultiply.h" |
| 16 #include "SkWriteBuffer.h" |
15 | 17 |
16 #if SK_SUPPORT_GPU | 18 #if SK_SUPPORT_GPU |
17 #include "effects/GrMatrixConvolutionEffect.h" | 19 #include "effects/GrMatrixConvolutionEffect.h" |
18 #endif | 20 #endif |
19 | 21 |
20 // We need to be able to read at most SK_MaxS32 bytes, so divide that | 22 // We need to be able to read at most SK_MaxS32 bytes, so divide that |
21 // by the size of a scalar to know how many scalars we can read. | 23 // by the size of a scalar to know how many scalars we can read. |
22 static const int32_t gMaxKernelSize = SK_MaxS32 / sizeof(SkScalar); | 24 static const int32_t gMaxKernelSize = SK_MaxS32 / sizeof(SkScalar); |
23 | 25 |
24 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( | 26 SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 const uint32_t* srcRow = src.getAddr32(0, y); | 260 const uint32_t* srcRow = src.getAddr32(0, y); |
259 uint32_t* dstRow = result.getAddr32(0, y); | 261 uint32_t* dstRow = result.getAddr32(0, y); |
260 for (int x = 0; x < src.width(); ++x) { | 262 for (int x = 0; x < src.width(); ++x) { |
261 dstRow[x] = SkUnPreMultiply::PMColorToColor(srcRow[x]); | 263 dstRow[x] = SkUnPreMultiply::PMColorToColor(srcRow[x]); |
262 } | 264 } |
263 } | 265 } |
264 return result; | 266 return result; |
265 } | 267 } |
266 | 268 |
267 bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy, | 269 bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy, |
268 const SkBitmap& source, | 270 const SkImage* source, |
269 const Context& ctx, | 271 const Context& ctx, |
270 SkBitmap* result, | 272 SkAutoTUnref<const SkImage>&
result, |
271 SkIPoint* offset) const { | 273 SkIPoint* offset) const { |
272 SkBitmap src = source; | 274 SkAutoTUnref<const SkImage> src(SkRef(source)); |
273 SkIPoint srcOffset = SkIPoint::Make(0, 0); | 275 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
274 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcO
ffset)) { | 276 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, src, &srcOf
fset)) { |
275 return false; | |
276 } | |
277 | |
278 if (src.colorType() != kN32_SkColorType) { | |
279 return false; | 277 return false; |
280 } | 278 } |
281 | 279 |
282 SkIRect bounds; | 280 SkIRect bounds; |
283 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { | 281 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, src)) { |
284 return false; | 282 return false; |
285 } | 283 } |
286 | 284 |
287 if (!fConvolveAlpha && !src.isOpaque()) { | 285 SkBitmap srcBitmap; |
288 src = unpremultiplyBitmap(src); | 286 if (!as_IB(src)->getROPixels(&srcBitmap)) { |
289 } | |
290 | |
291 SkAutoLockPixels alp(src); | |
292 if (!src.getPixels()) { | |
293 return false; | 287 return false; |
294 } | 288 } |
295 | 289 |
296 if (!result->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height(
)))) { | 290 if (srcBitmap.colorType() != kN32_SkColorType) { |
297 return false; | 291 return false; |
298 } | 292 } |
299 | 293 |
300 offset->fX = bounds.fLeft; | 294 src.reset(NULL); |
301 offset->fY = bounds.fTop; | 295 |
| 296 if (!fConvolveAlpha && !srcBitmap.isOpaque()) { |
| 297 srcBitmap = unpremultiplyBitmap(srcBitmap); |
| 298 } |
| 299 |
| 300 SkAutoLockPixels alp(srcBitmap); |
| 301 if (!srcBitmap.getPixels()) { |
| 302 return false; |
| 303 } |
| 304 |
| 305 SkBitmap resultBitmap; |
| 306 if (!resultBitmap.tryAllocPixels(srcBitmap.info().makeWH(bounds.width(), bou
nds.height()))) { |
| 307 return false; |
| 308 } |
| 309 |
| 310 int32_t resultX = bounds.fLeft; |
| 311 int32_t resultY = bounds.fTop; |
302 bounds.offset(-srcOffset); | 312 bounds.offset(-srcOffset); |
303 SkIRect interior = SkIRect::MakeXYWH(bounds.left() + fKernelOffset.fX, | 313 SkIRect interior = SkIRect::MakeXYWH(bounds.left() + fKernelOffset.fX, |
304 bounds.top() + fKernelOffset.fY, | 314 bounds.top() + fKernelOffset.fY, |
305 bounds.width() - fKernelSize.fWidth + 1
, | 315 bounds.width() - fKernelSize.fWidth + 1
, |
306 bounds.height() - fKernelSize.fHeight +
1); | 316 bounds.height() - fKernelSize.fHeight +
1); |
307 SkIRect top = SkIRect::MakeLTRB(bounds.left(), bounds.top(), bounds.right(),
interior.top()); | 317 SkIRect top = SkIRect::MakeLTRB(bounds.left(), bounds.top(), bounds.right(),
interior.top()); |
308 SkIRect bottom = SkIRect::MakeLTRB(bounds.left(), interior.bottom(), | 318 SkIRect bottom = SkIRect::MakeLTRB(bounds.left(), interior.bottom(), |
309 bounds.right(), bounds.bottom()); | 319 bounds.right(), bounds.bottom()); |
310 SkIRect left = SkIRect::MakeLTRB(bounds.left(), interior.top(), | 320 SkIRect left = SkIRect::MakeLTRB(bounds.left(), interior.top(), |
311 interior.left(), interior.bottom()); | 321 interior.left(), interior.bottom()); |
312 SkIRect right = SkIRect::MakeLTRB(interior.right(), interior.top(), | 322 SkIRect right = SkIRect::MakeLTRB(interior.right(), interior.top(), |
313 bounds.right(), interior.bottom()); | 323 bounds.right(), interior.bottom()); |
314 filterBorderPixels(src, result, top, bounds); | 324 filterBorderPixels(srcBitmap, &resultBitmap, top, bounds); |
315 filterBorderPixels(src, result, left, bounds); | 325 filterBorderPixels(srcBitmap, &resultBitmap, left, bounds); |
316 filterInteriorPixels(src, result, interior, bounds); | 326 filterInteriorPixels(srcBitmap, &resultBitmap, interior, bounds); |
317 filterBorderPixels(src, result, right, bounds); | 327 filterBorderPixels(srcBitmap, &resultBitmap, right, bounds); |
318 filterBorderPixels(src, result, bottom, bounds); | 328 filterBorderPixels(srcBitmap, &resultBitmap, bottom, bounds); |
| 329 |
| 330 srcBitmap = SkBitmap(); |
| 331 |
| 332 SkImage* image = SkNewImageFromBitmap(resultBitmap, NULL); |
| 333 if (NULL == image) { |
| 334 return false; |
| 335 } |
| 336 result.reset(image); |
| 337 offset->fX = resultX; |
| 338 offset->fY = resultY; |
319 return true; | 339 return true; |
320 } | 340 } |
321 | 341 |
322 bool SkMatrixConvolutionImageFilter::onFilterBounds(const SkIRect& src, const Sk
Matrix& ctm, | 342 bool SkMatrixConvolutionImageFilter::onFilterBounds(const SkIRect& src, const Sk
Matrix& ctm, |
323 SkIRect* dst) const { | 343 SkIRect* dst) const { |
324 SkIRect bounds = src; | 344 SkIRect bounds = src; |
325 bounds.fRight += fKernelSize.width() - 1; | 345 bounds.fRight += fKernelSize.width() - 1; |
326 bounds.fBottom += fKernelSize.height() - 1; | 346 bounds.fBottom += fKernelSize.height() - 1; |
327 bounds.offset(-fKernelOffset); | 347 bounds.offset(-fKernelOffset); |
328 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { | 348 if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 str->appendf("%f ", fKernel[y * fKernelSize.width() + x]); | 399 str->appendf("%f ", fKernel[y * fKernelSize.width() + x]); |
380 } | 400 } |
381 } | 401 } |
382 str->appendf(")"); | 402 str->appendf(")"); |
383 str->appendf("gain: %f bias: %f ", fGain, fBias); | 403 str->appendf("gain: %f bias: %f ", fGain, fBias); |
384 str->appendf("offset: (%d, %d) ", fKernelOffset.fX, fKernelOffset.fY); | 404 str->appendf("offset: (%d, %d) ", fKernelOffset.fX, fKernelOffset.fY); |
385 str->appendf("convolveAlpha: %s", fConvolveAlpha ? "true" : "false"); | 405 str->appendf("convolveAlpha: %s", fConvolveAlpha ? "true" : "false"); |
386 str->append(")"); | 406 str->append(")"); |
387 } | 407 } |
388 #endif | 408 #endif |
OLD | NEW |