| 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 |