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

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: Avoid setting a field to a local variable 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 (kPremul_SkAlphaType != dst.alphaType() ||
30 kUnpremul_SkAlphaType == src.alphaType())) {
scroggo 2015/04/06 14:55:11 I think this is not quite the ! of the original st
msarett 2015/04/06 18:10:55 Yeah that statement was confusing and wrong. Your
31 return false;
32 }
33
34 // Check for supported color types
27 switch (dst.colorType()) { 35 switch (dst.colorType()) {
36 // Allow output to kN32 from any type of input
28 case kN32_SkColorType: 37 case kN32_SkColorType:
29 return src.alphaType() == dst.alphaType() || 38 return true;
30 (kPremul_SkAlphaType == dst.alphaType() && 39 // Allow output to kIndex_8 from compatible inputs
31 kUnpremul_SkAlphaType == src.alphaType()); 40 case kIndex_8_SkColorType:
41 return kIndex_8_SkColorType == src.colorType();
32 default: 42 default:
33 return false; 43 return false;
34 } 44 }
35 } 45 }
36 46
37 /* 47 /*
38 * 48 *
39 * Defines the version and type of the second bitmap header 49 * Defines the version and type of the second bitmap header
40 * 50 *
41 */ 51 */
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 // Header types are matched based on size. If the header is 422 // Header types are matched based on size. If the header is
413 // V3+, we are guaranteed to be able to read at least this size. 423 // V3+, we are guaranteed to be able to read at least this size.
414 SkASSERT(infoBytesRemaining > 52); 424 SkASSERT(infoBytesRemaining > 52);
415 inputMasks.alpha = get_int(iBuffer.get(), 48); 425 inputMasks.alpha = get_int(iBuffer.get(), 48);
416 if (inputMasks.alpha != 0) { 426 if (inputMasks.alpha != 0) {
417 alphaType = kUnpremul_SkAlphaType; 427 alphaType = kUnpremul_SkAlphaType;
418 } 428 }
419 } 429 }
420 iBuffer.free(); 430 iBuffer.free();
421 431
422 // Additionally, 32 bit bmp-in-icos use the alpha channel 432 // Additionally, 32 bit bmp-in-icos use the alpha channel.
423 if (isIco && 32 == bitsPerPixel) { 433 // And, RLE inputs may skip pixels, leaving them as transparent. This
434 // is uncommon, but we cannot be certain that an RLE bmp will be opaque.
435 if ((isIco && 32 == bitsPerPixel) || (kRLE_BitmapInputFormat == inputFormat) ) {
424 alphaType = kUnpremul_SkAlphaType; 436 alphaType = kUnpremul_SkAlphaType;
425 } 437 }
426 438
427 // Check for valid bits per pixel input 439 // Check for valid bits per pixel.
440 // At the same time, use this information to choose a suggested color type
441 // and to set default masks.
442 SkColorType colorType = kN32_SkColorType;
428 switch (bitsPerPixel) { 443 switch (bitsPerPixel) {
429 // In addition to more standard pixel compression formats, bmp supports 444 // In addition to more standard pixel compression formats, bmp supports
430 // the use of bit masks to determine pixel components. The standard 445 // the use of bit masks to determine pixel components. The standard
431 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB), 446 // format for representing 16-bit colors is 555 (XRRRRRGGGGGBBBBB),
432 // which does not map well to any Skia color formats. For this reason, 447 // which does not map well to any Skia color formats. For this reason,
433 // we will always enable mask mode with 16 bits per pixel. 448 // we will always enable mask mode with 16 bits per pixel.
434 case 16: 449 case 16:
435 if (kBitMask_BitmapInputFormat != inputFormat) { 450 if (kBitMask_BitmapInputFormat != inputFormat) {
436 inputMasks.red = 0x7C00; 451 inputMasks.red = 0x7C00;
437 inputMasks.green = 0x03E0; 452 inputMasks.green = 0x03E0;
438 inputMasks.blue = 0x001F; 453 inputMasks.blue = 0x001F;
439 inputFormat = kBitMask_BitmapInputFormat; 454 inputFormat = kBitMask_BitmapInputFormat;
440 } 455 }
441 break; 456 break;
457 // We want to decode to kIndex_8 for input formats that are already
458 // designed in index format.
442 case 1: 459 case 1:
443 case 2: 460 case 2:
444 case 4: 461 case 4:
445 case 8: 462 case 8:
463 // However, we cannot in RLE format since we may need to leave some
464 // pixels as transparent. Similarly, we also cannot for ICO images
465 // since we may need to apply a transparent mask.
466 if (kRLE_BitmapInputFormat != inputFormat && !isIco) {
467 colorType = kIndex_8_SkColorType;
468 }
446 case 24: 469 case 24:
447 case 32: 470 case 32:
448 break; 471 break;
449 default: 472 default:
450 SkCodecPrintf("Error: invalid input value for bits per pixel.\n"); 473 SkCodecPrintf("Error: invalid input value for bits per pixel.\n");
451 return false; 474 return false;
452 } 475 }
453 476
454 // Check that input bit masks are valid and create the masks object 477 // Check that input bit masks are valid and create the masks object
455 SkAutoTDelete<SkMasks> 478 SkAutoTDelete<SkMasks>
(...skipping 12 matching lines...) Expand all
468 491
469 // Calculate the number of bytes read so far 492 // Calculate the number of bytes read so far
470 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes; 493 const uint32_t bytesRead = kBmpHeaderBytes + infoBytes + maskBytes;
471 if (!isIco && offset < bytesRead) { 494 if (!isIco && offset < bytesRead) {
472 SkCodecPrintf("Error: pixel data offset less than header size.\n"); 495 SkCodecPrintf("Error: pixel data offset less than header size.\n");
473 return false; 496 return false;
474 } 497 }
475 498
476 if (codecOut) { 499 if (codecOut) {
477 // Return the codec 500 // Return the codec
478 // We will use ImageInfo to store width, height, and alpha type. We 501 // We will use ImageInfo to store width, height, suggested color type, a nd
479 // will set color type to kN32_SkColorType because that should be the 502 // suggested alpha type.
480 // default output.
481 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height, 503 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height,
482 kN32_SkColorType, alphaType); 504 colorType, alphaType);
483 *codecOut = SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel, 505 *codecOut = SkNEW_ARGS(SkBmpCodec, (imageInfo, stream, bitsPerPixel,
484 inputFormat, masks.detach(), 506 inputFormat, masks.detach(),
485 numColors, bytesPerColor, 507 numColors, bytesPerColor,
486 offset - bytesRead, rowOrder, 508 offset - bytesRead, rowOrder,
487 RLEBytes, isIco)); 509 RLEBytes, isIco));
488 } 510 }
489 return true; 511 return true;
490 } 512 }
491 513
492 /* 514 /*
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 550
529 {} 551 {}
530 552
531 /* 553 /*
532 * 554 *
533 * Initiates the bitmap decode 555 * Initiates the bitmap decode
534 * 556 *
535 */ 557 */
536 SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo, 558 SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo,
537 void* dst, size_t dstRowBytes, 559 void* dst, size_t dstRowBytes,
538 const Options&, 560 const Options& opts,
539 SkPMColor*, int*) { 561 SkPMColor* inputColorPtr,
562 int* inputColorCount) {
540 // Check for proper input and output formats 563 // Check for proper input and output formats
541 SkCodec::RewindState rewindState = this->rewindIfNeeded(); 564 SkCodec::RewindState rewindState = this->rewindIfNeeded();
542 if (rewindState == kCouldNotRewind_RewindState) { 565 if (rewindState == kCouldNotRewind_RewindState) {
543 return kCouldNotRewind; 566 return kCouldNotRewind;
544 } else if (rewindState == kRewound_RewindState) { 567 } else if (rewindState == kRewound_RewindState) {
545 if (!ReadHeader(this->stream(), fIsIco, NULL)) { 568 if (!ReadHeader(this->stream(), fIsIco, NULL)) {
546 return kCouldNotRewind; 569 return kCouldNotRewind;
547 } 570 }
548 } 571 }
549 if (dstInfo.dimensions() != this->getInfo().dimensions()) { 572 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
550 SkCodecPrintf("Error: scaling not supported.\n"); 573 SkCodecPrintf("Error: scaling not supported.\n");
551 return kInvalidScale; 574 return kInvalidScale;
552 } 575 }
553 if (!conversion_possible(dstInfo, this->getInfo())) { 576 if (!conversion_possible(dstInfo, this->getInfo())) {
554 SkCodecPrintf("Error: cannot convert input type to output type.\n"); 577 SkCodecPrintf("Error: cannot convert input type to output type.\n");
555 return kInvalidConversion; 578 return kInvalidConversion;
556 } 579 }
557 580
558 // Create the color table if necessary and prepare the stream for decode 581 // Create the color table if necessary and prepare the stream for decode
559 if (!createColorTable(dstInfo.alphaType())) { 582 // Note that if it is non-NULL, inputColorCount will be modified
583 if (!createColorTable(dstInfo.alphaType(), inputColorCount)) {
560 SkCodecPrintf("Error: could not create color table.\n"); 584 SkCodecPrintf("Error: could not create color table.\n");
561 return kInvalidInput; 585 return kInvalidInput;
562 } 586 }
563 587
588 // Copy the color table to the client if necessary
589 if (kIndex_8_SkColorType == dstInfo.colorType()) {
590 SkASSERT(NULL != inputColorPtr);
591 SkASSERT(NULL != inputColorCount);
592 SkASSERT(NULL != fColorTable.get());
593 sk_memcpy32(inputColorPtr, fColorTable->readColors(), *inputColorCount);
594 }
595
564 // Perform the decode 596 // Perform the decode
565 switch (fInputFormat) { 597 switch (fInputFormat) {
566 case kBitMask_BitmapInputFormat: 598 case kBitMask_BitmapInputFormat:
567 return decodeMask(dstInfo, dst, dstRowBytes); 599 return decodeMask(dstInfo, dst, dstRowBytes);
568 case kRLE_BitmapInputFormat: 600 case kRLE_BitmapInputFormat:
569 return decodeRLE(dstInfo, dst, dstRowBytes); 601 return decodeRLE(dstInfo, dst, dstRowBytes, opts);
570 case kStandard_BitmapInputFormat: 602 case kStandard_BitmapInputFormat:
571 return decode(dstInfo, dst, dstRowBytes); 603 return decode(dstInfo, dst, dstRowBytes);
572 default: 604 default:
573 SkASSERT(false); 605 SkASSERT(false);
574 return kInvalidInput; 606 return kInvalidInput;
575 } 607 }
576 } 608 }
577 609
578 /* 610 /*
579 * 611 *
580 * Process the color table for the bmp input 612 * Process the color table for the bmp input
581 * 613 *
582 */ 614 */
583 bool SkBmpCodec::createColorTable(SkAlphaType alphaType) { 615 bool SkBmpCodec::createColorTable(SkAlphaType alphaType, int* numColors) {
584 // Allocate memory for color table 616 // Allocate memory for color table
585 uint32_t colorBytes = 0; 617 uint32_t colorBytes = 0;
586 uint32_t maxColors = 0; 618 uint32_t maxColors = 0;
587 SkPMColor colorTable[256]; 619 SkPMColor colorTable[256];
588 if (fBitsPerPixel <= 8) { 620 if (fBitsPerPixel <= 8) {
589 // Zero is a default for maxColors 621 // Zero is a default for maxColors
590 // Also set fNumColors to maxColors when it is too large 622 // Also set fNumColors to maxColors when it is too large
591 maxColors = 1 << fBitsPerPixel; 623 maxColors = 1 << fBitsPerPixel;
592 if (fNumColors == 0 || fNumColors >= maxColors) { 624 if (fNumColors == 0 || fNumColors >= maxColors) {
593 fNumColors = maxColors; 625 fNumColors = maxColors;
594 } 626 }
595 627
628 // Inform the caller of the number of colors
629 if (NULL != numColors) {
630 SkASSERT(256 == *numColors);
631 *numColors = maxColors;
scroggo 2015/04/06 14:55:11 Maybe add a note that we set it to maxColors in ca
msarett 2015/04/06 18:10:55 Done.
632 }
633
596 // Read the color table from the stream 634 // Read the color table from the stream
597 colorBytes = fNumColors * fBytesPerColor; 635 colorBytes = fNumColors * fBytesPerColor;
598 SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes)); 636 SkAutoTDeleteArray<uint8_t> cBuffer(SkNEW_ARRAY(uint8_t, colorBytes));
599 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { 637 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) {
600 SkCodecPrintf("Error: unable to read color table.\n"); 638 SkCodecPrintf("Error: unable to read color table.\n");
601 return false; 639 return false;
602 } 640 }
603 641
604 // Choose the proper packing function 642 // Choose the proper packing function
605 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); 643 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 765
728 // Finished decoding the entire image 766 // Finished decoding the entire image
729 return kSuccess; 767 return kSuccess;
730 } 768 }
731 769
732 /* 770 /*
733 * 771 *
734 * Set an RLE pixel using the color table 772 * Set an RLE pixel using the color table
735 * 773 *
736 */ 774 */
737 void SkBmpCodec::setRLEPixel(SkPMColor* dst, size_t dstRowBytes, 775 void SkBmpCodec::setRLEPixel(void* dst, size_t dstRowBytes,
738 const SkImageInfo& dstInfo, uint32_t x, uint32_t y, 776 const SkImageInfo& dstInfo, uint32_t x, uint32_t y,
739 uint8_t index) { 777 uint8_t index) {
740 // Set the row 778 // Set the row
741 int height = dstInfo.height(); 779 int height = dstInfo.height();
742 int row; 780 int row;
743 if (kBottomUp_RowOrder == fRowOrder) { 781 if (kBottomUp_RowOrder == fRowOrder) {
744 row = height - y - 1; 782 row = height - y - 1;
745 } else { 783 } else {
746 row = y; 784 row = y;
747 } 785 }
748 786
749 // Set the pixel based on destination color type 787 // Set the pixel based on destination color type
750 switch (dstInfo.colorType()) { 788 switch (dstInfo.colorType()) {
751 case kN32_SkColorType: { 789 case kN32_SkColorType: {
752 SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, 790 SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
753 row * (int) dstRowBytes); 791 row * (int) dstRowBytes);
754 dstRow[x] = fColorTable->operator[](index); 792 dstRow[x] = fColorTable->operator[](index);
755 break; 793 break;
756 } 794 }
757 case kRGB_565_SkColorType: {
758 uint16_t* dstRow = SkTAddOffset<uint16_t>(dst,
759 row * (int) dstRowBytes);
760 dstRow[x] = SkPixel32ToPixel16(fColorTable->operator[](index));
761 break;
762 }
763 default: 795 default:
764 // This case should not be reached. We should catch an invalid 796 // This case should not be reached. We should catch an invalid
765 // color type when we check that the conversion is possible. 797 // color type when we check that the conversion is possible.
766 SkASSERT(false); 798 SkASSERT(false);
767 break; 799 break;
768 } 800 }
769 } 801 }
770 802
771 /* 803 /*
772 * 804 *
773 * Set an RLE pixel from R, G, B values 805 * Set an RLE pixel from R, G, B values
774 * 806 *
775 */ 807 */
776 void SkBmpCodec::setRLE24Pixel(SkPMColor* dst, size_t dstRowBytes, 808 void SkBmpCodec::setRLE24Pixel(void* dst, size_t dstRowBytes,
777 const SkImageInfo& dstInfo, uint32_t x, 809 const SkImageInfo& dstInfo, uint32_t x,
778 uint32_t y, uint8_t red, uint8_t green, 810 uint32_t y, uint8_t red, uint8_t green,
779 uint8_t blue) { 811 uint8_t blue) {
780 // Set the row 812 // Set the row
781 int height = dstInfo.height(); 813 int height = dstInfo.height();
782 int row; 814 int row;
783 if (kBottomUp_RowOrder == fRowOrder) { 815 if (kBottomUp_RowOrder == fRowOrder) {
784 row = height - y - 1; 816 row = height - y - 1;
785 } else { 817 } else {
786 row = y; 818 row = y;
787 } 819 }
788 820
789 // Set the pixel based on destination color type 821 // Set the pixel based on destination color type
790 switch (dstInfo.colorType()) { 822 switch (dstInfo.colorType()) {
791 case kN32_SkColorType: { 823 case kN32_SkColorType: {
792 SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, 824 SkPMColor* dstRow = SkTAddOffset<SkPMColor>((SkPMColor*) dst,
793 row * (int) dstRowBytes); 825 row * (int) dstRowBytes);
794 dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue); 826 dstRow[x] = SkPackARGB32NoCheck(0xFF, red, green, blue);
795 break; 827 break;
796 } 828 }
797 case kRGB_565_SkColorType: {
798 uint16_t* dstRow = SkTAddOffset<uint16_t>(dst,
799 row * (int) dstRowBytes);
800 dstRow[x] = SkPack888ToRGB16(red, green, blue);
801 break;
802 }
803 default: 829 default:
804 // This case should not be reached. We should catch an invalid 830 // This case should not be reached. We should catch an invalid
805 // color type when we check that the conversion is possible. 831 // color type when we check that the conversion is possible.
806 SkASSERT(false); 832 SkASSERT(false);
807 break; 833 break;
808 } 834 }
809 } 835 }
810 836
811 /* 837 /*
812 * 838 *
813 * Performs the bitmap decoding for RLE input format 839 * Performs the bitmap decoding for RLE input format
814 * RLE decoding is performed all at once, rather than a one row at a time 840 * RLE decoding is performed all at once, rather than a one row at a time
815 * 841 *
816 */ 842 */
817 SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo, 843 SkCodec::Result SkBmpCodec::decodeRLE(const SkImageInfo& dstInfo,
818 void* dst, size_t dstRowBytes) { 844 void* dst, size_t dstRowBytes,
845 const Options& opts) {
819 // Set RLE flags 846 // Set RLE flags
820 static const uint8_t RLE_ESCAPE = 0; 847 static const uint8_t RLE_ESCAPE = 0;
821 static const uint8_t RLE_EOL = 0; 848 static const uint8_t RLE_EOL = 0;
822 static const uint8_t RLE_EOF = 1; 849 static const uint8_t RLE_EOF = 1;
823 static const uint8_t RLE_DELTA = 2; 850 static const uint8_t RLE_DELTA = 2;
824 851
825 // Set constant values 852 // Set constant values
826 const int width = dstInfo.width(); 853 const int width = dstInfo.width();
827 const int height = dstInfo.height(); 854 const int height = dstInfo.height();
828 855
829 // Input buffer parameters 856 // Input buffer parameters
830 uint32_t currByte = 0; 857 uint32_t currByte = 0;
831 SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRLEBytes)); 858 SkAutoTDeleteArray<uint8_t> buffer(SkNEW_ARRAY(uint8_t, fRLEBytes));
832 size_t totalBytes = stream()->read(buffer.get(), fRLEBytes); 859 size_t totalBytes = stream()->read(buffer.get(), fRLEBytes);
833 if (totalBytes < fRLEBytes) { 860 if (totalBytes < fRLEBytes) {
834 SkCodecPrintf("Warning: incomplete RLE file.\n"); 861 SkCodecPrintf("Warning: incomplete RLE file.\n");
835 } else if (totalBytes <= 0) { 862 } else if (totalBytes <= 0) {
836 SkCodecPrintf("Error: could not read RLE image data.\n"); 863 SkCodecPrintf("Error: could not read RLE image data.\n");
837 return kInvalidInput; 864 return kInvalidInput;
838 } 865 }
839 866
840 // Destination parameters 867 // Destination parameters
841 int x = 0; 868 int x = 0;
842 int y = 0; 869 int y = 0;
843 // If the code skips pixels, remaining pixels are transparent or black 870
844 // TODO: Skip this if memory was already zeroed. 871 // Set the background as transparent. Then, if the RLE code skips pixels,
845 memset(dst, 0, dstRowBytes * height); 872 // the skipped pixels will be transparent.
846 SkPMColor* dstPtr = (SkPMColor*) dst; 873 // Because of the need for transparent pixels, kN32 is the only color
874 // type that makes sense for the destination format.
875 SkASSERT(kN32_SkColorType == dstInfo.colorType());
876 if (kNo_ZeroInitialized == opts.fZeroInitialized) {
877 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, 0, SK_ColorTRANSPARENT, NULL );
878 }
847 879
848 while (true) { 880 while (true) {
849 // Every entry takes at least two bytes 881 // Every entry takes at least two bytes
850 if ((int) totalBytes - currByte < 2) { 882 if ((int) totalBytes - currByte < 2) {
851 SkCodecPrintf("Warning: incomplete RLE input.\n"); 883 SkCodecPrintf("Warning: incomplete RLE input.\n");
852 return kIncompleteInput; 884 return kIncompleteInput;
853 } 885 }
854 886
855 // Read the next two bytes. These bytes have different meanings 887 // Read the next two bytes. These bytes have different meanings
856 // depending on their values. In the first interpretation, the first 888 // depending on their values. In the first interpretation, the first
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 (int) totalBytes - currByte < SkAlign2(rowBytes)) { 939 (int) totalBytes - currByte < SkAlign2(rowBytes)) {
908 SkCodecPrintf("Warning: invalid RLE input.\n"); 940 SkCodecPrintf("Warning: invalid RLE input.\n");
909 return kIncompleteInput; 941 return kIncompleteInput;
910 } 942 }
911 // Set numPixels number of pixels 943 // Set numPixels number of pixels
912 while (numPixels > 0) { 944 while (numPixels > 0) {
913 switch(fBitsPerPixel) { 945 switch(fBitsPerPixel) {
914 case 4: { 946 case 4: {
915 SkASSERT(currByte < totalBytes); 947 SkASSERT(currByte < totalBytes);
916 uint8_t val = buffer.get()[currByte++]; 948 uint8_t val = buffer.get()[currByte++];
917 setRLEPixel(dstPtr, dstRowBytes, dstInfo, x++, 949 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
918 y, val >> 4); 950 y, val >> 4);
919 numPixels--; 951 numPixels--;
920 if (numPixels != 0) { 952 if (numPixels != 0) {
921 setRLEPixel(dstPtr, dstRowBytes, dstInfo, 953 setRLEPixel(dst, dstRowBytes, dstInfo,
922 x++, y, val & 0xF); 954 x++, y, val & 0xF);
923 numPixels--; 955 numPixels--;
924 } 956 }
925 break; 957 break;
926 } 958 }
927 case 8: 959 case 8:
928 SkASSERT(currByte < totalBytes); 960 SkASSERT(currByte < totalBytes);
929 setRLEPixel(dstPtr, dstRowBytes, dstInfo, x++, 961 setRLEPixel(dst, dstRowBytes, dstInfo, x++,
930 y, buffer.get()[currByte++]); 962 y, buffer.get()[currByte++]);
931 numPixels--; 963 numPixels--;
932 break; 964 break;
933 case 24: { 965 case 24: {
934 SkASSERT(currByte + 2 < totalBytes); 966 SkASSERT(currByte + 2 < totalBytes);
935 uint8_t blue = buffer.get()[currByte++]; 967 uint8_t blue = buffer.get()[currByte++];
936 uint8_t green = buffer.get()[currByte++]; 968 uint8_t green = buffer.get()[currByte++];
937 uint8_t red = buffer.get()[currByte++]; 969 uint8_t red = buffer.get()[currByte++];
938 setRLE24Pixel(dstPtr, dstRowBytes, dstInfo, 970 setRLE24Pixel(dst, dstRowBytes, dstInfo,
939 x++, y, red, green, blue); 971 x++, y, red, green, blue);
940 numPixels--; 972 numPixels--;
941 } 973 }
942 default: 974 default:
943 SkASSERT(false); 975 SkASSERT(false);
944 return kInvalidInput; 976 return kInvalidInput;
945 } 977 }
946 } 978 }
947 // Skip a byte if necessary to maintain alignment 979 // Skip a byte if necessary to maintain alignment
948 if (!SkIsAlign2(rowBytes)) { 980 if (!SkIsAlign2(rowBytes)) {
(...skipping 15 matching lines...) Expand all
964 if ((int) totalBytes - currByte < 2) { 996 if ((int) totalBytes - currByte < 2) {
965 SkCodecPrintf("Warning: incomplete RLE input\n"); 997 SkCodecPrintf("Warning: incomplete RLE input\n");
966 return kIncompleteInput; 998 return kIncompleteInput;
967 } 999 }
968 1000
969 // Fill the pixels up to endX with the specified color 1001 // Fill the pixels up to endX with the specified color
970 uint8_t blue = task; 1002 uint8_t blue = task;
971 uint8_t green = buffer.get()[currByte++]; 1003 uint8_t green = buffer.get()[currByte++];
972 uint8_t red = buffer.get()[currByte++]; 1004 uint8_t red = buffer.get()[currByte++];
973 while (x < endX) { 1005 while (x < endX) {
974 setRLE24Pixel(dstPtr, dstRowBytes, dstInfo, x++, y, red, 1006 setRLE24Pixel(dst, dstRowBytes, dstInfo, x++, y, red,
975 green, blue); 1007 green, blue);
976 } 1008 }
977 } else { 1009 } else {
978 // In RLE8 or RLE4, the second byte read gives the index in the 1010 // In RLE8 or RLE4, the second byte read gives the index in the
979 // color table to look up the pixel color. 1011 // color table to look up the pixel color.
980 // RLE8 has one color index that gets repeated 1012 // RLE8 has one color index that gets repeated
981 // RLE4 has two color indexes in the upper and lower 4 bits of 1013 // RLE4 has two color indexes in the upper and lower 4 bits of
982 // the bytes, which are alternated 1014 // the bytes, which are alternated
983 uint8_t indices[2] = { task, task }; 1015 uint8_t indices[2] = { task, task };
984 if (4 == fBitsPerPixel) { 1016 if (4 == fBitsPerPixel) {
985 indices[0] >>= 4; 1017 indices[0] >>= 4;
986 indices[1] &= 0xf; 1018 indices[1] &= 0xf;
987 } 1019 }
988 1020
989 // Set the indicated number of pixels 1021 // Set the indicated number of pixels
990 for (int which = 0; x < endX; x++) { 1022 for (int which = 0; x < endX; x++) {
991 setRLEPixel(dstPtr, dstRowBytes, dstInfo, x, y, 1023 setRLEPixel(dst, dstRowBytes, dstInfo, x, y,
992 indices[which]); 1024 indices[which]);
993 which = !which; 1025 which = !which;
994 } 1026 }
995 } 1027 }
996 } 1028 }
997 } 1029 }
998 } 1030 }
999 1031
1000 /* 1032 /*
1001 * 1033 *
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 } 1103 }
1072 1104
1073 // FIXME: This code exists to match the behavior in the chromium decoder 1105 // FIXME: This code exists to match the behavior in the chromium decoder
1074 // and to follow the bmp specification as it relates to alpha masks. It is 1106 // and to follow the bmp specification as it relates to alpha masks. It is
1075 // commented out because we have yet to discover a test image that provides 1107 // commented out because we have yet to discover a test image that provides
1076 // an alpha mask and uses this decode mode. 1108 // an alpha mask and uses this decode mode.
1077 1109
1078 // Now we adjust the output image with some additional behavior that 1110 // Now we adjust the output image with some additional behavior that
1079 // SkSwizzler does not support. Firstly, all bmp images that contain 1111 // SkSwizzler does not support. Firstly, all bmp images that contain
1080 // alpha are masked by the alpha mask. Secondly, many fully transparent 1112 // alpha are masked by the alpha mask. Secondly, many fully transparent
1081 // bmp images are intended to be opaque. Here, we make those corrections. 1113 // bmp images are intended to be opaque. Here, we make those corrections
1114 // in the kN32 case.
1082 /* 1115 /*
1083 SkPMColor* dstRow = (SkPMColor*) dst; 1116 SkPMColor* dstRow = (SkPMColor*) dst;
1084 if (SkSwizzler::kBGRA == config) { 1117 if (SkSwizzler::kBGRA == config) {
1085 for (int y = 0; y < height; y++) { 1118 for (int y = 0; y < height; y++) {
1086 for (int x = 0; x < width; x++) { 1119 for (int x = 0; x < width; x++) {
1087 if (transparent) { 1120 if (transparent) {
1088 dstRow[x] |= 0xFF000000; 1121 dstRow[x] |= 0xFF000000;
1089 } else { 1122 } else {
1090 dstRow[x] &= alphaMask; 1123 dstRow[x] &= alphaMask;
1091 } 1124 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 uint32_t alphaBit = 1159 uint32_t alphaBit =
1127 (srcBuffer.get()[quotient] >> shift) & 0x1; 1160 (srcBuffer.get()[quotient] >> shift) & 0x1;
1128 dstRow[x] &= alphaBit - 1; 1161 dstRow[x] &= alphaBit - 1;
1129 } 1162 }
1130 } 1163 }
1131 } 1164 }
1132 1165
1133 // Finished decoding the entire image 1166 // Finished decoding the entire image
1134 return kSuccess; 1167 return kSuccess;
1135 } 1168 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698