| 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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 | 388 |
| 389 src += offset; | 389 src += offset; |
| 390 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); | 390 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); |
| 391 for (int x = 0; x < dstWidth; x++) { | 391 for (int x = 0; x < dstWidth; x++) { |
| 392 unsigned alpha = src[3]; | 392 unsigned alpha = src[3]; |
| 393 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); | 393 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); |
| 394 src += deltaSrc; | 394 src += deltaSrc; |
| 395 } | 395 } |
| 396 } | 396 } |
| 397 | 397 |
| 398 static void swizzle_rgba_to_n32_premul_skipZ( | |
| 399 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, | |
| 400 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { | |
| 401 | |
| 402 src += offset; | |
| 403 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | |
| 404 for (int x = 0; x < dstWidth; x++) { | |
| 405 unsigned alpha = src[3]; | |
| 406 if (0 != alpha) { | |
| 407 dst[x] = SkPremultiplyARGBInline(alpha, src[0], src[1], src[2]); | |
| 408 } | |
| 409 src += deltaSrc; | |
| 410 } | |
| 411 } | |
| 412 | |
| 413 // kCMYK | 398 // kCMYK |
| 414 // | 399 // |
| 415 // CMYK is stored as four bytes per pixel. | 400 // CMYK is stored as four bytes per pixel. |
| 416 // | 401 // |
| 417 // We will implement a crude conversion from CMYK -> RGB using formulas | 402 // We will implement a crude conversion from CMYK -> RGB using formulas |
| 418 // from easyrgb.com. | 403 // from easyrgb.com. |
| 419 // | 404 // |
| 420 // CMYK -> CMY | 405 // CMYK -> CMY |
| 421 // C = C * (1 - K) + K | 406 // C = C * (1 - K) + K |
| 422 // M = M * (1 - K) + K | 407 // M = M * (1 - K) + K |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 for (int x = 0; x < dstWidth; x++) { | 465 for (int x = 0; x < dstWidth; x++) { |
| 481 const uint8_t r = SkMulDiv255Round(src[0], src[3]); | 466 const uint8_t r = SkMulDiv255Round(src[0], src[3]); |
| 482 const uint8_t g = SkMulDiv255Round(src[1], src[3]); | 467 const uint8_t g = SkMulDiv255Round(src[1], src[3]); |
| 483 const uint8_t b = SkMulDiv255Round(src[2], src[3]); | 468 const uint8_t b = SkMulDiv255Round(src[2], src[3]); |
| 484 | 469 |
| 485 dst[x] = SkPack888ToRGB16(r, g, b); | 470 dst[x] = SkPack888ToRGB16(r, g, b); |
| 486 src += deltaSrc; | 471 src += deltaSrc; |
| 487 } | 472 } |
| 488 } | 473 } |
| 489 | 474 |
| 490 /** | 475 template <SkSwizzler::RowProc proc> |
| 491 FIXME: This was my idea to cheat in order to continue taking advantage of sk
ipping zeroes. | 476 void SkSwizzler::SkipLeading8888ZerosThen( |
| 492 This would be fine for drawing normally, but not for drawing with transfer m
odes. Being | 477 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth, |
| 493 honest means we can draw correctly with transfer modes, with the cost of not
being able | 478 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) { |
| 494 to take advantage of Android's free unwritten pages. Something to keep in mi
nd when we | 479 SkASSERT(!ctable); |
| 495 decide whether to switch to unpremul default. | 480 |
| 496 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow, | 481 auto src32 = (const uint32_t*)(src+offset); |
| 497 const uint8_t* SK_RESTRICT src, | 482 auto dst32 = (uint32_t*)dstRow; |
| 498 int dstWidth, int bitsPerPixel, i
nt offset, | 483 |
| 499 const SkPMColor[]) { | 484 // This may miss opportunities to skip when the output is premultiplied, |
| 500 src += offset; | 485 // e.g. for a src pixel 0x00FFFFFF which is not zero but becomes zero after
premultiplication. |
| 501 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 486 while (dstWidth > 0 && *src32 == 0x00000000) { |
| 502 unsigned alphaMask = 0xFF; | 487 dstWidth--; |
| 503 for (int x = 0; x < dstWidth; x++) { | 488 dst32++; |
| 504 unsigned alpha = src[3]; | 489 src32 += deltaSrc/4; |
| 505 // NOTE: We cheat here. The caller requested unpremul and skip zeroes. I
t's possible | |
| 506 // the color components are not zero, but we skip them anyway, meaning t
hey'll remain | |
| 507 // zero (implied by the request to skip zeroes). | |
| 508 if (0 != alpha) { | |
| 509 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); | |
| 510 } | |
| 511 src += deltaSrc; | |
| 512 alphaMask &= alpha; | |
| 513 } | 490 } |
| 514 return alphaMask != 0xFF; | 491 proc(dst32, (const uint8_t*)src32, dstWidth, bpp, deltaSrc, 0, ctable); |
| 515 } | 492 } |
| 516 */ | |
| 517 | 493 |
| 518 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, | 494 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc, |
| 519 const SkPMColor* ctable, | 495 const SkPMColor* ctable, |
| 520 const SkImageInfo& dstInfo, | 496 const SkImageInfo& dstInfo, |
| 521 const SkCodec::Options& options, | 497 const SkCodec::Options& options, |
| 522 const SkIRect* frame) { | 498 const SkIRect* frame) { |
| 523 if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) { | 499 if (dstInfo.colorType() == kUnknown_SkColorType || kUnknown == sc) { |
| 524 return nullptr; | 500 return nullptr; |
| 525 } | 501 } |
| 526 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc) | 502 if ((kIndex == sc || kIndex4 == sc || kIndex2 == sc || kIndex1 == sc) |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 case kRGB_565_SkColorType: | 618 case kRGB_565_SkColorType: |
| 643 proc = &swizzle_rgbx_to_565; | 619 proc = &swizzle_rgbx_to_565; |
| 644 default: | 620 default: |
| 645 break; | 621 break; |
| 646 } | 622 } |
| 647 break; | 623 break; |
| 648 case kRGBA: | 624 case kRGBA: |
| 649 switch (dstInfo.colorType()) { | 625 switch (dstInfo.colorType()) { |
| 650 case kN32_SkColorType: | 626 case kN32_SkColorType: |
| 651 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { | 627 if (dstInfo.alphaType() == kUnpremul_SkAlphaType) { |
| 652 // Respect zeroInit? | 628 if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
| 653 proc = &swizzle_rgba_to_n32_unpremul; | 629 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32
_unpremul>; |
| 630 } else { |
| 631 proc = &swizzle_rgba_to_n32_unpremul; |
| 632 } |
| 654 } else { | 633 } else { |
| 655 if (SkCodec::kYes_ZeroInitialized == zeroInit) { | 634 if (SkCodec::kYes_ZeroInitialized == zeroInit) { |
| 656 proc = &swizzle_rgba_to_n32_premul_skipZ; | 635 proc = &SkipLeading8888ZerosThen<swizzle_rgba_to_n32
_premul>; |
| 657 } else { | 636 } else { |
| 658 proc = &swizzle_rgba_to_n32_premul; | 637 proc = &swizzle_rgba_to_n32_premul; |
| 659 } | 638 } |
| 660 } | 639 } |
| 661 break; | 640 break; |
| 662 default: | 641 default: |
| 663 break; | 642 break; |
| 664 } | 643 } |
| 665 break; | 644 break; |
| 666 case kRGB: | 645 case kRGB: |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX); | 729 fAllocatedWidth = get_scaled_dimension(fDstWidth, sampleX); |
| 751 | 730 |
| 752 return fAllocatedWidth; | 731 return fAllocatedWidth; |
| 753 } | 732 } |
| 754 | 733 |
| 755 void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { | 734 void SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRICT src) { |
| 756 SkASSERT(nullptr != dst && nullptr != src); | 735 SkASSERT(nullptr != dst && nullptr != src); |
| 757 fRowProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcB
PP, | 736 fRowProc(SkTAddOffset<void>(dst, fDstOffsetBytes), src, fSwizzleWidth, fSrcB
PP, |
| 758 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable); | 737 fSampleX * fSrcBPP, fSrcOffsetUnits, fColorTable); |
| 759 } | 738 } |
| OLD | NEW |