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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 return; | 164 return; |
165 } | 165 } |
166 | 166 |
167 SkAutoTDelete<SkCodec> codec(nullptr); | 167 SkAutoTDelete<SkCodec> codec(nullptr); |
168 bool isIncomplete = supportsIncomplete; | 168 bool isIncomplete = supportsIncomplete; |
169 if (isIncomplete) { | 169 if (isIncomplete) { |
170 size_t size = stream->getLength(); | 170 size_t size = stream->getLength(); |
171 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3)))
; | 171 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3)))
; |
172 codec.reset(SkCodec::NewFromData(data)); | 172 codec.reset(SkCodec::NewFromData(data)); |
173 } else { | 173 } else { |
174 codec.reset(SkCodec::NewFromStream(stream.detach())); | 174 codec.reset(SkCodec::NewFromStream(stream.release())); |
175 } | 175 } |
176 if (!codec) { | 176 if (!codec) { |
177 ERRORF(r, "Unable to decode '%s'", path); | 177 ERRORF(r, "Unable to decode '%s'", path); |
178 return; | 178 return; |
179 } | 179 } |
180 | 180 |
181 // Test full image decodes with SkCodec | 181 // Test full image decodes with SkCodec |
182 SkMD5::Digest codecDigest; | 182 SkMD5::Digest codecDigest; |
183 const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); | 183 const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); |
184 SkBitmap bm; | 184 SkBitmap bm; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 SkDebugf("Missing resource '%s'\n", path); | 293 SkDebugf("Missing resource '%s'\n", path); |
294 return; | 294 return; |
295 } | 295 } |
296 | 296 |
297 SkAutoTDelete<SkAndroidCodec> androidCodec(nullptr); | 297 SkAutoTDelete<SkAndroidCodec> androidCodec(nullptr); |
298 if (isIncomplete) { | 298 if (isIncomplete) { |
299 size_t size = stream->getLength(); | 299 size_t size = stream->getLength(); |
300 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size /
3))); | 300 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size /
3))); |
301 androidCodec.reset(SkAndroidCodec::NewFromData(data)); | 301 androidCodec.reset(SkAndroidCodec::NewFromData(data)); |
302 } else { | 302 } else { |
303 androidCodec.reset(SkAndroidCodec::NewFromStream(stream.detach())); | 303 androidCodec.reset(SkAndroidCodec::NewFromStream(stream.release())); |
304 } | 304 } |
305 if (!androidCodec) { | 305 if (!androidCodec) { |
306 ERRORF(r, "Unable to decode '%s'", path); | 306 ERRORF(r, "Unable to decode '%s'", path); |
307 return; | 307 return; |
308 } | 308 } |
309 | 309 |
310 SkBitmap bm; | 310 SkBitmap bm; |
311 SkMD5::Digest androidCodecDigest; | 311 SkMD5::Digest androidCodecDigest; |
312 test_codec(r, androidCodec.get(), bm, info, size, expectedResult, &andro
idCodecDigest, | 312 test_codec(r, androidCodec.get(), bm, info, size, expectedResult, &andro
idCodecDigest, |
313 &codecDigest); | 313 &codecDigest); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 } | 405 } |
406 | 406 |
407 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode | 407 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode |
408 DEF_TEST(Codec_stripes, r) { | 408 DEF_TEST(Codec_stripes, r) { |
409 const char * path = "plane_interlaced.png"; | 409 const char * path = "plane_interlaced.png"; |
410 SkAutoTDelete<SkStream> stream(resource(path)); | 410 SkAutoTDelete<SkStream> stream(resource(path)); |
411 if (!stream) { | 411 if (!stream) { |
412 SkDebugf("Missing resource '%s'\n", path); | 412 SkDebugf("Missing resource '%s'\n", path); |
413 } | 413 } |
414 | 414 |
415 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); | 415 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.release())); |
416 REPORTER_ASSERT(r, codec); | 416 REPORTER_ASSERT(r, codec); |
417 | 417 |
418 if (!codec) { | 418 if (!codec) { |
419 return; | 419 return; |
420 } | 420 } |
421 | 421 |
422 switch (codec->getScanlineOrder()) { | 422 switch (codec->getScanlineOrder()) { |
423 case SkCodec::kBottomUp_SkScanlineOrder: | 423 case SkCodec::kBottomUp_SkScanlineOrder: |
424 case SkCodec::kOutOfOrder_SkScanlineOrder: | 424 case SkCodec::kOutOfOrder_SkScanlineOrder: |
425 ERRORF(r, "This scanline order will not match the original."); | 425 ERRORF(r, "This scanline order will not match the original."); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 REPORTER_ASSERT(r, !androidCodec); | 538 REPORTER_ASSERT(r, !androidCodec); |
539 } | 539 } |
540 | 540 |
541 static void test_dimensions(skiatest::Reporter* r, const char path[]) { | 541 static void test_dimensions(skiatest::Reporter* r, const char path[]) { |
542 // Create the codec from the resource file | 542 // Create the codec from the resource file |
543 SkAutoTDelete<SkStream> stream(resource(path)); | 543 SkAutoTDelete<SkStream> stream(resource(path)); |
544 if (!stream) { | 544 if (!stream) { |
545 SkDebugf("Missing resource '%s'\n", path); | 545 SkDebugf("Missing resource '%s'\n", path); |
546 return; | 546 return; |
547 } | 547 } |
548 SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(stream.det
ach())); | 548 SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(stream.rel
ease())); |
549 if (!codec) { | 549 if (!codec) { |
550 ERRORF(r, "Unable to create codec '%s'", path); | 550 ERRORF(r, "Unable to create codec '%s'", path); |
551 return; | 551 return; |
552 } | 552 } |
553 | 553 |
554 // Check that the decode is successful for a variety of scales | 554 // Check that the decode is successful for a variety of scales |
555 for (int sampleSize = 1; sampleSize < 32; sampleSize++) { | 555 for (int sampleSize = 1; sampleSize < 32; sampleSize++) { |
556 // Scale the output dimensions | 556 // Scale the output dimensions |
557 SkISize scaledDims = codec->getSampledDimensions(sampleSize); | 557 SkISize scaledDims = codec->getSampledDimensions(sampleSize); |
558 SkImageInfo scaledInfo = codec->getInfo() | 558 SkImageInfo scaledInfo = codec->getInfo() |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 test_dimensions(r, "dng_with_preview.dng"); | 603 test_dimensions(r, "dng_with_preview.dng"); |
604 #endif | 604 #endif |
605 } | 605 } |
606 | 606 |
607 static void test_invalid(skiatest::Reporter* r, const char path[]) { | 607 static void test_invalid(skiatest::Reporter* r, const char path[]) { |
608 SkAutoTDelete<SkStream> stream(resource(path)); | 608 SkAutoTDelete<SkStream> stream(resource(path)); |
609 if (!stream) { | 609 if (!stream) { |
610 SkDebugf("Missing resource '%s'\n", path); | 610 SkDebugf("Missing resource '%s'\n", path); |
611 return; | 611 return; |
612 } | 612 } |
613 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); | 613 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.release())); |
614 REPORTER_ASSERT(r, nullptr == codec); | 614 REPORTER_ASSERT(r, nullptr == codec); |
615 } | 615 } |
616 | 616 |
617 DEF_TEST(Codec_Empty, r) { | 617 DEF_TEST(Codec_Empty, r) { |
618 // Test images that should not be able to create a codec | 618 // Test images that should not be able to create a codec |
619 test_invalid(r, "empty_images/zero-dims.gif"); | 619 test_invalid(r, "empty_images/zero-dims.gif"); |
620 test_invalid(r, "empty_images/zero-embedded.ico"); | 620 test_invalid(r, "empty_images/zero-embedded.ico"); |
621 test_invalid(r, "empty_images/zero-width.bmp"); | 621 test_invalid(r, "empty_images/zero-width.bmp"); |
622 test_invalid(r, "empty_images/zero-height.bmp"); | 622 test_invalid(r, "empty_images/zero-height.bmp"); |
623 test_invalid(r, "empty_images/zero-width.jpg"); | 623 test_invalid(r, "empty_images/zero-width.jpg"); |
624 test_invalid(r, "empty_images/zero-height.jpg"); | 624 test_invalid(r, "empty_images/zero-height.jpg"); |
625 test_invalid(r, "empty_images/zero-width.png"); | 625 test_invalid(r, "empty_images/zero-width.png"); |
626 test_invalid(r, "empty_images/zero-height.png"); | 626 test_invalid(r, "empty_images/zero-height.png"); |
627 test_invalid(r, "empty_images/zero-width.wbmp"); | 627 test_invalid(r, "empty_images/zero-width.wbmp"); |
628 test_invalid(r, "empty_images/zero-height.wbmp"); | 628 test_invalid(r, "empty_images/zero-height.wbmp"); |
629 // This image is an ico with an embedded mask-bmp. This is illegal. | 629 // This image is an ico with an embedded mask-bmp. This is illegal. |
630 test_invalid(r, "invalid_images/mask-bmp-ico.ico"); | 630 test_invalid(r, "invalid_images/mask-bmp-ico.ico"); |
631 } | 631 } |
632 | 632 |
633 static void test_invalid_parameters(skiatest::Reporter* r, const char path[]) { | 633 static void test_invalid_parameters(skiatest::Reporter* r, const char path[]) { |
634 SkAutoTDelete<SkStream> stream(resource(path)); | 634 SkAutoTDelete<SkStream> stream(resource(path)); |
635 if (!stream) { | 635 if (!stream) { |
636 SkDebugf("Missing resource '%s'\n", path); | 636 SkDebugf("Missing resource '%s'\n", path); |
637 return; | 637 return; |
638 } | 638 } |
639 SkAutoTDelete<SkCodec> decoder(SkCodec::NewFromStream(stream.detach())); | 639 SkAutoTDelete<SkCodec> decoder(SkCodec::NewFromStream(stream.release())); |
640 | 640 |
641 // This should return kSuccess because kIndex8 is supported. | 641 // This should return kSuccess because kIndex8 is supported. |
642 SkPMColor colorStorage[256]; | 642 SkPMColor colorStorage[256]; |
643 int colorCount; | 643 int colorCount; |
644 SkCodec::Result result = decoder->startScanlineDecode( | 644 SkCodec::Result result = decoder->startScanlineDecode( |
645 decoder->getInfo().makeColorType(kIndex_8_SkColorType), nullptr, colorSt
orage, &colorCount); | 645 decoder->getInfo().makeColorType(kIndex_8_SkColorType), nullptr, colorSt
orage, &colorCount); |
646 REPORTER_ASSERT(r, SkCodec::kSuccess == result); | 646 REPORTER_ASSERT(r, SkCodec::kSuccess == result); |
647 // The rest of the test is uninteresting if kIndex8 is not supported | 647 // The rest of the test is uninteresting if kIndex8 is not supported |
648 if (SkCodec::kSuccess != result) { | 648 if (SkCodec::kSuccess != result) { |
649 return; | 649 return; |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 // wbmp images have a header that can be arbitrarily large, depending on the | 947 // wbmp images have a header that can be arbitrarily large, depending on the |
948 // size of the image. We cap the size at 65535, meaning we only need to look at | 948 // size of the image. We cap the size at 65535, meaning we only need to look at |
949 // 8 bytes to determine whether we can read the image. This is important | 949 // 8 bytes to determine whether we can read the image. This is important |
950 // because SkCodec only passes 14 bytes to SkWbmpCodec to determine whether the | 950 // because SkCodec only passes 14 bytes to SkWbmpCodec to determine whether the |
951 // image is a wbmp. | 951 // image is a wbmp. |
952 DEF_TEST(Codec_wbmp_max_size, r) { | 952 DEF_TEST(Codec_wbmp_max_size, r) { |
953 const unsigned char maxSizeWbmp[] = { 0x00, 0x00, // Header | 953 const unsigned char maxSizeWbmp[] = { 0x00, 0x00, // Header |
954 0x83, 0xFF, 0x7F, // W: 65535 | 954 0x83, 0xFF, 0x7F, // W: 65535 |
955 0x83, 0xFF, 0x7F }; // H: 65535 | 955 0x83, 0xFF, 0x7F }; // H: 65535 |
956 SkAutoTDelete<SkStream> stream(new SkMemoryStream(maxSizeWbmp, sizeof(maxSiz
eWbmp), false)); | 956 SkAutoTDelete<SkStream> stream(new SkMemoryStream(maxSizeWbmp, sizeof(maxSiz
eWbmp), false)); |
957 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); | 957 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.release())); |
958 | 958 |
959 REPORTER_ASSERT(r, codec); | 959 REPORTER_ASSERT(r, codec); |
960 if (!codec) return; | 960 if (!codec) return; |
961 | 961 |
962 REPORTER_ASSERT(r, codec->getInfo().width() == 65535); | 962 REPORTER_ASSERT(r, codec->getInfo().width() == 65535); |
963 REPORTER_ASSERT(r, codec->getInfo().height() == 65535); | 963 REPORTER_ASSERT(r, codec->getInfo().height() == 65535); |
964 | 964 |
965 // Now test an image which is too big. Any image with a larger header (i.e. | 965 // Now test an image which is too big. Any image with a larger header (i.e. |
966 // has bigger width/height) is also too big. | 966 // has bigger width/height) is also too big. |
967 const unsigned char tooBigWbmp[] = { 0x00, 0x00, // Header | 967 const unsigned char tooBigWbmp[] = { 0x00, 0x00, // Header |
968 0x84, 0x80, 0x00, // W: 65536 | 968 0x84, 0x80, 0x00, // W: 65536 |
969 0x84, 0x80, 0x00 }; // H: 65536 | 969 0x84, 0x80, 0x00 }; // H: 65536 |
970 stream.reset(new SkMemoryStream(tooBigWbmp, sizeof(tooBigWbmp), false)); | 970 stream.reset(new SkMemoryStream(tooBigWbmp, sizeof(tooBigWbmp), false)); |
971 codec.reset(SkCodec::NewFromStream(stream.detach())); | 971 codec.reset(SkCodec::NewFromStream(stream.release())); |
972 | 972 |
973 REPORTER_ASSERT(r, !codec); | 973 REPORTER_ASSERT(r, !codec); |
974 } | 974 } |
OLD | NEW |