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 "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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |