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 "DMSrcSink.h" | 8 #include "DMSrcSink.h" |
9 #include "SkAndroidCodec.h" | 9 #include "SkAndroidCodec.h" |
10 #include "SkCodec.h" | 10 #include "SkCodec.h" |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 | 635 |
636 Name CodecSrc::name() const { | 636 Name CodecSrc::name() const { |
637 if (1.0f == fScale) { | 637 if (1.0f == fScale) { |
638 return SkOSPath::Basename(fPath.c_str()); | 638 return SkOSPath::Basename(fPath.c_str()); |
639 } | 639 } |
640 return get_scaled_name(fPath, fScale); | 640 return get_scaled_name(fPath, fScale); |
641 } | 641 } |
642 | 642 |
643 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 643 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
644 | 644 |
645 AndroidCodecSrc::AndroidCodecSrc(Path path, Mode mode, CodecSrc::DstColorType ds
tColorType, | 645 AndroidCodecSrc::AndroidCodecSrc(Path path, CodecSrc::DstColorType dstColorType, |
646 SkAlphaType dstAlphaType, int sampleSize) | 646 SkAlphaType dstAlphaType, int sampleSize) |
647 : fPath(path) | 647 : fPath(path) |
648 , fMode(mode) | |
649 , fDstColorType(dstColorType) | 648 , fDstColorType(dstColorType) |
650 , fDstAlphaType(dstAlphaType) | 649 , fDstAlphaType(dstAlphaType) |
651 , fSampleSize(sampleSize) | 650 , fSampleSize(sampleSize) |
652 , fRunSerially(serial_from_path_name(path)) | 651 , fRunSerially(serial_from_path_name(path)) |
653 {} | 652 {} |
654 | 653 |
655 bool AndroidCodecSrc::veto(SinkFlags flags) const { | 654 bool AndroidCodecSrc::veto(SinkFlags flags) const { |
656 // No need to test decoding to non-raster or indirect backend. | 655 // No need to test decoding to non-raster or indirect backend. |
657 return flags.type != SinkFlags::kRaster | 656 return flags.type != SinkFlags::kRaster |
658 || flags.approach != SinkFlags::kDirect; | 657 || flags.approach != SinkFlags::kDirect; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), | 704 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), |
706 decodeInfo.width(), decodeInfo.height()); | 705 decodeInfo.width(), decodeInfo.height()); |
707 } | 706 } |
708 | 707 |
709 // Create options for the codec. | 708 // Create options for the codec. |
710 SkAndroidCodec::AndroidOptions options; | 709 SkAndroidCodec::AndroidOptions options; |
711 options.fColorPtr = colorPtr; | 710 options.fColorPtr = colorPtr; |
712 options.fColorCount = colorCountPtr; | 711 options.fColorCount = colorCountPtr; |
713 options.fSampleSize = fSampleSize; | 712 options.fSampleSize = fSampleSize; |
714 | 713 |
715 switch (fMode) { | 714 switch (codec->getAndroidPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBy
tes(), &options)) { |
716 case kFullImage_Mode: { | 715 case SkCodec::kSuccess: |
717 switch (codec->getAndroidPixels(decodeInfo, bitmap.getPixels(), bitm
ap.rowBytes(), | 716 case SkCodec::kIncompleteInput: |
718 &options)) { | 717 break; |
719 case SkCodec::kSuccess: | |
720 case SkCodec::kIncompleteInput: | |
721 break; | |
722 default: | |
723 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str(
)); | |
724 } | |
725 premultiply_if_necessary(bitmap); | |
726 swap_rb_if_necessary(bitmap, fDstColorType); | |
727 canvas->drawBitmap(bitmap, 0, 0); | |
728 return ""; | |
729 } | |
730 case kDivisor_Mode: { | |
731 const int width = codec->getInfo().width(); | |
732 const int height = codec->getInfo().height(); | |
733 const int divisor = 2; | |
734 if (width < divisor || height < divisor) { | |
735 return Error::Nonfatal("Divisor is larger than image dimension."
); | |
736 } | |
737 | |
738 // Keep track of the final decoded dimensions. | |
739 int finalScaledWidth = 0; | |
740 int finalScaledHeight = 0; | |
741 for (int x = 0; x < divisor; x++) { | |
742 for (int y = 0; y < divisor; y++) { | |
743 // Calculate the subset dimensions | |
744 int subsetWidth = width / divisor; | |
745 int subsetHeight = height / divisor; | |
746 const int left = x * subsetWidth; | |
747 const int top = y * subsetHeight; | |
748 | |
749 // Increase the size of the last subset in each row or colum
n, when the | |
750 // divisor does not divide evenly into the image dimensions | |
751 subsetWidth += (x + 1 == divisor) ? (width % divisor) : 0; | |
752 subsetHeight += (y + 1 == divisor) ? (height % divisor) : 0; | |
753 SkIRect subset = SkIRect::MakeXYWH(left, top, subsetWidth, s
ubsetHeight); | |
754 if (!codec->getSupportedSubset(&subset)) { | |
755 return "Could not get supported subset to decode."; | |
756 } | |
757 options.fSubset = ⊂ | |
758 const int scaledWidthOffset = subset.left() / fSampleSize; | |
759 const int scaledHeightOffset = subset.top() / fSampleSize; | |
760 void* pixels = bitmap.getAddr(scaledWidthOffset, scaledHeigh
tOffset); | |
761 SkISize scaledSubsetSize = codec->getSampledSubsetDimensions
(fSampleSize, | |
762 subset); | |
763 SkImageInfo subsetDecodeInfo = decodeInfo.makeWH(scaledSubse
tSize.width(), | |
764 scaledSubsetSize.height()); | |
765 | |
766 if (x + 1 == divisor && y + 1 == divisor) { | |
767 finalScaledWidth = scaledWidthOffset + scaledSubsetSize.
width(); | |
768 finalScaledHeight = scaledHeightOffset + scaledSubsetSiz
e.height(); | |
769 } | |
770 | |
771 switch (codec->getAndroidPixels(subsetDecodeInfo, pixels, bi
tmap.rowBytes(), | |
772 &options)) { | |
773 case SkCodec::kSuccess: | |
774 case SkCodec::kIncompleteInput: | |
775 break; | |
776 default: | |
777 return SkStringPrintf("Couldn't getPixels %s.", fPat
h.c_str()); | |
778 } | |
779 } | |
780 } | |
781 | |
782 SkRect rect = SkRect::MakeXYWH(0, 0, (SkScalar) finalScaledWidth, | |
783 (SkScalar) finalScaledHeight); | |
784 premultiply_if_necessary(bitmap); | |
785 swap_rb_if_necessary(bitmap, fDstColorType); | |
786 canvas->drawBitmapRect(bitmap, rect, rect, nullptr); | |
787 return ""; | |
788 } | |
789 default: | 718 default: |
790 SkASSERT(false); | 719 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str()); |
791 return "Error: Should not be reached."; | |
792 } | 720 } |
| 721 premultiply_if_necessary(bitmap); |
| 722 swap_rb_if_necessary(bitmap, fDstColorType); |
| 723 canvas->drawBitmap(bitmap, 0, 0); |
| 724 return ""; |
793 } | 725 } |
794 | 726 |
795 SkISize AndroidCodecSrc::size() const { | 727 SkISize AndroidCodecSrc::size() const { |
796 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 728 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
797 SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromData(encoded)); | 729 SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromData(encoded)); |
798 if (nullptr == codec) { | 730 if (nullptr == codec) { |
799 return SkISize::Make(0, 0); | 731 return SkISize::Make(0, 0); |
800 } | 732 } |
801 return codec->getSampledDimensions(fSampleSize); | 733 return codec->getSampledDimensions(fSampleSize); |
802 } | 734 } |
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 skr.visit(i, drawsAsSingletonPictures); | 1495 skr.visit(i, drawsAsSingletonPictures); |
1564 } | 1496 } |
1565 sk_sp<SkPicture> macroPic(macroRec.finishRecordingAsPicture()); | 1497 sk_sp<SkPicture> macroPic(macroRec.finishRecordingAsPicture()); |
1566 | 1498 |
1567 canvas->drawPicture(macroPic); | 1499 canvas->drawPicture(macroPic); |
1568 return check_against_reference(bitmap, src, fSink); | 1500 return check_against_reference(bitmap, src, fSink); |
1569 }); | 1501 }); |
1570 } | 1502 } |
1571 | 1503 |
1572 } // namespace DM | 1504 } // namespace DM |
OLD | NEW |