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