Chromium Code Reviews| 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 "SkCodecPriv.h" | 8 #include "SkCodecPriv.h" |
| 9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
| 10 #include "SkSwizzler.h" | 10 #include "SkSwizzler.h" |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 455 INIT_RESULT_ALPHA; | 455 INIT_RESULT_ALPHA; |
| 456 for (int x = 0; x < dstWidth; x++) { | 456 for (int x = 0; x < dstWidth; x++) { |
| 457 unsigned alpha = src[3]; | 457 unsigned alpha = src[3]; |
| 458 UPDATE_RESULT_ALPHA(alpha); | 458 UPDATE_RESULT_ALPHA(alpha); |
| 459 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); | 459 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); |
| 460 src += deltaSrc; | 460 src += deltaSrc; |
| 461 } | 461 } |
| 462 return COMPUTE_RESULT_ALPHA; | 462 return COMPUTE_RESULT_ALPHA; |
| 463 } | 463 } |
| 464 | 464 |
| 465 static SkSwizzler::ResultAlpha swizzle_rgba_to_n32_premul_skipZ( | 465 template <SkSwizzler::RowProc proc> |
| 466 SkSwizzler::ResultAlpha SkSwizzler::SkipLeading8888ZerosThen( | |
| 466 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | 467 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
| 467 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | 468 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { |
| 469 SkASSERT(!ctable); | |
| 468 | 470 |
| 469 src += offset; | 471 auto src32 = (const uint32_t*)(src+offset); |
| 470 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 472 auto dst32 = (uint32_t*)dstRow; |
| 471 INIT_RESULT_ALPHA; | 473 |
| 472 for (int x = 0; x < dstWidth; x++) { | 474 while (dstWidth > 0 && *src32 == 0) { |
|
scroggo
2016/01/08 21:33:20
FWIW, when we are premultiplying, we really only n
| |
| 473 unsigned alpha = src[3]; | 475 dstWidth--; |
| 474 UPDATE_RESULT_ALPHA(alpha); | 476 dst32 += 1; |
| 475 if (0 != alpha) { | 477 src32 += deltaSrc/4; |
| 476 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | |
| 477 } | |
| 478 src += deltaSrc; | |
| 479 } | 478 } |
| 480 return COMPUTE_RESULT_ALPHA; | 479 return proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable ); |
| 481 } | 480 } |
| 482 | 481 |
| 483 // kCMYK | 482 // kCMYK |
| 484 // | 483 // |
| 485 // CMYK is stored as four bytes per pixel. | 484 // CMYK is stored as four bytes per pixel. |
| 486 // | 485 // |
| 487 // We will implement a crude conversion from CMYK -> RGB using formulas | 486 // We will implement a crude conversion from CMYK -> RGB using formulas |
| 488 // from easyrgb.com. | 487 // from easyrgb.com. |
| 489 // | 488 // |
| 490 // CMYK -> CMY | 489 // CMYK -> CMY |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 const uint8_t b = SkMulDiv255Round(src[2], src[3]); | 555 const uint8_t b = SkMulDiv255Round(src[2], src[3]); |
| 557 | 556 |
| 558 dst[x] = SkPack888ToRGB16(r, g, b); | 557 dst[x] = SkPack888ToRGB16(r, g, b); |
| 559 src += deltaSrc; | 558 src += deltaSrc; |
| 560 } | 559 } |
| 561 | 560 |
| 562 // CMYK is always opaque | 561 // CMYK is always opaque |
| 563 return SkSwizzler::kOpaque_ResultAlpha; | 562 return SkSwizzler::kOpaque_ResultAlpha; |
| 564 } | 563 } |
| 565 | 564 |
| 566 /** | |
| 567 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes. | |
| 568 This would be fine for drawing normally, but not for drawing with transfer m odes. Being | |
| 569 honest means we can draw correctly with transfer modes, with the cost of not being able | |
| 570 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we | |
| 571 decide whether to switch to unpremul default. | |
| 572 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow, | |
| 573 const uint8_t* SK_RESTRICT src, | |
| 574 int dstWidth, int bitsPerPixel, i nt offset, | |
| 575 const SkPMColor[]) { | |
| 576 src += offset; | |
| 577 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | |
| 578 unsigned alphaMask = 0xFF; | |
| 579 for (int x = 0; x < dstWidth; x++) { | |
| 580 unsigned alpha = src[3]; | |
| 581 // NOTE: We cheat here. The caller requested unpremul and skip zeroes. I t's possible | |
| 582 // the color components are not zero, but we skip them anyway, meaning t hey'll remain | |
| 583 // zero (implied by the request to skip zeroes). | |
| 584 if (0 != alpha) { | |
| 585 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); | |
| 586 } | |
| 587 src += deltaSrc; | |
| 588 alphaMask &= alpha; | |
| 589 } | |
| 590 return alphaMask != 0xFF; | |
| 591 } | |
| 592 */ | |
| 593 | |
| 594 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, | 565 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
| 595 const SkPMColor* ctable, | 566 const SkPMColor* ctable, |
| 596 const SkImageInfo& dstInfo, | 567 const SkImageInfo& dstInfo, |
| 597 const SkCodec::Options& options, | 568 const SkCodec::Options& options, |
| 598 const SkIRect* frame) { | 569 const SkIRect* frame) { |
| 599 if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) { | 570 if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) { |
| 600 return nullptr; | 571 return nullptr; |
| 601 } | 572 } |
| 602 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc) | 573 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc) |
| 603 && nullptr == ctable) { | 574 && nullptr == ctable) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 718 case kRGB_565_SkColorType: | 689 case kRGB_565_SkColorType: |
| 719 proc = &swizzle_rgbx_to_565; | 690 proc = &swizzle_rgbx_to_565; |
| 720 default: | 691 default: |
| 721 break; | 692 break; |
| 722 } | 693 } |
| 723 break; | 694 break; |
| 724 case kRGBA: | 695 case kRGBA: |
| 725 switch (dstInfo.colorType()) { | 696 switch (dstInfo.colorType()) { |
| 726 case kN32_SkColorType: | 697 case kN32_SkColorType: |
| 727 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { | 698 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { |
| 728 // Respect zeroInit? | 699 if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
| 729 proc = &swizzle_rgba_to_n32_unpremul; | 700 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32 _unpremul>; |
| 701 } else { | |
| 702 proc = &swizzle_rgba_to_n32_unpremul; | |
| 703 } | |
| 730 } else { | 704 } else { |
| 731 if (SkCodec::kYes_ZeroInitialized == zeroInit) { | 705 if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
| 732 proc = &swizzle_rgba_to_n32_premul_skipZ; | 706 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32 _premul>; |
| 733 } else { | 707 } else { |
| 734 proc = &swizzle_rgba_to_n32_premul; | 708 proc = &swizzle_rgba_to_n32_premul; |
| 735 } | 709 } |
| 736 } | 710 } |
| 737 break; | 711 break; |
| 738 default: | 712 default: |
| 739 break; | 713 break; |
| 740 } | 714 } |
| 741 break; | 715 break; |
| 742 case kRGB: | 716 case kRGB: |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 772 default: | 746 default: |
| 773 break; | 747 break; |
| 774 } | 748 } |
| 775 if (nullptr == proc) { | 749 if (nullptr == proc) { |
| 776 return nullptr; | 750 return nullptr; |
| 777 } | 751 } |
| 778 | 752 |
| 779 // Store bpp in bytes if it is an even multiple, otherwise use bits | 753 // Store bpp in bytes if it is an even multiple, otherwise use bits |
| 780 int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel (sc); | 754 int srcBPP = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel (sc); |
| 781 int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType()); | 755 int dstBPP = SkColorTypeBytesPerPixel(dstInfo.colorType()); |
| 782 | 756 |
| 783 int srcOffset = 0; | 757 int srcOffset = 0; |
| 784 int srcWidth = dstInfo.width(); | 758 int srcWidth = dstInfo.width(); |
| 785 int dstOffset = 0; | 759 int dstOffset = 0; |
| 786 int dstWidth = srcWidth; | 760 int dstWidth = srcWidth; |
| 787 if (options.fSubset) { | 761 if (options.fSubset) { |
| 788 // We do not currently support subset decodes for image types that may h ave | 762 // We do not currently support subset decodes for image types that may h ave |
| 789 // frames (gif). | 763 // frames (gif). |
| 790 SkASSERT(!frame); | 764 SkASSERT(!frame); |
| 791 srcOffset = options.fSubset->left(); | 765 srcOffset = options.fSubset->left(); |
| 792 srcWidth = options.fSubset->width(); | 766 srcWidth = options.fSubset->width(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 826 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX); | 800 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX); |
| 827 | 801 |
| 828 return fAllocatedWidth; | 802 return fAllocatedWidth; |
| 829 } | 803 } |
| 830 | 804 |
| 831 SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRIC T src) { | 805 SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRIC T src) { |
| 832 SkASSERT(nullptr != dst && nullptr != src); | 806 SkASSERT(nullptr != dst && nullptr != src); |
| 833 return fRowProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth , fSrcBPP, | 807 return fRowProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth , fSrcBPP, |
| 834 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable); | 808 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable); |
| 835 } | 809 } |
| OLD | NEW |