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 |