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

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

Issue 1055743003: Swizzler changes Index8 and 565 (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Safe fill for unlikely values of row bytes and other minor fixes Created 5 years, 8 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
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 "SkCodec_libbmp.h" 8 #include "SkCodec_libbmp.h"
9 #include "SkCodecPriv.h" 9 #include "SkCodecPriv.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
11 #include "SkStream.h" 11 #include "SkStream.h"
12 #include "SkUtils.h"
12 13
13 /* 14 /*
14 * 15 *
15 * Checks if the conversion between the input image and the requested output 16 * Checks if the conversion between the input image and the requested output
16 * image has been implemented 17 * image has been implemented
17 * 18 *
18 */ 19 */
19 static bool conversion_possible(const SkImageInfo& dst, 20 static bool conversion_possible(const SkImageInfo& dst,
20 const SkImageInfo& src) { 21 const SkImageInfo& src) {
21 // Ensure that the profile type is unchanged 22 // Ensure that the profile type is unchanged
22 if (dst.profileType() != src.profileType()) { 23 if (dst.profileType() != src.profileType()) {
23 return false; 24 return false;
24 } 25 }
25 26
26 // Check for supported color and alpha types 27 // Check for supported alpha types
28 if (src.alphaType() != dst.alphaType()) {
29 if (kOpaque_SkAlphaType == src.alphaType()) {
30 // If the source is opaque, we must decoder to opaque
scroggo 2015/04/06 21:26:30 decode*
msarett 2015/04/07 12:36:03 Done.
31 return false;
32 }
33
34 // The source is not opaque
35 switch (dst.alphaType()) {
36 case kPremul_SkAlphaType:
37 case kUnpremul_SkAlphaType:
38 // The source is not opaque, so either of these is okay
39 break;
40 default:
41 // We cannot decode a non-opaque image to opaque (or unknown)
42 return false;
43 }
44 }
45
46 // Check for supported color types
27 switch (dst.colorType()) { 47 switch (dst.colorType()) {
48 // Allow output to kN32 from any type of input
28 case kN32_SkColorType: 49 case kN32_SkColorType:
29 return src.alphaType() == dst.alphaType() || 50 return true;
30 (kPremul_SkAlphaType == dst.alphaType() && 51 // Allow output to kIndex_8 from compatible inputs
31 kUnpremul_SkAlphaType == src.alphaType()); 52 case kIndex_8_SkColorType:
53 return kIndex_8_SkColorType == src.colorType();
32 default: 54 default:
33 return false; 55 return false;
34 } 56 }
35 } 57 }
36 58
37 /* 59 /*
38 * 60 *
39 * Defines the version and type of the second bitmap header 61 * Defines the version and type of the second bitmap header
40 * 62 *
41 */ 63 */
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 // Header types are matched based on size. If the header is 435 // Header types are matched based on size. If the header is
414 // V3+, we are guaranteed to be able to read at least this size. 436 // V3+, we are guaranteed to be able to read at least this size.
415 SkASSERT(infoBytesRemaining > 52); 437 SkASSERT(infoBytesRemaining > 52);
416 inputMasks.alpha = get_int(iBuffer.get(), 48); 438 inputMasks.alpha = get_int(iBuffer.get(), 48);
417 if (inputMasks.alpha != 0) { 439 if (inputMasks.alpha != 0) {
418 alphaType = kUnpremul_SkAlphaType; 440 alphaType = kUnpremul_SkAlphaType;
419 } 441 }
420 } 442 }
421 iBuffer.free(); 443 iBuffer.free();
422 444
423 // Additionally, 32 bit bmp-in-icos use the alpha channel 445 // Additionally, 32 bit bmp-in-icos use the alpha channel.
424 if (isIco && 32 == bitsPerPixel) { 446 // And, RLE inputs may skip pixels, leaving them as transparent. This
447 // is uncommon, but we cannot be certain that an RLE bmp will be opaque.
448 if ((isIco && 32 == bitsPerPixel) || (kRLE_BitmapInputFormat == inputFormat) ) {
425 alphaType = kUnpremul_SkAlphaType; 449 alphaType = kUnpremul_SkAlphaType;
426 } 450 }
427 451
428 // Check for valid bits per pixel input 452 // Check for valid bits per pixel.
453 // At the same time, use this information to choose a suggested color type
454 // and to set default masks.
455 SkColorType colorType = kN32_SkColorType;
429 switch (bitsPerPixel) { 456 switch (bitsPerPixel) {
430 // In addition to more standard pixel compression formats, bmp supports 457 // In addition to more standard pixel compression formats, bmp supports
431 // the use of bit masks to determine pixel components. The standard 458 // the use of bit masks to determine pixel components. The standard
432 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB), 459 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
433 // which does not map well to any Skia color formats. For this reason, 460 // which does not map well to any Skia color formats. For this reason,
434 // we will always enable mask mode with 16 bits per pixel. 461 // we will always enable mask mode with 16 bits per pixel.
435 case 16: 462 case 16:
436 if (kBitMask_BitmapInputFormat != inputFormat) { 463 if (kBitMask_BitmapInputFormat != inputFormat) {
437 inputMasks.red = 0x7C00; 464 inputMasks.red = 0x7C00;
438 inputMasks.green = 0x03E0; 465 inputMasks.green = 0x03E0;
439 inputMasks.blue = 0x001F; 466 inputMasks.blue = 0x001F;
440 inputFormat = kBitMask_BitmapInputFormat; 467 inputFormat = kBitMask_BitmapInputFormat;
441 } 468 }
442 break; 469 break;
470 // We want to decode to kIndex_8 for input formats that are already
471 // designed in index format.
443 case 1: 472 case 1:
444 case 2: 473 case 2:
445 case 4: 474 case 4:
446 case 8: 475 case 8:
476 // However, we cannot in RLE format since we may need to leave some
477 // pixels as transparent. Similarly, we also cannot for ICO images
478 // since we may need to apply a transparent mask.
479 if (kRLE_BitmapInputFormat != inputFormat && !isIco) {
480 colorType = kIndex_8_SkColorType;
481 }
447 case 24: 482 case 24:
448 case 32: 483 case 32:
449 break; 484 break;
450 default: 485 default:
451 SkCodecPrintf("Error: invalid input value for bits per pixel.\n"); 486 SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
452 return false; 487 return false;
453 } 488 }
454 489
455 // Check that input bit masks are valid and create the masks object 490 // Check that input bit masks are valid and create the masks object
456 SkAutoTDelete<SkMasks> 491 SkAutoTDelete<SkMasks>
(...skipping 12 matching lines...) Expand all
469 504
470 // Calculate the number of bytes read so far 505 // Calculate the number of bytes read so far
471 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes; 506 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
472 if (!isIco && offset < bytesRead) { 507 if (!isIco && offset < bytesRead) {
473 SkCodecPrintf("Error: pixel data offset less than header size.\n"); 508 SkCodecPrintf("Error: pixel data offset less than header size.\n");
474 return false; 509 return false;
475 } 510 }
476 511
477 if (codecOut) { 512 if (codecOut) {
478 // Return the codec 513 // Return the codec
479 // We will use ImageInfo to store width, height, and alpha type. We 514 // We will use ImageInfo to store width, height, suggested color type, a nd
480 // will set color type to kN32_SkColorType because that should be the 515 // suggested alpha type.
481 // default output.
482 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height, 516 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
483 kN32_SkColorType, alphaType); 517 colorType, alphaType);
484 *codecOut = SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel, 518 *codecOut = SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel,
485 inputFormat, masks.detach(), 519 inputFormat, masks.detach(),
486 numColors, bytesPerColor, 520 numColors, bytesPerColor,
487 offset - bytesRead, rowOrder, 521 offset - bytesRead, rowOrder,
488 RLEBytes, isIco)); 522 RLEBytes, isIco));
489 } 523 }
490 return true; 524 return true;
491 } 525 }
492 526
493 /* 527 /*
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 568
535 {} 569 {}
536 570
537 /* 571 /*
538 * 572 *
539 * Initiates the bitmap decode 573 * Initiates the bitmap decode
540 * 574 *
541 */ 575 */
542 SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo, 576 SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo,
543 void* dst, size_t dstRowBytes, 577 void* dst, size_t dstRowBytes,
544 const Options&, 578 const Options& opts,
545 SkPMColor*, int*) { 579 SkPMColor* inputColorPtr,
580 int* inputColorCount) {
546 // Check for proper input and output formats 581 // Check for proper input and output formats
547 SkCodec::RewindState rewindState = this->rewindIfNeeded(); 582 SkCodec::RewindState rewindState = this->rewindIfNeeded();
548 if (rewindState == kCouldNotRewind_RewindState) { 583 if (rewindState == kCouldNotRewind_RewindState) {
549 return kCouldNotRewind; 584 return kCouldNotRewind;
550 } else if (rewindState == kRewound_RewindState) { 585 } else if (rewindState == kRewound_RewindState) {
551 if (!ReadHeader(this->stream(), fIsIco, NULL)) { 586 if (!ReadHeader(this->stream(), fIsIco, NULL)) {
552 return kCouldNotRewind; 587 return kCouldNotRewind;
553 } 588 }
554 } 589 }
555 if (dstInfo.dimensions() != this->getInfo().dimensions()) { 590 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
556 SkCodecPrintf("Error: scaling not supported.\n"); 591 SkCodecPrintf("Error: scaling not supported.\n");
557 return kInvalidScale; 592 return kInvalidScale;
558 } 593 }
559 if (!conversion_possible(dstInfo, this->getInfo())) { 594 if (!conversion_possible(dstInfo, this->getInfo())) {
560 SkCodecPrintf("Error: cannot convert input type to output type.\n"); 595 SkCodecPrintf("Error: cannot convert input type to output type.\n");
561 return kInvalidConversion; 596 return kInvalidConversion;
562 } 597 }
563 598
564 // Create the color table if necessary and prepare the stream for decode 599 // Create the color table if necessary and prepare the stream for decode
565 if (!createColorTable(dstInfo.alphaType())) { 600 // Note that if it is non-NULL, inputColorCount will be modified
601 if (!createColorTable(dstInfo.alphaType(), inputColorCount)) {
566 SkCodecPrintf("Error: could not create color table.\n"); 602 SkCodecPrintf("Error: could not create color table.\n");
567 return kInvalidInput; 603 return kInvalidInput;
568 } 604 }
569 605
606 // Copy the color table to the client if necessary
607 if (kIndex_8_SkColorType == dstInfo.colorType()) {
608 SkASSERT(NULL != inputColorPtr);
609 SkASSERT(NULL != inputColorCount);
610 SkASSERT(NULL != fColorTable.get());
611 sk_memcpy32(inputColorPtr, fColorTable->readColors(), *inputColorCount);
612 }
613
570 // Perform the decode 614 // Perform the decode
571 switch (fInputFormat) { 615 switch (fInputFormat) {
572 case kBitMask_BitmapInputFormat: 616 case kBitMask_BitmapInputFormat:
573 return decodeMask(dstInfo, dst, dstRowBytes); 617 return decodeMask(dstInfo, dst, dstRowBytes);
574 case kRLE_BitmapInputFormat: 618 case kRLE_BitmapInputFormat:
575 return decodeRLE(dstInfo, dst, dstRowBytes); 619 return decodeRLE(dstInfo, dst, dstRowBytes, opts);
576 case kStandard_BitmapInputFormat: 620 case kStandard_BitmapInputFormat:
577 return decode(dstInfo, dst, dstRowBytes); 621 return decode(dstInfo, dst, dstRowBytes);
578 default: 622 default:
579 SkASSERT(false); 623 SkASSERT(false);
580 return kInvalidInput; 624 return kInvalidInput;
581 } 625 }
582 } 626 }
583 627
584 /* 628 /*
585 * 629 *
586 * Process the color table for the bmp input 630 * Process the color table for the bmp input
587 * 631 *
588 */ 632 */
589 bool SkBmpCodec::createColorTable(SkAlphaType alphaType) { 633 bool SkBmpCodec::createColorTable(SkAlphaType alphaType, int* numColors) {
590 // Allocate memory for color table 634 // Allocate memory for color table
591 uint32_t colorBytes = 0; 635 uint32_t colorBytes = 0;
592 uint32_t maxColors = 0; 636 uint32_t maxColors = 0;
593 SkPMColor colorTable[256]; 637 SkPMColor colorTable[256];
594 if (fBitsPerPixel <= 8) { 638 if (fBitsPerPixel <= 8) {
595 // Zero is a default for maxColors 639 // Zero is a default for maxColors
596 // Also set fNumColors to maxColors when it is too large 640 // Also set fNumColors to maxColors when it is too large
597 maxColors = 1 << fBitsPerPixel; 641 maxColors = 1 << fBitsPerPixel;
598 if (fNumColors == 0 || fNumColors >= maxColors) { 642 if (fNumColors == 0 || fNumColors >= maxColors) {
599 fNumColors = maxColors; 643 fNumColors = maxColors;
600 } 644 }
601 645
646 // Inform the caller of the number of colors
647 if (NULL != numColors) {
648 SkASSERT(256 == *numColors);
649 // We set the number of colors to maxColors in order to ensure
650 // safe memory accesses. Otherwise, an invalid pixel could
651 // access memory outside of our color table array.
652 *numColors = maxColors;
653 }
654
602 // Read the color table from the stream 655 // Read the color table from the stream
603 colorBytes = fNumColors * fBytesPerColor; 656 colorBytes = fNumColors * fBytesPerColor;
604 SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes)); 657 SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes));
605 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { 658 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) {
606 SkCodecPrintf("Error: unable to read color table.\n"); 659 SkCodecPrintf("Error: unable to read color table.\n");
607 return false; 660 return false;
608 } 661 }
609 662
610 // Choose the proper packing function 663 // Choose the proper packing function
611 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); 664 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
733 786
734 // Finished decoding the entire image 787 // Finished decoding the entire image
735 return kSuccess; 788 return kSuccess;
736 } 789 }
737 790
738 /* 791 /*
739 * 792 *
740 * Set an RLE pixel using the color table 793 * Set an RLE pixel using the color table
741 * 794 *
742 */ 795 */
743 void SkBmpCodec::setRLEPixel(SkPMColor* dst, size_t dstRowBytes, 796 void SkBmpCodec::setRLEPixel(void* dst, size_t dstRowBytes,
744 const SkImageInfo& dstInfo, uint32_t x, uint32_t y, 797 const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
745 uint8_t index) { 798 uint8_t index) {
746 // Set the row 799 // Set the row
747 int height = dstInfo.height(); 800 int height = dstInfo.height();
748 int row; 801 int row;
749 if (kBottomUp_RowOrder == fRowOrder) { 802 if (kBottomUp_RowOrder == fRowOrder) {
750 row = height - y - 1; 803 row = height - y - 1;
751 } else { 804 } else {
752 row = y; 805 row = y;
753 } 806 }
754 807
755 // Set the pixel based on destination color type 808 // Set the pixel based on destination color type
756 switch (dstInfo.colorType()) { 809 switch (dstInfo.colorType()) {
757 case kN32_SkColorType: { 810 case kN32_SkColorType: {
758 SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, 811 SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
759 row * (int) dstRowBytes); 812 row * (int) dstRowBytes);
760 dstRow[x] = fColorTable->operator[](index); 813 dstRow[x] = fColorTable->operator[](index);
761 break; 814 break;
762 } 815 }
763 case kRGB_565_SkColorType: {
764 uint16_t* dstRow = SkTAddOffset<uint16_t>(dst,
765 row * (int) dstRowBytes);
766 dstRow[x] = SkPixel32ToPixel16(fColorTable->operator[](index));
767 break;
768 }
769 default: 816 default:
770 // This case should not be reached. We should catch an invalid 817 // This case should not be reached. We should catch an invalid
771 // color type when we check that the conversion is possible. 818 // color type when we check that the conversion is possible.
772 SkASSERT(false); 819 SkASSERT(false);
773 break; 820 break;
774 } 821 }
775 } 822 }
776 823
777 /* 824 /*
778 * 825 *
779 * Set an RLE pixel from R, G, B values 826 * Set an RLE pixel from R, G, B values
780 * 827 *
781 */ 828 */
782 void SkBmpCodec::setRLE24Pixel(SkPMColor* dst, size_t dstRowBytes, 829 void SkBmpCodec::setRLE24Pixel(void* dst, size_t dstRowBytes,
783 const SkImageInfo& dstInfo, uint32_t x, 830 const SkImageInfo& dstInfo, uint32_t x,
784 uint32_t y, uint8_t red, uint8_t green, 831 uint32_t y, uint8_t red, uint8_t green,
785 uint8_t blue) { 832 uint8_t blue) {
786 // Set the row 833 // Set the row
787 int height = dstInfo.height(); 834 int height = dstInfo.height();
788 int row; 835 int row;
789 if (kBottomUp_RowOrder == fRowOrder) { 836 if (kBottomUp_RowOrder == fRowOrder) {
790 row = height - y - 1; 837 row = height - y - 1;
791 } else { 838 } else {
792 row = y; 839 row = y;
793 } 840 }
794 841
795 // Set the pixel based on destination color type 842 // Set the pixel based on destination color type
796 switch (dstInfo.colorType()) { 843 switch (dstInfo.colorType()) {
797 case kN32_SkColorType: { 844 case kN32_SkColorType: {
798 SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, 845 SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
799 row * (int) dstRowBytes); 846 row * (int) dstRowBytes);
800 dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue); 847 dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue);
801 break; 848 break;
802 } 849 }
803 case kRGB_565_SkColorType: {
804 uint16_t* dstRow = SkTAddOffset<uint16_t>(dst,
805 row * (int) dstRowBytes);
806 dstRow[x] = SkPack888ToRGB16(red, green, blue);
807 break;
808 }
809 default: 850 default:
810 // This case should not be reached. We should catch an invalid 851 // This case should not be reached. We should catch an invalid
811 // color type when we check that the conversion is possible. 852 // color type when we check that the conversion is possible.
812 SkASSERT(false); 853 SkASSERT(false);
813 break; 854 break;
814 } 855 }
815 } 856 }
816 857
817 /* 858 /*
818 * 859 *
819 * Performs the bitmap decoding for RLE input format 860 * Performs the bitmap decoding for RLE input format
820 * RLE decoding is performed all at once, rather than a one row at a time 861 * RLE decoding is performed all at once, rather than a one row at a time
821 * 862 *
822 */ 863 */
823 SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo, 864 SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo,
824 void* dst, size_t dstRowBytes) { 865 void* dst, size_t dstRowBytes,
866 const Options& opts) {
825 // Set RLE flags 867 // Set RLE flags
826 static const uint8_t RLE_ESCAPE = 0; 868 static const uint8_t RLE_ESCAPE = 0;
827 static const uint8_t RLE_EOL = 0; 869 static const uint8_t RLE_EOL = 0;
828 static const uint8_t RLE_EOF = 1; 870 static const uint8_t RLE_EOF = 1;
829 static const uint8_t RLE_DELTA = 2; 871 static const uint8_t RLE_DELTA = 2;
830 872
831 // Set constant values 873 // Set constant values
832 const int width = dstInfo.width(); 874 const int width = dstInfo.width();
833 const int height = dstInfo.height(); 875 const int height = dstInfo.height();
834 876
835 // Input buffer parameters 877 // Input buffer parameters
836 uint32_t currByte = 0; 878 uint32_t currByte = 0;
837 SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRLEBytes)); 879 SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRLEBytes));
838 size_t totalBytes = stream()->read(buffer.get(), fRLEBytes); 880 size_t totalBytes = stream()->read(buffer.get(), fRLEBytes);
839 if (totalBytes < fRLEBytes) { 881 if (totalBytes < fRLEBytes) {
840 SkCodecPrintf("Warning: incomplete RLE file.\n"); 882 SkCodecPrintf("Warning: incomplete RLE file.\n");
841 } else if (totalBytes <= 0) { 883 } else if (totalBytes <= 0) {
842 SkCodecPrintf("Error: could not read RLE image data.\n"); 884 SkCodecPrintf("Error: could not read RLE image data.\n");
843 return kInvalidInput; 885 return kInvalidInput;
844 } 886 }
845 887
846 // Destination parameters 888 // Destination parameters
847 int x = 0; 889 int x = 0;
848 int y = 0; 890 int y = 0;
849 // If the code skips pixels, remaining pixels are transparent or black 891
850 // TODO: Skip this if memory was already zeroed. 892 // Set the background as transparent. Then, if the RLE code skips pixels,
851 memset(dst, 0, dstRowBytes * height); 893 // the skipped pixels will be transparent.
852 SkPMColor* dstPtr = (SkPMColor*) dst; 894 // Because of the need for transparent pixels, kN32 is the only color
895 // type that makes sense for the destination format.
896 SkASSERT(kN32_SkColorType == dstInfo.colorType());
897 if (kNo_ZeroInitialized == opts.fZeroInitialized) {
898 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, 0, SK_ColorTRANSPARENT, NULL );
899 }
853 900
854 while (true) { 901 while (true) {
855 // Every entry takes at least two bytes 902 // Every entry takes at least two bytes
856 if ((int) totalBytes - currByte < 2) { 903 if ((int) totalBytes - currByte < 2) {
857 SkCodecPrintf("Warning: incomplete RLE input.\n"); 904 SkCodecPrintf("Warning: incomplete RLE input.\n");
858 return kIncompleteInput; 905 return kIncompleteInput;
859 } 906 }
860 907
861 // Read the next two bytes. These bytes have different meanings 908 // Read the next two bytes. These bytes have different meanings
862 // depending on their values. In the first interpretation, the first 909 // depending on their values. In the first interpretation, the first
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 (int) totalBytes - currByte < SkAlign2(rowBytes)) { 960 (int) totalBytes - currByte < SkAlign2(rowBytes)) {
914 SkCodecPrintf("Warning: invalid RLE input.\n"); 961 SkCodecPrintf("Warning: invalid RLE input.\n");
915 return kIncompleteInput; 962 return kIncompleteInput;
916 } 963 }
917 // Set numPixels number of pixels 964 // Set numPixels number of pixels
918 while (numPixels > 0) { 965 while (numPixels > 0) {
919 switch(fBitsPerPixel) { 966 switch(fBitsPerPixel) {
920 case 4: { 967 case 4: {
921 SkASSERT(currByte < totalBytes); 968 SkASSERT(currByte < totalBytes);
922 uint8_t val = buffer.get()[currByte++]; 969 uint8_t val = buffer.get()[currByte++];
923 setRLEPixel(dstPtr, dstRowBytes, dstInfo, x++, 970 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
924 y, val >> 4); 971 y, val >> 4);
925 numPixels--; 972 numPixels--;
926 if (numPixels != 0) { 973 if (numPixels != 0) {
927 setRLEPixel(dstPtr, dstRowBytes, dstInfo, 974 setRLEPixel(dst, dstRowBytes, dstInfo,
928 x++, y, val & 0xF); 975 x++, y, val & 0xF);
929 numPixels--; 976 numPixels--;
930 } 977 }
931 break; 978 break;
932 } 979 }
933 case 8: 980 case 8:
934 SkASSERT(currByte < totalBytes); 981 SkASSERT(currByte < totalBytes);
935 setRLEPixel(dstPtr, dstRowBytes, dstInfo, x++, 982 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
936 y, buffer.get()[currByte++]); 983 y, buffer.get()[currByte++]);
937 numPixels--; 984 numPixels--;
938 break; 985 break;
939 case 24: { 986 case 24: {
940 SkASSERT(currByte + 2 < totalBytes); 987 SkASSERT(currByte + 2 < totalBytes);
941 uint8_t blue = buffer.get()[currByte++]; 988 uint8_t blue = buffer.get()[currByte++];
942 uint8_t green = buffer.get()[currByte++]; 989 uint8_t green = buffer.get()[currByte++];
943 uint8_t red = buffer.get()[currByte++]; 990 uint8_t red = buffer.get()[currByte++];
944 setRLE24Pixel(dstPtr, dstRowBytes, dstInfo, 991 setRLE24Pixel(dst, dstRowBytes, dstInfo,
945 x++, y, red, green, blue); 992 x++, y, red, green, blue);
946 numPixels--; 993 numPixels--;
947 } 994 }
948 default: 995 default:
949 SkASSERT(false); 996 SkASSERT(false);
950 return kInvalidInput; 997 return kInvalidInput;
951 } 998 }
952 } 999 }
953 // Skip a byte if necessary to maintain alignment 1000 // Skip a byte if necessary to maintain alignment
954 if (!SkIsAlign2(rowBytes)) { 1001 if (!SkIsAlign2(rowBytes)) {
(...skipping 15 matching lines...) Expand all
970 if ((int) totalBytes - currByte < 2) { 1017 if ((int) totalBytes - currByte < 2) {
971 SkCodecPrintf("Warning: incomplete RLE input\n"); 1018 SkCodecPrintf("Warning: incomplete RLE input\n");
972 return kIncompleteInput; 1019 return kIncompleteInput;
973 } 1020 }
974 1021
975 // Fill the pixels up to endX with the specified color 1022 // Fill the pixels up to endX with the specified color
976 uint8_t blue = task; 1023 uint8_t blue = task;
977 uint8_t green = buffer.get()[currByte++]; 1024 uint8_t green = buffer.get()[currByte++];
978 uint8_t red = buffer.get()[currByte++]; 1025 uint8_t red = buffer.get()[currByte++];
979 while (x < endX) { 1026 while (x < endX) {
980 setRLE24Pixel(dstPtr, dstRowBytes, dstInfo, x++, y, red, 1027 setRLE24Pixel(dst, dstRowBytes, dstInfo, x++, y, red,
981 green, blue); 1028 green, blue);
982 } 1029 }
983 } else { 1030 } else {
984 // In RLE8 or RLE4, the second byte read gives the index in the 1031 // In RLE8 or RLE4, the second byte read gives the index in the
985 // color table to look up the pixel color. 1032 // color table to look up the pixel color.
986 // RLE8 has one color index that gets repeated 1033 // RLE8 has one color index that gets repeated
987 // RLE4 has two color indexes in the upper and lower 4 bits of 1034 // RLE4 has two color indexes in the upper and lower 4 bits of
988 // the bytes, which are alternated 1035 // the bytes, which are alternated
989 uint8_t indices[2] = { task, task }; 1036 uint8_t indices[2] = { task, task };
990 if (4 == fBitsPerPixel) { 1037 if (4 == fBitsPerPixel) {
991 indices[0] >>= 4; 1038 indices[0] >>= 4;
992 indices[1] &= 0xf; 1039 indices[1] &= 0xf;
993 } 1040 }
994 1041
995 // Set the indicated number of pixels 1042 // Set the indicated number of pixels
996 for (int which = 0; x < endX; x++) { 1043 for (int which = 0; x < endX; x++) {
997 setRLEPixel(dstPtr, dstRowBytes, dstInfo, x, y, 1044 setRLEPixel(dst, dstRowBytes, dstInfo, x, y,
998 indices[which]); 1045 indices[which]);
999 which = !which; 1046 which = !which;
1000 } 1047 }
1001 } 1048 }
1002 } 1049 }
1003 } 1050 }
1004 } 1051 }
1005 1052
1006 /* 1053 /*
1007 * 1054 *
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 } 1124 }
1078 1125
1079 // FIXME: This code exists to match the behavior in the chromium decoder 1126 // FIXME: This code exists to match the behavior in the chromium decoder
1080 // and to follow the bmp specification as it relates to alpha masks. It is 1127 // and to follow the bmp specification as it relates to alpha masks. It is
1081 // commented out because we have yet to discover a test image that provides 1128 // commented out because we have yet to discover a test image that provides
1082 // an alpha mask and uses this decode mode. 1129 // an alpha mask and uses this decode mode.
1083 1130
1084 // Now we adjust the output image with some additional behavior that 1131 // Now we adjust the output image with some additional behavior that
1085 // SkSwizzler does not support. Firstly, all bmp images that contain 1132 // SkSwizzler does not support. Firstly, all bmp images that contain
1086 // alpha are masked by the alpha mask. Secondly, many fully transparent 1133 // alpha are masked by the alpha mask. Secondly, many fully transparent
1087 // bmp images are intended to be opaque. Here, we make those corrections. 1134 // bmp images are intended to be opaque. Here, we make those corrections
1135 // in the kN32 case.
1088 /* 1136 /*
1089 SkPMColor* dstRow = (SkPMColor*) dst; 1137 SkPMColor* dstRow = (SkPMColor*) dst;
1090 if (SkSwizzler::kBGRA == config) { 1138 if (SkSwizzler::kBGRA == config) {
1091 for (int y = 0; y < height; y++) { 1139 for (int y = 0; y < height; y++) {
1092 for (int x = 0; x < width; x++) { 1140 for (int x = 0; x < width; x++) {
1093 if (transparent) { 1141 if (transparent) {
1094 dstRow[x] |= 0xFF000000; 1142 dstRow[x] |= 0xFF000000;
1095 } else { 1143 } else {
1096 dstRow[x] &= alphaMask; 1144 dstRow[x] &= alphaMask;
1097 } 1145 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 uint32_t alphaBit = 1180 uint32_t alphaBit =
1133 (srcBuffer.get()[quotient] >> shift) & 0x1; 1181 (srcBuffer.get()[quotient] >> shift) & 0x1;
1134 dstRow[x] &= alphaBit - 1; 1182 dstRow[x] &= alphaBit - 1;
1135 } 1183 }
1136 } 1184 }
1137 } 1185 }
1138 1186
1139 // Finished decoding the entire image 1187 // Finished decoding the entire image
1140 return kSuccess; 1188 return kSuccess;
1141 } 1189 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698