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 "Resources.h" | 8 #include "Resources.h" |
9 #include "SkAndroidCodec.h" | 9 #include "SkAndroidCodec.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 if (!stream) { | 203 if (!stream) { |
204 SkDebugf("Missing resource '%s'\n", path); | 204 SkDebugf("Missing resource '%s'\n", path); |
205 return; | 205 return; |
206 } | 206 } |
207 | 207 |
208 SkAutoTDelete<SkCodec> codec(nullptr); | 208 SkAutoTDelete<SkCodec> codec(nullptr); |
209 bool isIncomplete = supportsIncomplete; | 209 bool isIncomplete = supportsIncomplete; |
210 if (isIncomplete) { | 210 if (isIncomplete) { |
211 size_t size = stream->getLength(); | 211 size_t size = stream->getLength(); |
212 sk_sp<SkData> data((SkData::MakeFromStream(stream, 2 * size / 3))); | 212 sk_sp<SkData> data((SkData::MakeFromStream(stream, 2 * size / 3))); |
213 codec.reset(SkCodec::NewFromData(data.get())); | 213 codec.reset(SkCodec::NewFromData(data)); |
214 } else { | 214 } else { |
215 codec.reset(SkCodec::NewFromStream(stream.release())); | 215 codec.reset(SkCodec::NewFromStream(stream.release())); |
216 } | 216 } |
217 if (!codec) { | 217 if (!codec) { |
218 ERRORF(r, "Unable to decode '%s'", path); | 218 ERRORF(r, "Unable to decode '%s'", path); |
219 return; | 219 return; |
220 } | 220 } |
221 | 221 |
222 // Test full image decodes with SkCodec | 222 // Test full image decodes with SkCodec |
223 SkMD5::Digest codecDigest; | 223 SkMD5::Digest codecDigest; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 SkAutoTDelete<SkStream> stream(resource(path)); | 332 SkAutoTDelete<SkStream> stream(resource(path)); |
333 if (!stream) { | 333 if (!stream) { |
334 SkDebugf("Missing resource '%s'\n", path); | 334 SkDebugf("Missing resource '%s'\n", path); |
335 return; | 335 return; |
336 } | 336 } |
337 | 337 |
338 SkAutoTDelete<SkAndroidCodec> androidCodec(nullptr); | 338 SkAutoTDelete<SkAndroidCodec> androidCodec(nullptr); |
339 if (isIncomplete) { | 339 if (isIncomplete) { |
340 size_t size = stream->getLength(); | 340 size_t size = stream->getLength(); |
341 sk_sp<SkData> data((SkData::MakeFromStream(stream, 2 * size / 3))); | 341 sk_sp<SkData> data((SkData::MakeFromStream(stream, 2 * size / 3))); |
342 androidCodec.reset(SkAndroidCodec::NewFromData(data.get())); | 342 androidCodec.reset(SkAndroidCodec::NewFromData(data)); |
343 } else { | 343 } else { |
344 androidCodec.reset(SkAndroidCodec::NewFromStream(stream.release())); | 344 androidCodec.reset(SkAndroidCodec::NewFromStream(stream.release())); |
345 } | 345 } |
346 if (!androidCodec) { | 346 if (!androidCodec) { |
347 ERRORF(r, "Unable to decode '%s'", path); | 347 ERRORF(r, "Unable to decode '%s'", path); |
348 return; | 348 return; |
349 } | 349 } |
350 | 350 |
351 SkBitmap bm; | 351 SkBitmap bm; |
352 SkMD5::Digest androidCodecDigest; | 352 SkMD5::Digest androidCodecDigest; |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 } | 817 } |
818 | 818 |
819 private: | 819 private: |
820 skiatest::Reporter* fReporter; // Unowned | 820 skiatest::Reporter* fReporter; // Unowned |
821 bool fSeen[3]; | 821 bool fSeen[3]; |
822 }; | 822 }; |
823 | 823 |
824 ChunkReader chunkReader(r); | 824 ChunkReader chunkReader(r); |
825 | 825 |
826 // Now read the file with SkCodec. | 826 // Now read the file with SkCodec. |
827 sk_sp<SkData> data(wStream.copyToData()); | 827 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(wStream.detachAsData(), &c
hunkReader)); |
828 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data.get(), &chunkReader))
; | |
829 REPORTER_ASSERT(r, codec); | 828 REPORTER_ASSERT(r, codec); |
830 if (!codec) { | 829 if (!codec) { |
831 return; | 830 return; |
832 } | 831 } |
833 | 832 |
834 // Now compare to the original. | 833 // Now compare to the original. |
835 SkBitmap decodedBm; | 834 SkBitmap decodedBm; |
836 decodedBm.setInfo(codec->getInfo()); | 835 decodedBm.setInfo(codec->getInfo()); |
837 decodedBm.allocPixels(); | 836 decodedBm.allocPixels(); |
838 SkCodec::Result result = codec->getPixels(codec->getInfo(), decodedBm.getPix
els(), | 837 SkCodec::Result result = codec->getPixels(codec->getInfo(), decodedBm.getPix
els(), |
(...skipping 19 matching lines...) Expand all Loading... |
858 REPORTER_ASSERT(r, !chunkReader.allHaveBeenSeen()); | 857 REPORTER_ASSERT(r, !chunkReader.allHaveBeenSeen()); |
859 result = codec->getPixels(codec->getInfo(), decodedBm.getPixels(), decodedBm
.rowBytes()); | 858 result = codec->getPixels(codec->getInfo(), decodedBm.getPixels(), decodedBm
.rowBytes()); |
860 REPORTER_ASSERT(r, SkCodec::kSuccess == result); | 859 REPORTER_ASSERT(r, SkCodec::kSuccess == result); |
861 REPORTER_ASSERT(r, chunkReader.allHaveBeenSeen()); | 860 REPORTER_ASSERT(r, chunkReader.allHaveBeenSeen()); |
862 } | 861 } |
863 #endif // PNG_READ_UNKNOWN_CHUNKS_SUPPORTED | 862 #endif // PNG_READ_UNKNOWN_CHUNKS_SUPPORTED |
864 | 863 |
865 // Stream that can only peek up to a limit | 864 // Stream that can only peek up to a limit |
866 class LimitedPeekingMemStream : public SkStream { | 865 class LimitedPeekingMemStream : public SkStream { |
867 public: | 866 public: |
868 LimitedPeekingMemStream(SkData* data, size_t limit) | 867 LimitedPeekingMemStream(sk_sp<SkData> data, size_t limit) |
869 : fStream(data) | 868 : fStream(std::move(data)) |
870 , fLimit(limit) {} | 869 , fLimit(limit) {} |
871 | 870 |
872 size_t peek(void* buf, size_t bytes) const override { | 871 size_t peek(void* buf, size_t bytes) const override { |
873 return fStream.peek(buf, SkTMin(bytes, fLimit)); | 872 return fStream.peek(buf, SkTMin(bytes, fLimit)); |
874 } | 873 } |
875 size_t read(void* buf, size_t bytes) override { | 874 size_t read(void* buf, size_t bytes) override { |
876 return fStream.read(buf, bytes); | 875 return fStream.read(buf, bytes); |
877 } | 876 } |
878 bool rewind() override { | 877 bool rewind() override { |
879 return fStream.rewind(); | 878 return fStream.rewind(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 const char* path = "baby_tux.webp"; | 940 const char* path = "baby_tux.webp"; |
942 SkString fullPath(GetResourcePath(path)); | 941 SkString fullPath(GetResourcePath(path)); |
943 auto data = SkData::MakeFromFileName(fullPath.c_str()); | 942 auto data = SkData::MakeFromFileName(fullPath.c_str()); |
944 if (!data) { | 943 if (!data) { |
945 SkDebugf("Missing resource '%s'\n", path); | 944 SkDebugf("Missing resource '%s'\n", path); |
946 return; | 945 return; |
947 } | 946 } |
948 | 947 |
949 // The limit is less than webp needs to peek or read. | 948 // The limit is less than webp needs to peek or read. |
950 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream( | 949 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream( |
951 new LimitedPeekingMemStream(data.get(), 25))); | 950 new LimitedPeekingMemStream(data, 25))); |
952 REPORTER_ASSERT(r, codec); | 951 REPORTER_ASSERT(r, codec); |
953 | 952 |
954 test_info(r, codec.get(), codec->getInfo(), SkCodec::kSuccess, nullptr); | 953 test_info(r, codec.get(), codec->getInfo(), SkCodec::kSuccess, nullptr); |
955 | 954 |
956 // Similarly, a stream which does not peek should still succeed. | 955 // Similarly, a stream which does not peek should still succeed. |
957 codec.reset(SkCodec::NewFromStream(new LimitedPeekingMemStream(data.get(), 0
))); | 956 codec.reset(SkCodec::NewFromStream(new LimitedPeekingMemStream(data, 0))); |
958 REPORTER_ASSERT(r, codec); | 957 REPORTER_ASSERT(r, codec); |
959 | 958 |
960 test_info(r, codec.get(), codec->getInfo(), SkCodec::kSuccess, nullptr); | 959 test_info(r, codec.get(), codec->getInfo(), SkCodec::kSuccess, nullptr); |
961 } | 960 } |
962 | 961 |
963 // SkCodec's wbmp decoder was initially unnecessarily restrictive. | 962 // SkCodec's wbmp decoder was initially unnecessarily restrictive. |
964 // It required the second byte to be zero. The wbmp specification allows | 963 // It required the second byte to be zero. The wbmp specification allows |
965 // a couple of bits to be 1 (so long as they do not overlap with 0x9F). | 964 // a couple of bits to be 1 (so long as they do not overlap with 0x9F). |
966 // Test that SkCodec now supports an image with these bits set. | 965 // Test that SkCodec now supports an image with these bits set. |
967 DEF_TEST(Codec_wbmp, r) { | 966 DEF_TEST(Codec_wbmp, r) { |
968 const char* path = "mandrill.wbmp"; | 967 const char* path = "mandrill.wbmp"; |
969 SkAutoTDelete<SkStream> stream(resource(path)); | 968 SkAutoTDelete<SkStream> stream(resource(path)); |
970 if (!stream) { | 969 if (!stream) { |
971 SkDebugf("Missing resource '%s'\n", path); | 970 SkDebugf("Missing resource '%s'\n", path); |
972 return; | 971 return; |
973 } | 972 } |
974 | 973 |
975 // Modify the stream to contain a second byte with some bits set. | 974 // Modify the stream to contain a second byte with some bits set. |
976 auto data = SkCopyStreamToData(stream); | 975 auto data = SkCopyStreamToData(stream); |
977 uint8_t* writeableData = static_cast<uint8_t*>(data->writable_data()); | 976 uint8_t* writeableData = static_cast<uint8_t*>(data->writable_data()); |
978 writeableData[1] = static_cast<uint8_t>(~0x9F); | 977 writeableData[1] = static_cast<uint8_t>(~0x9F); |
979 | 978 |
980 // SkCodec should support this. | 979 // SkCodec should support this. |
981 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data.get())); | 980 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data)); |
982 REPORTER_ASSERT(r, codec); | 981 REPORTER_ASSERT(r, codec); |
983 if (!codec) { | 982 if (!codec) { |
984 return; | 983 return; |
985 } | 984 } |
986 test_info(r, codec.get(), codec->getInfo(), SkCodec::kSuccess, nullptr); | 985 test_info(r, codec.get(), codec->getInfo(), SkCodec::kSuccess, nullptr); |
987 } | 986 } |
988 | 987 |
989 // wbmp images have a header that can be arbitrarily large, depending on the | 988 // wbmp images have a header that can be arbitrarily large, depending on the |
990 // size of the image. We cap the size at 65535, meaning we only need to look at | 989 // size of the image. We cap the size at 65535, meaning we only need to look at |
991 // 8 bytes to determine whether we can read the image. This is important | 990 // 8 bytes to determine whether we can read the image. This is important |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 | 1075 |
1077 static void check_round_trip(skiatest::Reporter* r, const SkBitmap& bm1) { | 1076 static void check_round_trip(skiatest::Reporter* r, const SkBitmap& bm1) { |
1078 SkColorType origColorType = bm1.colorType(); | 1077 SkColorType origColorType = bm1.colorType(); |
1079 SkAlphaType origAlphaType = bm1.alphaType(); | 1078 SkAlphaType origAlphaType = bm1.alphaType(); |
1080 | 1079 |
1081 // Encode the image to png. | 1080 // Encode the image to png. |
1082 sk_sp<SkData> data = | 1081 sk_sp<SkData> data = |
1083 sk_sp<SkData>(SkImageEncoder::EncodeData(bm1, SkImageEncoder::kPNG_T
ype, 100)); | 1082 sk_sp<SkData>(SkImageEncoder::EncodeData(bm1, SkImageEncoder::kPNG_T
ype, 100)); |
1084 | 1083 |
1085 // Prepare to decode. The codec should recognize that the PNG is 565. | 1084 // Prepare to decode. The codec should recognize that the PNG is 565. |
1086 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data.get())); | 1085 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data)); |
1087 REPORTER_ASSERT(r, origColorType == codec->getInfo().colorType()); | 1086 REPORTER_ASSERT(r, origColorType == codec->getInfo().colorType()); |
1088 REPORTER_ASSERT(r, origAlphaType == codec->getInfo().alphaType()); | 1087 REPORTER_ASSERT(r, origAlphaType == codec->getInfo().alphaType()); |
1089 | 1088 |
1090 SkBitmap bm2; | 1089 SkBitmap bm2; |
1091 bm2.allocPixels(codec->getInfo()); | 1090 bm2.allocPixels(codec->getInfo()); |
1092 SkCodec::Result result = codec->getPixels(codec->getInfo(), bm2.getPixels(),
bm2.rowBytes()); | 1091 SkCodec::Result result = codec->getPixels(codec->getInfo(), bm2.getPixels(),
bm2.rowBytes()); |
1093 REPORTER_ASSERT(r, SkCodec::kSuccess == result); | 1092 REPORTER_ASSERT(r, SkCodec::kSuccess == result); |
1094 | 1093 |
1095 SkMD5::Digest d1, d2; | 1094 SkMD5::Digest d1, d2; |
1096 md5(bm1, &d1); | 1095 md5(bm1, &d1); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 result = codec->startScanlineDecode(infoF16); | 1142 result = codec->startScanlineDecode(infoF16); |
1144 REPORTER_ASSERT(r, SkCodec::kSuccess == result); | 1143 REPORTER_ASSERT(r, SkCodec::kSuccess == result); |
1145 } | 1144 } |
1146 } | 1145 } |
1147 | 1146 |
1148 DEF_TEST(Codec_F16ConversionPossible, r) { | 1147 DEF_TEST(Codec_F16ConversionPossible, r) { |
1149 test_conversion_possible(r, "color_wheel.webp", false); | 1148 test_conversion_possible(r, "color_wheel.webp", false); |
1150 test_conversion_possible(r, "mandrill_512_q075.jpg", true); | 1149 test_conversion_possible(r, "mandrill_512_q075.jpg", true); |
1151 test_conversion_possible(r, "yellow_rose.png", true); | 1150 test_conversion_possible(r, "yellow_rose.png", true); |
1152 } | 1151 } |
OLD | NEW |