Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(621)

Side by Side Diff: src/codec/SkSwizzler.cpp

Issue 1411083009: Use SkSwizzler to convert from CMYK (Closed) Base URL: https://skia.googlesource.com/skia.git@NewFromData
Patch Set: Add missing break statement Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/codec/SkSwizzler.h ('k') | tests/CodexTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 unsigned alpha = src[3]; 473 unsigned alpha = src[3];
474 UPDATE_RESULT_ALPHA(alpha); 474 UPDATE_RESULT_ALPHA(alpha);
475 if (0 != alpha) { 475 if (0 != alpha) {
476 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); 476 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]);
477 } 477 }
478 src += deltaSrc; 478 src += deltaSrc;
479 } 479 }
480 return COMPUTE_RESULT_ALPHA; 480 return COMPUTE_RESULT_ALPHA;
481 } 481 }
482 482
483 // kCMYK
484 //
485 // CMYK is stored as four bytes per pixel.
486 //
487 // We will implement a crude conversion from CMYK -> RGB using formulas
488 // from easyrgb.com.
489 //
490 // CMYK -> CMY
491 // C = C * (1 - K) + K
492 // M = M * (1 - K) + K
493 // Y = Y * (1 - K) + K
494 //
495 // libjpeg actually gives us inverted CMYK, so we must subtract the
496 // original terms from 1.
497 // CMYK -> CMY
498 // C = (1 - C) * (1 - (1 - K)) + (1 - K)
499 // M = (1 - M) * (1 - (1 - K)) + (1 - K)
500 // Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
501 //
502 // Simplifying the above expression.
503 // CMYK -> CMY
504 // C = 1 - CK
505 // M = 1 - MK
506 // Y = 1 - YK
507 //
508 // CMY -> RGB
509 // R = (1 - C) * 255
510 // G = (1 - M) * 255
511 // B = (1 - Y) * 255
512 //
513 // Therefore the full conversion is below. This can be verified at
514 // www.rapidtables.com (assuming inverted CMYK).
515 // CMYK -> RGB
516 // R = C * K * 255
517 // G = M * K * 255
518 // B = Y * K * 255
519 //
520 // As a final note, we have treated the CMYK values as if they were on
521 // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
522 // We must divide each CMYK component by 255 to obtain the true conversion
523 // we should perform.
524 // CMYK -> RGB
525 // R = C * K / 255
526 // G = M * K / 255
527 // B = Y * K / 255
528 static SkSwizzler::ResultAlpha swizzle_cmyk_to_n32(
529 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
530 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
531
532 src += offset;
533 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow;
534 for (int x = 0; x < dstWidth; x++) {
535 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
536 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
537 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
538
539 dst[x] = SkPackARGB32NoCheck(0xFF, r, g, b);
540 src += deltaSrc;
541 }
542
543 // CMYK is always opaque
544 return SkSwizzler::kOpaque_ResultAlpha;
545 }
546
547 static SkSwizzler::ResultAlpha swizzle_cmyk_to_565(
548 void* SK_RESTRICT dstRow, const uint8_t* SK_RESTRICT src, int dstWidth,
549 int bpp, int deltaSrc, int offset, const SkPMColor ctable[]) {
550
551 src += offset;
552 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow;
553 for (int x = 0; x < dstWidth; x++) {
554 const uint8_t r = SkMulDiv255Round(src[0], src[3]);
555 const uint8_t g = SkMulDiv255Round(src[1], src[3]);
556 const uint8_t b = SkMulDiv255Round(src[2], src[3]);
557
558 dst[x] = SkPack888ToRGB16(r, g, b);
559 src += deltaSrc;
560 }
561
562 // CMYK is always opaque
563 return SkSwizzler::kOpaque_ResultAlpha;
564 }
565
483 /** 566 /**
484 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes. 567 FIXME: This was my idea to cheat in order to continue taking advantage of sk ipping zeroes.
485 This would be fine for drawing normally, but not for drawing with transfer m odes. Being 568 This would be fine for drawing normally, but not for drawing with transfer m odes. Being
486 honest means we can draw correctly with transfer modes, with the cost of not being able 569 honest means we can draw correctly with transfer modes, with the cost of not being able
487 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we 570 to take advantage of Android's free unwritten pages. Something to keep in mi nd when we
488 decide whether to switch to unpremul default. 571 decide whether to switch to unpremul default.
489 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow, 572 static bool swizzle_rgba_to_n32_unpremul_skipZ(void* SK_RESTRICT dstRow,
490 const uint8_t* SK_RESTRICT src, 573 const uint8_t* SK_RESTRICT src,
491 int dstWidth, int bitsPerPixel, i nt offset, 574 int dstWidth, int bitsPerPixel, i nt offset,
492 const SkPMColor[]) { 575 const SkPMColor[]) {
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 } 748 }
666 break; 749 break;
667 case kRGB_565: 750 case kRGB_565:
668 switch (dstInfo.colorType()) { 751 switch (dstInfo.colorType()) {
669 case kRGB_565_SkColorType: 752 case kRGB_565_SkColorType:
670 proc = &sample565; 753 proc = &sample565;
671 break; 754 break;
672 default: 755 default:
673 break; 756 break;
674 } 757 }
758 break;
759 case kCMYK:
760 switch (dstInfo.colorType()) {
761 case kN32_SkColorType:
762 proc = &swizzle_cmyk_to_n32;
763 break;
764 case kRGB_565_SkColorType:
765 proc = &swizzle_cmyk_to_565;
766 break;
767 default:
768 break;
769 }
770 break;
675 default: 771 default:
676 break; 772 break;
677 } 773 }
678 if (nullptr == proc) { 774 if (nullptr == proc) {
679 return nullptr; 775 return nullptr;
680 } 776 }
681 777
682 // Store bpp in bytes if it is an even multiple, otherwise use bits 778 // Store bpp in bytes if it is an even multiple, otherwise use bits
683 int bpp = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc ); 779 int bpp = SkIsAlign8(BitsPerPixel(sc)) ? BytesPerPixel(sc) : BitsPerPixel(sc );
684 780
(...skipping 28 matching lines...) Expand all
713 809
714 // check that fX0 is valid 810 // check that fX0 is valid
715 SkASSERT(fX0 >= 0); 811 SkASSERT(fX0 >= 0);
716 return fDstWidth; 812 return fDstWidth;
717 } 813 }
718 814
719 SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRIC T src) { 815 SkSwizzler::ResultAlpha SkSwizzler::swizzle(void* dst, const uint8_t* SK_RESTRIC T src) {
720 SkASSERT(nullptr != dst && nullptr != src); 816 SkASSERT(nullptr != dst && nullptr != src);
721 return fRowProc(dst, src, fDstWidth, fBPP, fSampleX * fBPP, fX0 * fBPP, fCol orTable); 817 return fRowProc(dst, src, fDstWidth, fBPP, fSampleX * fBPP, fX0 * fBPP, fCol orTable);
722 } 818 }
OLDNEW
« no previous file with comments | « src/codec/SkSwizzler.h ('k') | tests/CodexTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698