OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkBlurMask.h" | 10 #include "SkBlurMask.h" |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 } | 428 } |
429 dst += dstRB; | 429 dst += dstRB; |
430 src += srcRB; | 430 src += srcRB; |
431 blur += blurRB; | 431 blur += blurRB; |
432 } | 432 } |
433 } | 433 } |
434 | 434 |
435 static void clamp_with_orig(uint8_t dst[], int dstRowBytes, | 435 static void clamp_with_orig(uint8_t dst[], int dstRowBytes, |
436 const uint8_t src[], int srcRowBytes, | 436 const uint8_t src[], int srcRowBytes, |
437 int sw, int sh, | 437 int sw, int sh, |
438 SkBlurMask::Style style) { | 438 SkBlurStyle style) { |
439 int x; | 439 int x; |
440 while (--sh >= 0) { | 440 while (--sh >= 0) { |
441 switch (style) { | 441 switch (style) { |
442 case SkBlurMask::kSolid_Style: | 442 case kSolid_SkBlurStyle: |
443 for (x = sw - 1; x >= 0; --x) { | 443 for (x = sw - 1; x >= 0; --x) { |
444 int s = *src; | 444 int s = *src; |
445 int d = *dst; | 445 int d = *dst; |
446 *dst = SkToU8(s + d - SkMulDiv255Round(s, d)); | 446 *dst = SkToU8(s + d - SkMulDiv255Round(s, d)); |
447 dst += 1; | 447 dst += 1; |
448 src += 1; | 448 src += 1; |
449 } | 449 } |
450 break; | 450 break; |
451 case SkBlurMask::kOuter_Style: | 451 case kOuter_SkBlurStyle: |
452 for (x = sw - 1; x >= 0; --x) { | 452 for (x = sw - 1; x >= 0; --x) { |
453 if (*src) { | 453 if (*src) { |
454 *dst = SkToU8(SkAlphaMul(*dst, SkAlpha255To256(255 - *src)))
; | 454 *dst = SkToU8(SkAlphaMul(*dst, SkAlpha255To256(255 - *src)))
; |
455 } | 455 } |
456 dst += 1; | 456 dst += 1; |
457 src += 1; | 457 src += 1; |
458 } | 458 } |
459 break; | 459 break; |
460 default: | 460 default: |
461 SkDEBUGFAIL("Unexpected blur style here"); | 461 SkDEBUGFAIL("Unexpected blur style here"); |
462 break; | 462 break; |
463 } | 463 } |
464 dst += dstRowBytes - sw; | 464 dst += dstRowBytes - sw; |
465 src += srcRowBytes - sw; | 465 src += srcRowBytes - sw; |
466 } | 466 } |
467 } | 467 } |
468 | 468 |
469 /////////////////////////////////////////////////////////////////////////////// | 469 /////////////////////////////////////////////////////////////////////////////// |
470 | 470 |
471 // we use a local function to wrap the class static method to work around | 471 // we use a local function to wrap the class static method to work around |
472 // a bug in gcc98 | 472 // a bug in gcc98 |
473 void SkMask_FreeImage(uint8_t* image); | 473 void SkMask_FreeImage(uint8_t* image); |
474 void SkMask_FreeImage(uint8_t* image) { | 474 void SkMask_FreeImage(uint8_t* image) { |
475 SkMask::FreeImage(image); | 475 SkMask::FreeImage(image); |
476 } | 476 } |
477 | 477 |
478 bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src, | 478 bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src, SkScalar sigma, SkBlurS
tyle style, |
479 SkScalar sigma, Style style, Quality quality, | 479 SkBlurQuality quality, SkIPoint* margin) { |
480 SkIPoint* margin) { | |
481 | 480 |
482 if (src.fFormat != SkMask::kA8_Format) { | 481 if (src.fFormat != SkMask::kA8_Format) { |
483 return false; | 482 return false; |
484 } | 483 } |
485 | 484 |
486 // Force high quality off for small radii (performance) | 485 // Force high quality off for small radii (performance) |
487 if (sigma <= SkIntToScalar(2)) { | 486 if (sigma <= SkIntToScalar(2)) { |
488 quality = kLow_Quality; | 487 quality = kLow_SkBlurQuality; |
489 } | 488 } |
490 | 489 |
491 SkScalar passRadius; | 490 SkScalar passRadius; |
492 if (kHigh_Quality == quality) { | 491 if (kHigh_SkBlurQuality == quality) { |
493 // For the high quality path the 3 pass box blur kernel width is | 492 // For the high quality path the 3 pass box blur kernel width is |
494 // 6*rad+1 while the full Gaussian width is 6*sigma. | 493 // 6*rad+1 while the full Gaussian width is 6*sigma. |
495 passRadius = sigma - (1/6.0f); | 494 passRadius = sigma - (1/6.0f); |
496 } else { | 495 } else { |
497 // For the low quality path we only attempt to cover 3*sigma of the | 496 // For the low quality path we only attempt to cover 3*sigma of the |
498 // Gaussian blur area (1.5*sigma on each side). The single pass box | 497 // Gaussian blur area (1.5*sigma on each side). The single pass box |
499 // blur's kernel size is 2*rad+1. | 498 // blur's kernel size is 2*rad+1. |
500 passRadius = 1.5f*sigma - 0.5f; | 499 passRadius = 1.5f*sigma - 0.5f; |
501 } | 500 } |
502 | 501 |
503 // highQuality: use three box blur passes as a cheap way | 502 // highQuality: use three box blur passes as a cheap way |
504 // to approximate a Gaussian blur | 503 // to approximate a Gaussian blur |
505 int passCount = (kHigh_Quality == quality) ? 3 : 1; | 504 int passCount = (kHigh_SkBlurQuality == quality) ? 3 : 1; |
506 | 505 |
507 int rx = SkScalarCeilToInt(passRadius); | 506 int rx = SkScalarCeilToInt(passRadius); |
508 int outerWeight = 255 - SkScalarRoundToInt((SkIntToScalar(rx) - passRadius)
* 255); | 507 int outerWeight = 255 - SkScalarRoundToInt((SkIntToScalar(rx) - passRadius)
* 255); |
509 | 508 |
510 SkASSERT(rx >= 0); | 509 SkASSERT(rx >= 0); |
511 SkASSERT((unsigned)outerWeight <= 255); | 510 SkASSERT((unsigned)outerWeight <= 255); |
512 if (rx <= 0) { | 511 if (rx <= 0) { |
513 return false; | 512 return false; |
514 } | 513 } |
515 | 514 |
(...skipping 25 matching lines...) Expand all Loading... |
541 SkAutoTCallVProc<uint8_t, SkMask_FreeImage> autoCall(dp); | 540 SkAutoTCallVProc<uint8_t, SkMask_FreeImage> autoCall(dp); |
542 | 541 |
543 // build the blurry destination | 542 // build the blurry destination |
544 SkAutoTMalloc<uint8_t> tmpBuffer(dstSize); | 543 SkAutoTMalloc<uint8_t> tmpBuffer(dstSize); |
545 uint8_t* tp = tmpBuffer.get(); | 544 uint8_t* tp = tmpBuffer.get(); |
546 int w = sw, h = sh; | 545 int w = sw, h = sh; |
547 | 546 |
548 if (outerWeight == 255) { | 547 if (outerWeight == 255) { |
549 int loRadius, hiRadius; | 548 int loRadius, hiRadius; |
550 get_adjusted_radii(passRadius, &loRadius, &hiRadius); | 549 get_adjusted_radii(passRadius, &loRadius, &hiRadius); |
551 if (kHigh_Quality == quality) { | 550 if (kHigh_SkBlurQuality == quality) { |
552 // Do three X blurs, with a transpose on the final one. | 551 // Do three X blurs, with a transpose on the final one. |
553 w = boxBlur(sp, src.fRowBytes, tp, loRadius, hiRadius, w, h, fal
se); | 552 w = boxBlur(sp, src.fRowBytes, tp, loRadius, hiRadius, w, h, fal
se); |
554 w = boxBlur(tp, w, dp, hiRadius, loRadius, w, h, fal
se); | 553 w = boxBlur(tp, w, dp, hiRadius, loRadius, w, h, fal
se); |
555 w = boxBlur(dp, w, tp, hiRadius, hiRadius, w, h, tru
e); | 554 w = boxBlur(dp, w, tp, hiRadius, hiRadius, w, h, tru
e); |
556 // Do three Y blurs, with a transpose on the final one. | 555 // Do three Y blurs, with a transpose on the final one. |
557 h = boxBlur(tp, h, dp, loRadius, hiRadius, h, w, fal
se); | 556 h = boxBlur(tp, h, dp, loRadius, hiRadius, h, w, fal
se); |
558 h = boxBlur(dp, h, tp, hiRadius, loRadius, h, w, fal
se); | 557 h = boxBlur(dp, h, tp, hiRadius, loRadius, h, w, fal
se); |
559 h = boxBlur(tp, h, dp, hiRadius, hiRadius, h, w, tru
e); | 558 h = boxBlur(tp, h, dp, hiRadius, hiRadius, h, w, tru
e); |
560 } else { | 559 } else { |
561 w = boxBlur(sp, src.fRowBytes, tp, rx, rx, w, h, true); | 560 w = boxBlur(sp, src.fRowBytes, tp, rx, rx, w, h, true); |
562 h = boxBlur(tp, h, dp, ry, ry, h, w, true); | 561 h = boxBlur(tp, h, dp, ry, ry, h, w, true); |
563 } | 562 } |
564 } else { | 563 } else { |
565 if (kHigh_Quality == quality) { | 564 if (kHigh_SkBlurQuality == quality) { |
566 // Do three X blurs, with a transpose on the final one. | 565 // Do three X blurs, with a transpose on the final one. |
567 w = boxBlurInterp(sp, src.fRowBytes, tp, rx, w, h, false, outerW
eight); | 566 w = boxBlurInterp(sp, src.fRowBytes, tp, rx, w, h, false, outerW
eight); |
568 w = boxBlurInterp(tp, w, dp, rx, w, h, false, outerW
eight); | 567 w = boxBlurInterp(tp, w, dp, rx, w, h, false, outerW
eight); |
569 w = boxBlurInterp(dp, w, tp, rx, w, h, true, outerWe
ight); | 568 w = boxBlurInterp(dp, w, tp, rx, w, h, true, outerWe
ight); |
570 // Do three Y blurs, with a transpose on the final one. | 569 // Do three Y blurs, with a transpose on the final one. |
571 h = boxBlurInterp(tp, h, dp, ry, h, w, false, outerW
eight); | 570 h = boxBlurInterp(tp, h, dp, ry, h, w, false, outerW
eight); |
572 h = boxBlurInterp(dp, h, tp, ry, h, w, false, outerW
eight); | 571 h = boxBlurInterp(dp, h, tp, ry, h, w, false, outerW
eight); |
573 h = boxBlurInterp(tp, h, dp, ry, h, w, true, outerWe
ight); | 572 h = boxBlurInterp(tp, h, dp, ry, h, w, true, outerWe
ight); |
574 } else { | 573 } else { |
575 w = boxBlurInterp(sp, src.fRowBytes, tp, rx, w, h, true, outerWe
ight); | 574 w = boxBlurInterp(sp, src.fRowBytes, tp, rx, w, h, true, outerWe
ight); |
576 h = boxBlurInterp(tp, h, dp, ry, h, w, true, outerWe
ight); | 575 h = boxBlurInterp(tp, h, dp, ry, h, w, true, outerWe
ight); |
577 } | 576 } |
578 } | 577 } |
579 | 578 |
580 dst->fImage = dp; | 579 dst->fImage = dp; |
581 // if need be, alloc the "real" dst (same size as src) and copy/merge | 580 // if need be, alloc the "real" dst (same size as src) and copy/merge |
582 // the blur into it (applying the src) | 581 // the blur into it (applying the src) |
583 if (style == kInner_Style) { | 582 if (style == kInner_SkBlurStyle) { |
584 // now we allocate the "real" dst, mirror the size of src | 583 // now we allocate the "real" dst, mirror the size of src |
585 size_t srcSize = src.computeImageSize(); | 584 size_t srcSize = src.computeImageSize(); |
586 if (0 == srcSize) { | 585 if (0 == srcSize) { |
587 return false; // too big to allocate, abort | 586 return false; // too big to allocate, abort |
588 } | 587 } |
589 dst->fImage = SkMask::AllocImage(srcSize); | 588 dst->fImage = SkMask::AllocImage(srcSize); |
590 merge_src_with_blur(dst->fImage, src.fRowBytes, | 589 merge_src_with_blur(dst->fImage, src.fRowBytes, |
591 sp, src.fRowBytes, | 590 sp, src.fRowBytes, |
592 dp + passCount * (rx + ry * dst->fRowBytes), | 591 dp + passCount * (rx + ry * dst->fRowBytes), |
593 dst->fRowBytes, sw, sh); | 592 dst->fRowBytes, sw, sh); |
594 SkMask::FreeImage(dp); | 593 SkMask::FreeImage(dp); |
595 } else if (style != kNormal_Style) { | 594 } else if (style != kNormal_SkBlurStyle) { |
596 clamp_with_orig(dp + passCount * (rx + ry * dst->fRowBytes), | 595 clamp_with_orig(dp + passCount * (rx + ry * dst->fRowBytes), |
597 dst->fRowBytes, sp, src.fRowBytes, sw, sh, style); | 596 dst->fRowBytes, sp, src.fRowBytes, sw, sh, style); |
598 } | 597 } |
599 (void)autoCall.detach(); | 598 (void)autoCall.detach(); |
600 } | 599 } |
601 | 600 |
602 if (style == kInner_Style) { | 601 if (style == kInner_SkBlurStyle) { |
603 dst->fBounds = src.fBounds; // restore trimmed bounds | 602 dst->fBounds = src.fBounds; // restore trimmed bounds |
604 dst->fRowBytes = src.fRowBytes; | 603 dst->fRowBytes = src.fRowBytes; |
605 } | 604 } |
606 | 605 |
607 return true; | 606 return true; |
608 } | 607 } |
609 | 608 |
610 /* Convolving a box with itself three times results in a piecewise | 609 /* Convolving a box with itself three times results in a piecewise |
611 quadratic function: | 610 quadratic function: |
612 | 611 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 pixels[x] = ProfileLookup(profile, x, width, w); | 726 pixels[x] = ProfileLookup(profile, x, width, w); |
728 } else { | 727 } else { |
729 float span = float(sw)/(2*sigma); | 728 float span = float(sw)/(2*sigma); |
730 float giX = 1.5f - (x+.5f)/(2*sigma); | 729 float giX = 1.5f - (x+.5f)/(2*sigma); |
731 pixels[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegra
l(giX + span))); | 730 pixels[x] = (uint8_t) (255 * (gaussianIntegral(giX) - gaussianIntegra
l(giX + span))); |
732 } | 731 } |
733 } | 732 } |
734 } | 733 } |
735 | 734 |
736 bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, | 735 bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, |
737 const SkRect &src, Style style, | 736 const SkRect &src, SkBlurStyle style, |
738 SkIPoint *margin, SkMask::CreateMode createMode) { | 737 SkIPoint *margin, SkMask::CreateMode createMode) { |
739 int profile_size = SkScalarCeilToInt(6*sigma); | 738 int profile_size = SkScalarCeilToInt(6*sigma); |
740 | 739 |
741 int pad = profile_size/2; | 740 int pad = profile_size/2; |
742 if (margin) { | 741 if (margin) { |
743 margin->set( pad, pad ); | 742 margin->set( pad, pad ); |
744 } | 743 } |
745 | 744 |
746 dst->fBounds.set(SkScalarRoundToInt(src.fLeft - pad), | 745 dst->fBounds.set(SkScalarRoundToInt(src.fLeft - pad), |
747 SkScalarRoundToInt(src.fTop - pad), | 746 SkScalarRoundToInt(src.fTop - pad), |
748 SkScalarRoundToInt(src.fRight + pad), | 747 SkScalarRoundToInt(src.fRight + pad), |
749 SkScalarRoundToInt(src.fBottom + pad)); | 748 SkScalarRoundToInt(src.fBottom + pad)); |
750 | 749 |
751 dst->fRowBytes = dst->fBounds.width(); | 750 dst->fRowBytes = dst->fBounds.width(); |
752 dst->fFormat = SkMask::kA8_Format; | 751 dst->fFormat = SkMask::kA8_Format; |
753 dst->fImage = NULL; | 752 dst->fImage = NULL; |
754 | 753 |
755 int sw = SkScalarFloorToInt(src.width()); | 754 int sw = SkScalarFloorToInt(src.width()); |
756 int sh = SkScalarFloorToInt(src.height()); | 755 int sh = SkScalarFloorToInt(src.height()); |
757 | 756 |
758 if (createMode == SkMask::kJustComputeBounds_CreateMode) { | 757 if (createMode == SkMask::kJustComputeBounds_CreateMode) { |
759 if (style == kInner_Style) { | 758 if (style == kInner_SkBlurStyle) { |
760 dst->fBounds.set(SkScalarRoundToInt(src.fLeft), | 759 dst->fBounds.set(SkScalarRoundToInt(src.fLeft), |
761 SkScalarRoundToInt(src.fTop), | 760 SkScalarRoundToInt(src.fTop), |
762 SkScalarRoundToInt(src.fRight), | 761 SkScalarRoundToInt(src.fRight), |
763 SkScalarRoundToInt(src.fBottom)); // restore trimme
d bounds | 762 SkScalarRoundToInt(src.fBottom)); // restore trimme
d bounds |
764 dst->fRowBytes = sw; | 763 dst->fRowBytes = sw; |
765 } | 764 } |
766 return true; | 765 return true; |
767 } | 766 } |
768 uint8_t *profile = NULL; | 767 uint8_t *profile = NULL; |
769 | 768 |
(...skipping 20 matching lines...) Expand all Loading... |
790 ComputeBlurredScanline(horizontalScanline, profile, dstWidth, sigma); | 789 ComputeBlurredScanline(horizontalScanline, profile, dstWidth, sigma); |
791 ComputeBlurredScanline(verticalScanline, profile, dstHeight, sigma); | 790 ComputeBlurredScanline(verticalScanline, profile, dstHeight, sigma); |
792 | 791 |
793 for (int y = 0 ; y < dstHeight ; ++y) { | 792 for (int y = 0 ; y < dstHeight ; ++y) { |
794 for (int x = 0 ; x < dstWidth ; x++) { | 793 for (int x = 0 ; x < dstWidth ; x++) { |
795 unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], verti
calScanline[y]); | 794 unsigned int maskval = SkMulDiv255Round(horizontalScanline[x], verti
calScanline[y]); |
796 *(outptr++) = maskval; | 795 *(outptr++) = maskval; |
797 } | 796 } |
798 } | 797 } |
799 | 798 |
800 if (style == kInner_Style) { | 799 if (style == kInner_SkBlurStyle) { |
801 // now we allocate the "real" dst, mirror the size of src | 800 // now we allocate the "real" dst, mirror the size of src |
802 size_t srcSize = (size_t)(src.width() * src.height()); | 801 size_t srcSize = (size_t)(src.width() * src.height()); |
803 if (0 == srcSize) { | 802 if (0 == srcSize) { |
804 return false; // too big to allocate, abort | 803 return false; // too big to allocate, abort |
805 } | 804 } |
806 dst->fImage = SkMask::AllocImage(srcSize); | 805 dst->fImage = SkMask::AllocImage(srcSize); |
807 for (int y = 0 ; y < sh ; y++) { | 806 for (int y = 0 ; y < sh ; y++) { |
808 uint8_t *blur_scanline = dp + (y+pad)*dstWidth + pad; | 807 uint8_t *blur_scanline = dp + (y+pad)*dstWidth + pad; |
809 uint8_t *inner_scanline = dst->fImage + y*sw; | 808 uint8_t *inner_scanline = dst->fImage + y*sw; |
810 memcpy(inner_scanline, blur_scanline, sw); | 809 memcpy(inner_scanline, blur_scanline, sw); |
811 } | 810 } |
812 SkMask::FreeImage(dp); | 811 SkMask::FreeImage(dp); |
813 | 812 |
814 dst->fBounds.set(SkScalarRoundToInt(src.fLeft), | 813 dst->fBounds.set(SkScalarRoundToInt(src.fLeft), |
815 SkScalarRoundToInt(src.fTop), | 814 SkScalarRoundToInt(src.fTop), |
816 SkScalarRoundToInt(src.fRight), | 815 SkScalarRoundToInt(src.fRight), |
817 SkScalarRoundToInt(src.fBottom)); // restore trimmed bo
unds | 816 SkScalarRoundToInt(src.fBottom)); // restore trimmed bo
unds |
818 dst->fRowBytes = sw; | 817 dst->fRowBytes = sw; |
819 | 818 |
820 } else if (style == kOuter_Style) { | 819 } else if (style == kOuter_SkBlurStyle) { |
821 for (int y = pad ; y < dstHeight-pad ; y++) { | 820 for (int y = pad ; y < dstHeight-pad ; y++) { |
822 uint8_t *dst_scanline = dp + y*dstWidth + pad; | 821 uint8_t *dst_scanline = dp + y*dstWidth + pad; |
823 memset(dst_scanline, 0, sw); | 822 memset(dst_scanline, 0, sw); |
824 } | 823 } |
825 } else if (style == kSolid_Style) { | 824 } else if (style == kSolid_SkBlurStyle) { |
826 for (int y = pad ; y < dstHeight-pad ; y++) { | 825 for (int y = pad ; y < dstHeight-pad ; y++) { |
827 uint8_t *dst_scanline = dp + y*dstWidth + pad; | 826 uint8_t *dst_scanline = dp + y*dstWidth + pad; |
828 memset(dst_scanline, 0xff, sw); | 827 memset(dst_scanline, 0xff, sw); |
829 } | 828 } |
830 } | 829 } |
831 // normal and solid styles are the same for analytic rect blurs, so don't | 830 // normal and solid styles are the same for analytic rect blurs, so don't |
832 // need to handle solid specially. | 831 // need to handle solid specially. |
833 | 832 |
834 return true; | 833 return true; |
835 } | 834 } |
836 | 835 |
837 bool SkBlurMask::BlurRRect(SkScalar sigma, SkMask *dst, | 836 bool SkBlurMask::BlurRRect(SkScalar sigma, SkMask *dst, |
838 const SkRRect &src, Style style, | 837 const SkRRect &src, SkBlurStyle style, |
839 SkIPoint *margin, SkMask::CreateMode createMode) { | 838 SkIPoint *margin, SkMask::CreateMode createMode) { |
840 // Temporary for now -- always fail, should cause caller to fall back | 839 // Temporary for now -- always fail, should cause caller to fall back |
841 // to old path. Plumbing just to land API and parallelize effort. | 840 // to old path. Plumbing just to land API and parallelize effort. |
842 | 841 |
843 return false; | 842 return false; |
844 } | 843 } |
845 | 844 |
846 // The "simple" blur is a direct implementation of separable convolution with a
discrete | 845 // The "simple" blur is a direct implementation of separable convolution with a
discrete |
847 // gaussian kernel. It's "ground truth" in a sense; too slow to be used, but ve
ry | 846 // gaussian kernel. It's "ground truth" in a sense; too slow to be used, but ve
ry |
848 // useful for correctness comparisons. | 847 // useful for correctness comparisons. |
849 | 848 |
850 bool SkBlurMask::BlurGroundTruth(SkScalar sigma, SkMask* dst, const SkMask& src, | 849 bool SkBlurMask::BlurGroundTruth(SkScalar sigma, SkMask* dst, const SkMask& src, |
851 Style style, SkIPoint* margin) { | 850 SkBlurStyle style, SkIPoint* margin) { |
852 | 851 |
853 if (src.fFormat != SkMask::kA8_Format) { | 852 if (src.fFormat != SkMask::kA8_Format) { |
854 return false; | 853 return false; |
855 } | 854 } |
856 | 855 |
857 float variance = sigma * sigma; | 856 float variance = sigma * sigma; |
858 | 857 |
859 int windowSize = SkScalarCeilToInt(sigma*6); | 858 int windowSize = SkScalarCeilToInt(sigma*6); |
860 // round window size up to nearest odd number | 859 // round window size up to nearest odd number |
861 windowSize |= 1; | 860 windowSize |= 1; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 finalValue /= windowSum; | 956 finalValue /= windowSum; |
958 uint8_t *outPixel = dstPixels + (x-pad)*dstWidth + y; // transpo
sed output | 957 uint8_t *outPixel = dstPixels + (x-pad)*dstWidth + y; // transpo
sed output |
959 int integerPixel = int(finalValue + 0.5f); | 958 int integerPixel = int(finalValue + 0.5f); |
960 *outPixel = SkClampMax( SkClampPos(integerPixel), 255 ); | 959 *outPixel = SkClampMax( SkClampPos(integerPixel), 255 ); |
961 } | 960 } |
962 } | 961 } |
963 | 962 |
964 dst->fImage = dstPixels; | 963 dst->fImage = dstPixels; |
965 // if need be, alloc the "real" dst (same size as src) and copy/merge | 964 // if need be, alloc the "real" dst (same size as src) and copy/merge |
966 // the blur into it (applying the src) | 965 // the blur into it (applying the src) |
967 if (style == kInner_Style) { | 966 if (style == kInner_SkBlurStyle) { |
968 // now we allocate the "real" dst, mirror the size of src | 967 // now we allocate the "real" dst, mirror the size of src |
969 size_t srcSize = src.computeImageSize(); | 968 size_t srcSize = src.computeImageSize(); |
970 if (0 == srcSize) { | 969 if (0 == srcSize) { |
971 return false; // too big to allocate, abort | 970 return false; // too big to allocate, abort |
972 } | 971 } |
973 dst->fImage = SkMask::AllocImage(srcSize); | 972 dst->fImage = SkMask::AllocImage(srcSize); |
974 merge_src_with_blur(dst->fImage, src.fRowBytes, | 973 merge_src_with_blur(dst->fImage, src.fRowBytes, |
975 srcPixels, src.fRowBytes, | 974 srcPixels, src.fRowBytes, |
976 dstPixels + pad*dst->fRowBytes + pad, | 975 dstPixels + pad*dst->fRowBytes + pad, |
977 dst->fRowBytes, srcWidth, srcHeight); | 976 dst->fRowBytes, srcWidth, srcHeight); |
978 SkMask::FreeImage(dstPixels); | 977 SkMask::FreeImage(dstPixels); |
979 } else if (style != kNormal_Style) { | 978 } else if (style != kNormal_SkBlurStyle) { |
980 clamp_with_orig(dstPixels + pad*dst->fRowBytes + pad, | 979 clamp_with_orig(dstPixels + pad*dst->fRowBytes + pad, |
981 dst->fRowBytes, srcPixels, src.fRowBytes, srcWidth, srcHeight, s
tyle); | 980 dst->fRowBytes, srcPixels, src.fRowBytes, srcWidth, srcHeight, s
tyle); |
982 } | 981 } |
983 (void)autoCall.detach(); | 982 (void)autoCall.detach(); |
984 } | 983 } |
985 | 984 |
986 if (style == kInner_Style) { | 985 if (style == kInner_SkBlurStyle) { |
987 dst->fBounds = src.fBounds; // restore trimmed bounds | 986 dst->fBounds = src.fBounds; // restore trimmed bounds |
988 dst->fRowBytes = src.fRowBytes; | 987 dst->fRowBytes = src.fRowBytes; |
989 } | 988 } |
990 | 989 |
991 return true; | 990 return true; |
992 } | 991 } |
OLD | NEW |