Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: tests/CodexTest.cpp

Issue 1406223002: Create an SkAndroidCodec API separate from SkCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Win bot fix Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/codec/SkWebpAdapterCodec.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "SkBitmap.h" 10 #include "SkBitmap.h"
10 #include "SkCodec.h" 11 #include "SkCodec.h"
11 #include "SkData.h" 12 #include "SkData.h"
12 #include "SkMD5.h" 13 #include "SkMD5.h"
13 #include "SkRandom.h" 14 #include "SkRandom.h"
14 #include "SkScaledCodec.h"
15 #include "Test.h" 15 #include "Test.h"
16 16
17 static SkStreamAsset* resource(const char path[]) { 17 static SkStreamAsset* resource(const char path[]) {
18 SkString fullPath = GetResourcePath(path); 18 SkString fullPath = GetResourcePath(path);
19 return SkStream::NewFromFile(fullPath.c_str()); 19 return SkStream::NewFromFile(fullPath.c_str());
20 } 20 }
21 21
22 static void md5(const SkBitmap& bm, SkMD5::Digest* digest) { 22 static void md5(const SkBitmap& bm, SkMD5::Digest* digest) {
23 SkAutoLockPixels autoLockPixels(bm); 23 SkAutoLockPixels autoLockPixels(bm);
24 SkASSERT(bm.getPixels()); 24 SkASSERT(bm.getPixels());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 SkAutoLockPixels autoLockPixels(bm); 56 SkAutoLockPixels autoLockPixels(bm);
57 57
58 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes( )); 58 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes( ));
59 REPORTER_ASSERT(r, result == expectedResult); 59 REPORTER_ASSERT(r, result == expectedResult);
60 60
61 if (goodDigest) { 61 if (goodDigest) {
62 compare_to_good_digest(r, *goodDigest, bm); 62 compare_to_good_digest(r, *goodDigest, bm);
63 } 63 }
64 } 64 }
65 65
66 static void test_android_info(skiatest::Reporter* r, SkAndroidCodec* codec, cons t SkImageInfo& info,
67 SkCodec::Result expectedResult, const SkMD5::Diges t* goodDigest) {
68 SkBitmap bm;
69 bm.allocPixels(info);
70 SkAutoLockPixels autoLockPixels(bm);
71
72 SkCodec::Result result = codec->getAndroidPixels(info, bm.getPixels(), bm.ro wBytes());
73 REPORTER_ASSERT(r, result == expectedResult);
74
75 if (goodDigest) {
76 compare_to_good_digest(r, *goodDigest, bm);
77 }
78 }
79
66 SkIRect generate_random_subset(SkRandom* rand, int w, int h) { 80 SkIRect generate_random_subset(SkRandom* rand, int w, int h) {
67 SkIRect rect; 81 SkIRect rect;
68 do { 82 do {
69 rect.fLeft = rand->nextRangeU(0, w); 83 rect.fLeft = rand->nextRangeU(0, w);
70 rect.fTop = rand->nextRangeU(0, h); 84 rect.fTop = rand->nextRangeU(0, h);
71 rect.fRight = rand->nextRangeU(0, w); 85 rect.fRight = rand->nextRangeU(0, w);
72 rect.fBottom = rand->nextRangeU(0, h); 86 rect.fBottom = rand->nextRangeU(0, h);
73 rect.sort(); 87 rect.sort();
74 } while (rect.isEmpty()); 88 } while (rect.isEmpty());
75 return rect; 89 return rect;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 otherAt = kUnpremul_SkAlphaType; 135 otherAt = kUnpremul_SkAlphaType;
122 } else { 136 } else {
123 otherAt = kPremul_SkAlphaType; 137 otherAt = kPremul_SkAlphaType;
124 } 138 }
125 // 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.
126 test_info(r, codec, info.makeAlphaType(otherAt), expectedResult, nul lptr); 140 test_info(r, codec, info.makeAlphaType(otherAt), expectedResult, nul lptr);
127 } 141 }
128 } 142 }
129 } 143 }
130 144
145 static void test_android_codec(skiatest::Reporter* r, SkAndroidCodec* codec, SkB itmap& bm,
146 const SkImageInfo& info, const SkISize& size, bool supports565,
147 SkCodec::Result expectedResult, SkMD5::Digest* digest, const SkMD5::Dige st* goodDigest) {
148
149 REPORTER_ASSERT(r, info.dimensions() == size);
150 bm.allocPixels(info);
151 SkAutoLockPixels autoLockPixels(bm);
152
153 SkCodec::Result result = codec->getAndroidPixels(info, bm.getPixels(), bm.ro wBytes());
154 REPORTER_ASSERT(r, result == expectedResult);
155
156 md5(bm, digest);
157 if (goodDigest) {
158 REPORTER_ASSERT(r, *digest == *goodDigest);
159 }
160
161 {
162 // Test decoding to 565
163 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType);
164 SkCodec::Result expected565 = (supports565 && info.alphaType() == kOpaqu e_SkAlphaType) ?
165 expectedResult : SkCodec::kInvalidConversion;
166 test_android_info(r, codec, info565, expected565, nullptr);
167 }
168
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
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.
173 test_android_info(r, codec, info, expectedResult, digest);
174
175 {
176 // Check alpha type conversions
177 if (info.alphaType() == kOpaque_SkAlphaType) {
178 test_android_info(r, codec, info.makeAlphaType(kUnpremul_SkAlphaType ),
179 SkCodec::kInvalidConversion, nullptr);
180 test_android_info(r, codec, info.makeAlphaType(kPremul_SkAlphaType),
181 SkCodec::kInvalidConversion, nullptr);
182 } else {
183 // Decoding to opaque should fail
184 test_android_info(r, codec, info.makeAlphaType(kOpaque_SkAlphaType),
185 SkCodec::kInvalidConversion, nullptr);
186 SkAlphaType otherAt = info.alphaType();
187 if (kPremul_SkAlphaType == otherAt) {
188 otherAt = kUnpremul_SkAlphaType;
189 } else {
190 otherAt = kPremul_SkAlphaType;
191 }
192 // The other non-opaque alpha type should always succeed, but not ma tch.
193 test_android_info(r, codec, info.makeAlphaType(otherAt), expectedRes ult, nullptr);
194 }
195 }
196 }
197
131 // FIXME: SkScaledCodec is currently only supported for types used by BRD 198 // FIXME: SkScaledCodec is currently only supported for types used by BRD
132 // skbug.com/4428 199 // skbug.com/4428
133 static bool supports_scaled_codec(const char path[]) { 200 static bool supports_scaled_codec(const char path[]) {
134 static const char* const exts[] = { 201 static const char* const exts[] = {
135 "jpg", "jpeg", "png", "webp" 202 "jpg", "jpeg", "png", "webp"
136 "JPG", "JPEG", "PNG", "WEBP" 203 "JPG", "JPEG", "PNG", "WEBP"
137 }; 204 };
138 205
139 for (uint32_t i = 0; i < SK_ARRAY_COUNT(exts); i++) { 206 for (uint32_t i = 0; i < SK_ARRAY_COUNT(exts); i++) {
140 if (SkStrEndsWith(path, exts[i])) { 207 if (SkStrEndsWith(path, exts[i])) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 348
282 // SkScaledCodec tests 349 // SkScaledCodec tests
283 if ((supportsScanlineDecoding || supportsSubsetDecoding) && supports_scaled_ codec(path)) { 350 if ((supportsScanlineDecoding || supportsSubsetDecoding) && supports_scaled_ codec(path)) {
284 351
285 SkAutoTDelete<SkStream> stream(resource(path)); 352 SkAutoTDelete<SkStream> stream(resource(path));
286 if (!stream) { 353 if (!stream) {
287 SkDebugf("Missing resource '%s'\n", path); 354 SkDebugf("Missing resource '%s'\n", path);
288 return; 355 return;
289 } 356 }
290 357
291 SkAutoTDelete<SkCodec> codec(nullptr); 358 SkAutoTDelete<SkAndroidCodec> codec(nullptr);
292 if (isIncomplete) { 359 if (isIncomplete) {
293 size_t size = stream->getLength(); 360 size_t size = stream->getLength();
294 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3))); 361 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3)));
295 codec.reset(SkScaledCodec::NewFromData(data)); 362 codec.reset(SkAndroidCodec::NewFromData(data));
296 } else { 363 } else {
297 codec.reset(SkScaledCodec::NewFromStream(stream.detach())); 364 codec.reset(SkAndroidCodec::NewFromStream(stream.detach()));
298 } 365 }
299 if (!codec) { 366 if (!codec) {
300 ERRORF(r, "Unable to decode '%s'", path); 367 ERRORF(r, "Unable to decode '%s'", path);
301 return; 368 return;
302 } 369 }
303 370
304 SkBitmap bm; 371 SkBitmap bm;
305 SkMD5::Digest scaledCodecDigest; 372 SkMD5::Digest scaledCodecDigest;
306 test_codec(r, codec, bm, info, size, supports565, expectedResult, &scale dCodecDigest, 373 test_android_codec(r, codec, bm, info, size, supports565, expectedResult ,
307 &codecDigest); 374 &scaledCodecDigest, &codecDigest);
308 } 375 }
309 376
310 // If we've just tested incomplete decodes, let's run the same test again on full decodes. 377 // If we've just tested incomplete decodes, let's run the same test again on full decodes.
311 if (isIncomplete) { 378 if (isIncomplete) {
312 check(r, path, size, supportsScanlineDecoding, supportsSubsetDecoding, s upports565, false); 379 check(r, path, size, supportsScanlineDecoding, supportsSubsetDecoding, s upports565, false);
313 } 380 }
314 } 381 }
315 382
316 DEF_TEST(Codec, r) { 383 DEF_TEST(Codec, r) {
317 // WBMP 384 // WBMP
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 } 523 }
457 524
458 compare_to_good_digest(r, digest, bm); 525 compare_to_good_digest(r, digest, bm);
459 } 526 }
460 527
461 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_ t len) { 528 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_ t len) {
462 // Neither of these calls should return a codec. Bots should catch us if we leaked anything. 529 // Neither of these calls should return a codec. Bots should catch us if we leaked anything.
463 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals e)); 530 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals e));
464 REPORTER_ASSERT(r, !codec); 531 REPORTER_ASSERT(r, !codec);
465 532
466 codec = SkScaledCodec::NewFromStream(new SkMemoryStream(stream, len, false)) ; 533 SkAndroidCodec* androidCodec =
467 REPORTER_ASSERT(r, !codec); 534 SkAndroidCodec::NewFromStream(new SkMemoryStream(stream, len, false) );
535 REPORTER_ASSERT(r, !androidCodec);
468 } 536 }
469 537
470 // Ensure that SkCodec::NewFromStream handles freeing the passed in SkStream, 538 // Ensure that SkCodec::NewFromStream handles freeing the passed in SkStream,
471 // even on failure. Test some bad streams. 539 // even on failure. Test some bad streams.
472 DEF_TEST(Codec_leaks, r) { 540 DEF_TEST(Codec_leaks, r) {
473 // No codec should claim this as their format, so this tests SkCodec::NewFro mStream. 541 // No codec should claim this as their format, so this tests SkCodec::NewFro mStream.
474 const char nonSupportedStream[] = "hello world"; 542 const char nonSupportedStream[] = "hello world";
475 // The other strings should look like the beginning of a file type, so we'll call some 543 // The other strings should look like the beginning of a file type, so we'll call some
476 // internal version of NewFromStream, which must also delete the stream on f ailure. 544 // internal version of NewFromStream, which must also delete the stream on f ailure.
477 const unsigned char emptyPng[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a }; 545 const unsigned char emptyPng[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
(...skipping 11 matching lines...) Expand all
489 test_invalid_stream(r, emptyIco, sizeof(emptyIco)); 557 test_invalid_stream(r, emptyIco, sizeof(emptyIco));
490 test_invalid_stream(r, emptyGif, sizeof(emptyGif)); 558 test_invalid_stream(r, emptyGif, sizeof(emptyGif));
491 } 559 }
492 560
493 DEF_TEST(Codec_null, r) { 561 DEF_TEST(Codec_null, r) {
494 // Attempting to create an SkCodec or an SkScaledCodec with null should not 562 // Attempting to create an SkCodec or an SkScaledCodec with null should not
495 // crash. 563 // crash.
496 SkCodec* codec = SkCodec::NewFromStream(nullptr); 564 SkCodec* codec = SkCodec::NewFromStream(nullptr);
497 REPORTER_ASSERT(r, !codec); 565 REPORTER_ASSERT(r, !codec);
498 566
499 codec = SkScaledCodec::NewFromStream(nullptr); 567 SkAndroidCodec* androidCodec = SkAndroidCodec::NewFromStream(nullptr);
500 REPORTER_ASSERT(r, !codec); 568 REPORTER_ASSERT(r, !androidCodec);
501 } 569 }
502 570
503 static void test_dimensions(skiatest::Reporter* r, const char path[]) { 571 static void test_dimensions(skiatest::Reporter* r, const char path[]) {
504 // Create the codec from the resource file 572 // Create the codec from the resource file
505 SkAutoTDelete<SkStream> stream(resource(path)); 573 SkAutoTDelete<SkStream> stream(resource(path));
506 if (!stream) { 574 if (!stream) {
507 SkDebugf("Missing resource '%s'\n", path); 575 SkDebugf("Missing resource '%s'\n", path);
508 return; 576 return;
509 } 577 }
510 SkAutoTDelete<SkCodec> codec(SkScaledCodec::NewFromStream(stream.detach())); 578 SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(stream.det ach()));
511 if (!codec) { 579 if (!codec) {
512 ERRORF(r, "Unable to create codec '%s'", path); 580 ERRORF(r, "Unable to create codec '%s'", path);
513 return; 581 return;
514 } 582 }
515 583
516 // Check that the decode is successful for a variety of scales 584 // Check that the decode is successful for a variety of scales
517 for (float scale = 0.05f; scale < 2.0f; scale += 0.05f) { 585 for (int sampleSize = 1; sampleSize < 10; sampleSize++) {
518 // Scale the output dimensions 586 // Scale the output dimensions
519 SkISize scaledDims = codec->getScaledDimensions(scale); 587 SkISize scaledDims = codec->getSampledDimensions(sampleSize);
520 SkImageInfo scaledInfo = codec->getInfo() 588 SkImageInfo scaledInfo = codec->getInfo()
521 .makeWH(scaledDims.width(), scaledDims.height()) 589 .makeWH(scaledDims.width(), scaledDims.height())
522 .makeColorType(kN32_SkColorType); 590 .makeColorType(kN32_SkColorType);
523 591
524 // Set up for the decode 592 // Set up for the decode
525 size_t rowBytes = scaledDims.width() * sizeof(SkPMColor); 593 size_t rowBytes = scaledDims.width() * sizeof(SkPMColor);
526 size_t totalBytes = scaledInfo.getSafeSize(rowBytes); 594 size_t totalBytes = scaledInfo.getSafeSize(rowBytes);
527 SkAutoTMalloc<SkPMColor> pixels(totalBytes); 595 SkAutoTMalloc<SkPMColor> pixels(totalBytes);
528 596
597 SkAndroidCodec::AndroidOptions options;
598 options.fSampleSize = sampleSize;
529 SkCodec::Result result = 599 SkCodec::Result result =
530 codec->getPixels(scaledInfo, pixels.get(), rowBytes, nullptr, nu llptr, nullptr); 600 codec->getAndroidPixels(scaledInfo, pixels.get(), rowBytes, &opt ions);
531 REPORTER_ASSERT(r, SkCodec::kSuccess == result); 601 REPORTER_ASSERT(r, SkCodec::kSuccess == result);
532 } 602 }
533 } 603 }
534 604
535 // Ensure that onGetScaledDimensions returns valid image dimensions to use for d ecodes 605 // Ensure that onGetScaledDimensions returns valid image dimensions to use for d ecodes
536 DEF_TEST(Codec_Dimensions, r) { 606 DEF_TEST(Codec_Dimensions, r) {
537 // JPG 607 // JPG
538 test_dimensions(r, "CMYK.jpg"); 608 test_dimensions(r, "CMYK.jpg");
539 test_dimensions(r, "color_wheel.jpg"); 609 test_dimensions(r, "color_wheel.jpg");
540 test_dimensions(r, "grayscale.jpg"); 610 test_dimensions(r, "grayscale.jpg");
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); 679 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
610 result = decoder->startScanlineDecode( 680 result = decoder->startScanlineDecode(
611 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); 681 decoder->getInfo().makeColorType(kIndex_8_SkColorType));
612 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); 682 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
613 } 683 }
614 684
615 DEF_TEST(Codec_Params, r) { 685 DEF_TEST(Codec_Params, r) {
616 test_invalid_parameters(r, "index8.png"); 686 test_invalid_parameters(r, "index8.png");
617 test_invalid_parameters(r, "mandrill.wbmp"); 687 test_invalid_parameters(r, "mandrill.wbmp");
618 } 688 }
OLDNEW
« no previous file with comments | « src/codec/SkWebpAdapterCodec.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698