| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 rect.fLeft = rand->nextRangeU(0, w); | 83 rect.fLeft = rand->nextRangeU(0, w); |
| 84 rect.fTop = rand->nextRangeU(0, h); | 84 rect.fTop = rand->nextRangeU(0, h); |
| 85 rect.fRight = rand->nextRangeU(0, w); | 85 rect.fRight = rand->nextRangeU(0, w); |
| 86 rect.fBottom = rand->nextRangeU(0, h); | 86 rect.fBottom = rand->nextRangeU(0, h); |
| 87 rect.sort(); | 87 rect.sort(); |
| 88 } while (rect.isEmpty()); | 88 } while (rect.isEmpty()); |
| 89 return rect; | 89 return rect; |
| 90 } | 90 } |
| 91 | 91 |
| 92 static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, cons
t SkImageInfo& info, | 92 static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, cons
t SkImageInfo& info, |
| 93 const SkISize& size, bool supports565, SkCodec::Result expectedResult, | 93 const SkISize& size, SkCodec::Result expectedResult, SkMD5::Digest* dige
st, |
| 94 SkMD5::Digest* digest, const SkMD5::Digest* goodDigest) { | 94 const SkMD5::Digest* goodDigest) { |
| 95 | 95 |
| 96 REPORTER_ASSERT(r, info.dimensions() == size); | 96 REPORTER_ASSERT(r, info.dimensions() == size); |
| 97 bm.allocPixels(info); | 97 bm.allocPixels(info); |
| 98 SkAutoLockPixels autoLockPixels(bm); | 98 SkAutoLockPixels autoLockPixels(bm); |
| 99 | 99 |
| 100 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes(
)); | 100 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes(
)); |
| 101 REPORTER_ASSERT(r, result == expectedResult); | 101 REPORTER_ASSERT(r, result == expectedResult); |
| 102 | 102 |
| 103 md5(bm, digest); | 103 md5(bm, digest); |
| 104 if (goodDigest) { | 104 if (goodDigest) { |
| 105 REPORTER_ASSERT(r, *digest == *goodDigest); | 105 REPORTER_ASSERT(r, *digest == *goodDigest); |
| 106 } | 106 } |
| 107 | 107 |
| 108 { | 108 { |
| 109 // Test decoding to 565 | 109 // Test decoding to 565 |
| 110 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType); | 110 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType); |
| 111 SkCodec::Result expected565 = (supports565 && info.alphaType() == kOpaqu
e_SkAlphaType) ? | 111 SkCodec::Result expected565 = info.alphaType() == kOpaque_SkAlphaType ? |
| 112 expectedResult : SkCodec::kInvalidConversion; | 112 expectedResult : SkCodec::kInvalidConversion; |
| 113 test_info(r, codec, info565, expected565, nullptr); | 113 test_info(r, codec, info565, expected565, nullptr); |
| 114 } | 114 } |
| 115 | 115 |
| 116 // Verify that re-decoding gives the same result. It is interesting to chec
k this after | 116 // Verify that re-decoding gives the same result. It is interesting to chec
k this after |
| 117 // a decode to 565, since choosing to decode to 565 may result in some of th
e decode | 117 // a decode to 565, since choosing to decode to 565 may result in some of th
e decode |
| 118 // options being modified. These options should return to their defaults on
another | 118 // options being modified. These options should return to their defaults on
another |
| 119 // decode to kN32, so the new digest should match the old digest. | 119 // decode to kN32, so the new digest should match the old digest. |
| 120 test_info(r, codec, info, expectedResult, digest); | 120 test_info(r, codec, info, expectedResult, digest); |
| 121 | 121 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 136 } else { | 136 } else { |
| 137 otherAt = kPremul_SkAlphaType; | 137 otherAt = kPremul_SkAlphaType; |
| 138 } | 138 } |
| 139 // The other non-opaque alpha type should always succeed, but not ma
tch. | 139 // The other non-opaque alpha type should always succeed, but not ma
tch. |
| 140 test_info(r, codec, info.makeAlphaType(otherAt), expectedResult, nul
lptr); | 140 test_info(r, codec, info.makeAlphaType(otherAt), expectedResult, nul
lptr); |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 } | 143 } |
| 144 | 144 |
| 145 static void test_android_codec(skiatest::Reporter* r, SkAndroidCodec* codec, SkB
itmap& bm, | 145 static void test_android_codec(skiatest::Reporter* r, SkAndroidCodec* codec, SkB
itmap& bm, |
| 146 const SkImageInfo& info, const SkISize& size, bool supports565, | 146 const SkImageInfo& info, const SkISize& size, SkCodec::Result expectedRe
sult, |
| 147 SkCodec::Result expectedResult, SkMD5::Digest* digest, const SkMD5::Dige
st* goodDigest) { | 147 SkMD5::Digest* digest, const SkMD5::Digest* goodDigest) { |
| 148 | 148 |
| 149 REPORTER_ASSERT(r, info.dimensions() == size); | 149 REPORTER_ASSERT(r, info.dimensions() == size); |
| 150 bm.allocPixels(info); | 150 bm.allocPixels(info); |
| 151 SkAutoLockPixels autoLockPixels(bm); | 151 SkAutoLockPixels autoLockPixels(bm); |
| 152 | 152 |
| 153 SkCodec::Result result = codec->getAndroidPixels(info, bm.getPixels(), bm.ro
wBytes()); | 153 SkCodec::Result result = codec->getAndroidPixels(info, bm.getPixels(), bm.ro
wBytes()); |
| 154 REPORTER_ASSERT(r, result == expectedResult); | 154 REPORTER_ASSERT(r, result == expectedResult); |
| 155 | 155 |
| 156 md5(bm, digest); | 156 md5(bm, digest); |
| 157 if (goodDigest) { | 157 if (goodDigest) { |
| 158 REPORTER_ASSERT(r, *digest == *goodDigest); | 158 REPORTER_ASSERT(r, *digest == *goodDigest); |
| 159 } | 159 } |
| 160 | 160 |
| 161 { | 161 { |
| 162 // Test decoding to 565 | 162 // Test decoding to 565 |
| 163 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType); | 163 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType); |
| 164 SkCodec::Result expected565 = (supports565 && info.alphaType() == kOpaqu
e_SkAlphaType) ? | 164 SkCodec::Result expected565 = info.alphaType() == kOpaque_SkAlphaType ? |
| 165 expectedResult : SkCodec::kInvalidConversion; | 165 expectedResult : SkCodec::kInvalidConversion; |
| 166 test_android_info(r, codec, info565, expected565, nullptr); | 166 test_android_info(r, codec, info565, expected565, nullptr); |
| 167 } | 167 } |
| 168 | 168 |
| 169 // Verify that re-decoding gives the same result. It is interesting to chec
k this after | 169 // Verify that re-decoding gives the same result. It is interesting to chec
k this after |
| 170 // a decode to 565, since choosing to decode to 565 may result in some of th
e decode | 170 // a decode to 565, since choosing to decode to 565 may result in some of th
e decode |
| 171 // options being modified. These options should return to their defaults on
another | 171 // options being modified. These options should return to their defaults on
another |
| 172 // decode to kN32, so the new digest should match the old digest. | 172 // decode to kN32, so the new digest should match the old digest. |
| 173 test_android_info(r, codec, info, expectedResult, digest); | 173 test_android_info(r, codec, info, expectedResult, digest); |
| 174 | 174 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 } | 209 } |
| 210 } | 210 } |
| 211 return false; | 211 return false; |
| 212 } | 212 } |
| 213 | 213 |
| 214 static void check(skiatest::Reporter* r, | 214 static void check(skiatest::Reporter* r, |
| 215 const char path[], | 215 const char path[], |
| 216 SkISize size, | 216 SkISize size, |
| 217 bool supportsScanlineDecoding, | 217 bool supportsScanlineDecoding, |
| 218 bool supportsSubsetDecoding, | 218 bool supportsSubsetDecoding, |
| 219 bool supports565 = true, | |
| 220 bool supportsIncomplete = true) { | 219 bool supportsIncomplete = true) { |
| 221 | 220 |
| 222 SkAutoTDelete<SkStream> stream(resource(path)); | 221 SkAutoTDelete<SkStream> stream(resource(path)); |
| 223 if (!stream) { | 222 if (!stream) { |
| 224 SkDebugf("Missing resource '%s'\n", path); | 223 SkDebugf("Missing resource '%s'\n", path); |
| 225 return; | 224 return; |
| 226 } | 225 } |
| 227 | 226 |
| 228 SkAutoTDelete<SkCodec> codec(nullptr); | 227 SkAutoTDelete<SkCodec> codec(nullptr); |
| 229 bool isIncomplete = supportsIncomplete; | 228 bool isIncomplete = supportsIncomplete; |
| 230 if (isIncomplete) { | 229 if (isIncomplete) { |
| 231 size_t size = stream->getLength(); | 230 size_t size = stream->getLength(); |
| 232 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3)))
; | 231 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3)))
; |
| 233 codec.reset(SkCodec::NewFromData(data)); | 232 codec.reset(SkCodec::NewFromData(data)); |
| 234 } else { | 233 } else { |
| 235 codec.reset(SkCodec::NewFromStream(stream.detach())); | 234 codec.reset(SkCodec::NewFromStream(stream.detach())); |
| 236 } | 235 } |
| 237 if (!codec) { | 236 if (!codec) { |
| 238 ERRORF(r, "Unable to decode '%s'", path); | 237 ERRORF(r, "Unable to decode '%s'", path); |
| 239 return; | 238 return; |
| 240 } | 239 } |
| 241 | 240 |
| 242 // Test full image decodes with SkCodec | 241 // Test full image decodes with SkCodec |
| 243 SkMD5::Digest codecDigest; | 242 SkMD5::Digest codecDigest; |
| 244 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); | 243 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); |
| 245 SkBitmap bm; | 244 SkBitmap bm; |
| 246 SkCodec::Result expectedResult = isIncomplete ? SkCodec::kIncompleteInput :
SkCodec::kSuccess; | 245 SkCodec::Result expectedResult = isIncomplete ? SkCodec::kIncompleteInput :
SkCodec::kSuccess; |
| 247 test_codec(r, codec, bm, info, size, supports565, expectedResult, &codecDige
st, nullptr); | 246 test_codec(r, codec, bm, info, size, expectedResult, &codecDigest, nullptr); |
| 248 | 247 |
| 249 // Scanline decoding follows. | 248 // Scanline decoding follows. |
| 250 // Need to call startScanlineDecode() first. | 249 // Need to call startScanlineDecode() first. |
| 251 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) | 250 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) |
| 252 == 0); | 251 == 0); |
| 253 REPORTER_ASSERT(r, codec->skipScanlines(1) | 252 REPORTER_ASSERT(r, codec->skipScanlines(1) |
| 254 == 0); | 253 == 0); |
| 255 | 254 |
| 256 const SkCodec::Result startResult = codec->startScanlineDecode(info); | 255 const SkCodec::Result startResult = codec->startScanlineDecode(info); |
| 257 if (supportsScanlineDecoding) { | 256 if (supportsScanlineDecoding) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 } else { | 362 } else { |
| 364 codec.reset(SkAndroidCodec::NewFromStream(stream.detach())); | 363 codec.reset(SkAndroidCodec::NewFromStream(stream.detach())); |
| 365 } | 364 } |
| 366 if (!codec) { | 365 if (!codec) { |
| 367 ERRORF(r, "Unable to decode '%s'", path); | 366 ERRORF(r, "Unable to decode '%s'", path); |
| 368 return; | 367 return; |
| 369 } | 368 } |
| 370 | 369 |
| 371 SkBitmap bm; | 370 SkBitmap bm; |
| 372 SkMD5::Digest scaledCodecDigest; | 371 SkMD5::Digest scaledCodecDigest; |
| 373 test_android_codec(r, codec, bm, info, size, supports565, expectedResult
, | 372 test_android_codec(r, codec, bm, info, size, expectedResult, |
| 374 &scaledCodecDigest, &codecDigest); | 373 &scaledCodecDigest, &codecDigest); |
| 375 } | 374 } |
| 376 | 375 |
| 377 // If we've just tested incomplete decodes, let's run the same test again on
full decodes. | 376 // If we've just tested incomplete decodes, let's run the same test again on
full decodes. |
| 378 if (isIncomplete) { | 377 if (isIncomplete) { |
| 379 check(r, path, size, supportsScanlineDecoding, supportsSubsetDecoding, s
upports565, false); | 378 check(r, path, size, supportsScanlineDecoding, supportsSubsetDecoding, f
alse); |
| 380 } | 379 } |
| 381 } | 380 } |
| 382 | 381 |
| 383 DEF_TEST(Codec, r) { | 382 DEF_TEST(Codec, r) { |
| 384 // WBMP | 383 // WBMP |
| 385 check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false); | 384 check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false); |
| 386 | 385 |
| 387 // WEBP | 386 // WEBP |
| 388 check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true); | 387 check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true); |
| 389 check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true); | 388 check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true); |
| 390 check(r, "yellow_rose.webp", SkISize::Make(400, 301), false, true); | 389 check(r, "yellow_rose.webp", SkISize::Make(400, 301), false, true); |
| 391 | 390 |
| 392 // BMP | 391 // BMP |
| 393 check(r, "randPixels.bmp", SkISize::Make(8, 8), true, false); | 392 check(r, "randPixels.bmp", SkISize::Make(8, 8), true, false); |
| 394 | 393 |
| 395 // ICO | 394 // ICO |
| 396 // FIXME: We are not ready to test incomplete ICOs | 395 // FIXME: We are not ready to test incomplete ICOs |
| 397 // These two tests examine interestingly different behavior: | 396 // These two tests examine interestingly different behavior: |
| 398 // Decodes an embedded BMP image | 397 // Decodes an embedded BMP image |
| 399 check(r, "color_wheel.ico", SkISize::Make(128, 128), false, false, true, fal
se); | 398 check(r, "color_wheel.ico", SkISize::Make(128, 128), false, false, false); |
| 400 // Decodes an embedded PNG image | 399 // Decodes an embedded PNG image |
| 401 check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false, true, f
alse); | 400 check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false, false); |
| 402 | 401 |
| 403 // GIF | 402 // GIF |
| 404 // FIXME: We are not ready to test incomplete GIFs | 403 // FIXME: We are not ready to test incomplete GIFs |
| 405 check(r, "box.gif", SkISize::Make(200, 55), true, false, true, false); | 404 check(r, "box.gif", SkISize::Make(200, 55), true, false, false); |
| 406 check(r, "color_wheel.gif", SkISize::Make(128, 128), true, false, true, fals
e); | 405 check(r, "color_wheel.gif", SkISize::Make(128, 128), true, false, false); |
| 407 // randPixels.gif is too small to test incomplete | 406 // randPixels.gif is too small to test incomplete |
| 408 check(r, "randPixels.gif", SkISize::Make(8, 8), true, false, true, false); | 407 check(r, "randPixels.gif", SkISize::Make(8, 8), true, false, false); |
| 409 | 408 |
| 410 // JPG | 409 // JPG |
| 411 check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false, true); | 410 check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false); |
| 412 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false); | 411 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false); |
| 413 // grayscale.jpg is too small to test incomplete | 412 // grayscale.jpg is too small to test incomplete |
| 414 check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false, true, false)
; | 413 check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false, false); |
| 415 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false); | 414 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false); |
| 416 // randPixels.jpg is too small to test incomplete | 415 // randPixels.jpg is too small to test incomplete |
| 417 check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false, true, false); | 416 check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false, false); |
| 418 | 417 |
| 419 // PNG | 418 // PNG |
| 420 check(r, "arrow.png", SkISize::Make(187, 312), true, false, true, false); | 419 check(r, "arrow.png", SkISize::Make(187, 312), true, false, false); |
| 421 check(r, "baby_tux.png", SkISize::Make(240, 246), true, false, true, false); | 420 check(r, "baby_tux.png", SkISize::Make(240, 246), true, false, false); |
| 422 check(r, "color_wheel.png", SkISize::Make(128, 128), true, false, true, fals
e); | 421 check(r, "color_wheel.png", SkISize::Make(128, 128), true, false, false); |
| 423 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, fals
e, true, false); | 422 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, fals
e, false); |
| 424 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false, true, fal
se); | 423 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false, false); |
| 425 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false, true, false)
; | 424 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false, false); |
| 426 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false, true, fal
se); | 425 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false, false); |
| 427 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false, true, false)
; | 426 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false, false); |
| 428 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false, true, fal
se); | 427 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false, false); |
| 429 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false, true, false)
; | 428 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false, false); |
| 430 check(r, "plane.png", SkISize::Make(250, 126), true, false, true, false); | 429 check(r, "plane.png", SkISize::Make(250, 126), true, false, false); |
| 431 // FIXME: We are not ready to test incomplete interlaced pngs | 430 // FIXME: We are not ready to test incomplete interlaced pngs |
| 432 check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false, true,
false); | 431 check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false, false
); |
| 433 check(r, "randPixels.png", SkISize::Make(8, 8), true, false, true, false); | 432 check(r, "randPixels.png", SkISize::Make(8, 8), true, false, false); |
| 434 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false, true, fals
e); | 433 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false, false); |
| 435 } | 434 } |
| 436 | 435 |
| 437 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode | 436 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode |
| 438 DEF_TEST(Codec_stripes, r) { | 437 DEF_TEST(Codec_stripes, r) { |
| 439 const char * path = "plane_interlaced.png"; | 438 const char * path = "plane_interlaced.png"; |
| 440 SkAutoTDelete<SkStream> stream(resource(path)); | 439 SkAutoTDelete<SkStream> stream(resource(path)); |
| 441 if (!stream) { | 440 if (!stream) { |
| 442 SkDebugf("Missing resource '%s'\n", path); | 441 SkDebugf("Missing resource '%s'\n", path); |
| 443 } | 442 } |
| 444 | 443 |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); | 678 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); |
| 680 result = decoder->startScanlineDecode( | 679 result = decoder->startScanlineDecode( |
| 681 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); | 680 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); |
| 682 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); | 681 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); |
| 683 } | 682 } |
| 684 | 683 |
| 685 DEF_TEST(Codec_Params, r) { | 684 DEF_TEST(Codec_Params, r) { |
| 686 test_invalid_parameters(r, "index8.png"); | 685 test_invalid_parameters(r, "index8.png"); |
| 687 test_invalid_parameters(r, "mandrill.wbmp"); | 686 test_invalid_parameters(r, "mandrill.wbmp"); |
| 688 } | 687 } |
| OLD | NEW |