| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 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 "gm_expectations.h" | 8 #include "gm_expectations.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| 11 #include "SkCommandLineFlags.h" | 11 #include "SkCommandLineFlags.h" |
| 12 #include "SkData.h" | 12 #include "SkData.h" |
| 13 #include "SkForceLinking.h" | 13 #include "SkForceLinking.h" |
| 14 #include "SkGraphics.h" | 14 #include "SkGraphics.h" |
| 15 #include "SkImageDecoder.h" | 15 #include "SkImageDecoder.h" |
| 16 #include "SkImageEncoder.h" | 16 #include "SkImageEncoder.h" |
| 17 #include "SkOSFile.h" | 17 #include "SkOSFile.h" |
| 18 #include "SkRandom.h" | 18 #include "SkRandom.h" |
| 19 #include "SkStream.h" | 19 #include "SkStream.h" |
| 20 #include "SkTArray.h" | 20 #include "SkTArray.h" |
| 21 #include "SkTemplates.h" | 21 #include "SkTemplates.h" |
| 22 | 22 |
| 23 __SK_FORCE_IMAGE_DECODER_LINKING; | 23 __SK_FORCE_IMAGE_DECODER_LINKING; |
| 24 | 24 |
| 25 DEFINE_string(config, "None", "Preferred config to decode into. [None|8888|565|A
8]"); |
| 25 DEFINE_string(createExpectationsPath, "", "Path to write JSON expectations."); | 26 DEFINE_string(createExpectationsPath, "", "Path to write JSON expectations."); |
| 26 DEFINE_string(mismatchPath, "", "Folder to write mismatched images to."); | 27 DEFINE_string(mismatchPath, "", "Folder to write mismatched images to."); |
| 27 DEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required.
"); | 28 DEFINE_string2(readPath, r, "", "Folder(s) and files to decode images. Required.
"); |
| 28 DEFINE_string(readExpectationsPath, "", "Path to read JSON expectations from."); | 29 DEFINE_string(readExpectationsPath, "", "Path to read JSON expectations from."); |
| 29 DEFINE_bool(reencode, true, "Reencode the images to test encoding."); | 30 DEFINE_bool(reencode, true, "Reencode the images to test encoding."); |
| 30 DEFINE_bool(testSubsetDecoding, true, "Test decoding subsets of images."); | 31 DEFINE_bool(testSubsetDecoding, true, "Test decoding subsets of images."); |
| 31 DEFINE_string2(writePath, w, "", "Write rendered images into this directory."); | 32 DEFINE_string2(writePath, w, "", "Write rendered images into this directory."); |
| 32 | 33 |
| 33 struct Format { | 34 struct Format { |
| 34 SkImageEncoder::Type fType; | 35 SkImageEncoder::Type fType; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 // Store the names of the filenames to report later which ones failed, succeeded
, and were | 92 // Store the names of the filenames to report later which ones failed, succeeded
, and were |
| 92 // invalid. | 93 // invalid. |
| 93 static SkTArray<SkString, false> gInvalidStreams; | 94 static SkTArray<SkString, false> gInvalidStreams; |
| 94 static SkTArray<SkString, false> gMissingCodecs; | 95 static SkTArray<SkString, false> gMissingCodecs; |
| 95 static SkTArray<SkString, false> gDecodeFailures; | 96 static SkTArray<SkString, false> gDecodeFailures; |
| 96 static SkTArray<SkString, false> gEncodeFailures; | 97 static SkTArray<SkString, false> gEncodeFailures; |
| 97 static SkTArray<SkString, false> gSuccessfulDecodes; | 98 static SkTArray<SkString, false> gSuccessfulDecodes; |
| 98 static SkTArray<SkString, false> gSuccessfulSubsetDecodes; | 99 static SkTArray<SkString, false> gSuccessfulSubsetDecodes; |
| 99 static SkTArray<SkString, false> gFailedSubsetDecodes; | 100 static SkTArray<SkString, false> gFailedSubsetDecodes; |
| 100 | 101 |
| 102 static SkBitmap::Config gPrefConfig(SkBitmap::kNo_Config); |
| 103 |
| 101 // Expections read from a file specified by readExpectationsPath. The expectatio
ns must have been | 104 // Expections read from a file specified by readExpectationsPath. The expectatio
ns must have been |
| 102 // previously written using createExpectationsPath. | 105 // previously written using createExpectationsPath. |
| 103 SkAutoTUnref<skiagm::JsonExpectationsSource> gJsonExpectations; | 106 SkAutoTUnref<skiagm::JsonExpectationsSource> gJsonExpectations; |
| 104 | 107 |
| 105 static bool write_bitmap(const char outName[], const SkBitmap& bm) { | 108 static bool write_bitmap(const char outName[], const SkBitmap& bm) { |
| 106 return SkImageEncoder::EncodeFile(outName, bm, SkImageEncoder::kPNG_Type, 10
0); | 109 return SkImageEncoder::EncodeFile(outName, bm, SkImageEncoder::kPNG_Type, 10
0); |
| 107 } | 110 } |
| 108 | 111 |
| 109 /** | 112 /** |
| 110 * Return a random SkIRect inside the range specified. | 113 * Return a random SkIRect inside the range specified. |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 } | 312 } |
| 310 | 313 |
| 311 SkAutoTDelete<SkImageDecoder> ad(codec); | 314 SkAutoTDelete<SkImageDecoder> ad(codec); |
| 312 | 315 |
| 313 stream.rewind(); | 316 stream.rewind(); |
| 314 | 317 |
| 315 // Create a string representing just the filename itself, for use in json ex
pectations. | 318 // Create a string representing just the filename itself, for use in json ex
pectations. |
| 316 SkString basename = SkOSPath::SkBasename(srcPath); | 319 SkString basename = SkOSPath::SkBasename(srcPath); |
| 317 const char* filename = basename.c_str(); | 320 const char* filename = basename.c_str(); |
| 318 | 321 |
| 319 if (!codec->decode(&stream, &bitmap, SkBitmap::kARGB_8888_Config, | 322 if (!codec->decode(&stream, &bitmap, gPrefConfig, |
| 320 SkImageDecoder::kDecodePixels_Mode)) { | 323 SkImageDecoder::kDecodePixels_Mode)) { |
| 321 if (expect_to_fail(filename)) { | 324 if (expect_to_fail(filename)) { |
| 322 gSuccessfulDecodes.push_back().appendf( | 325 gSuccessfulDecodes.push_back().appendf( |
| 323 "failed to decode %s, which is a known failure.", srcPath); | 326 "failed to decode %s, which is a known failure.", srcPath); |
| 324 } else { | 327 } else { |
| 325 gDecodeFailures.push_back().set(srcPath); | 328 gDecodeFailures.push_back().set(srcPath); |
| 326 } | 329 } |
| 327 return; | 330 return; |
| 328 } | 331 } |
| 329 | 332 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 if (codec->buildTileIndex(&stream, &width, &height) && width > 1 && heig
ht > 1) { | 380 if (codec->buildTileIndex(&stream, &width, &height) && width > 1 && heig
ht > 1) { |
| 378 SkASSERT(bitmap.width() == width && bitmap.height() == height); | 381 SkASSERT(bitmap.width() == width && bitmap.height() == height); |
| 379 // Call decodeSubset multiple times: | 382 // Call decodeSubset multiple times: |
| 380 SkRandom rand(0); | 383 SkRandom rand(0); |
| 381 for (int i = 0; i < 5; i++) { | 384 for (int i = 0; i < 5; i++) { |
| 382 SkBitmap bitmapFromDecodeSubset; | 385 SkBitmap bitmapFromDecodeSubset; |
| 383 // FIXME: Come up with a more representative set of rectangles. | 386 // FIXME: Come up with a more representative set of rectangles. |
| 384 SkIRect rect = generate_random_rect(&rand, width, height); | 387 SkIRect rect = generate_random_rect(&rand, width, height); |
| 385 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft,
rect.fTop, | 388 SkString subsetDim = SkStringPrintf("[%d,%d,%d,%d]", rect.fLeft,
rect.fTop, |
| 386 rect.fRight, rect.fBottom); | 389 rect.fRight, rect.fBottom); |
| 387 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, SkBitmap:
:kNo_Config)) { | 390 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, gPrefConf
ig)) { |
| 388 SkString subsetName = SkStringPrintf("%s_%s", filename, subs
etDim.c_str()); | 391 SkString subsetName = SkStringPrintf("%s_%s", filename, subs
etDim.c_str()); |
| 389 if (compare_to_expectations_if_necessary(bitmapFromDecodeSub
set, | 392 if (compare_to_expectations_if_necessary(bitmapFromDecodeSub
set, |
| 390 subsetName.c_str(), | 393 subsetName.c_str(), |
| 391 &gFailedSubsetDecod
es)) { | 394 &gFailedSubsetDecod
es)) { |
| 392 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub
set %s from %s", | 395 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub
set %s from %s", |
| 393 subsetDim.c_str(),
srcPath); | 396 subsetDim.c_str(),
srcPath); |
| 394 } else if (!FLAGS_mismatchPath.isEmpty()) { | 397 } else if (!FLAGS_mismatchPath.isEmpty()) { |
| 395 write_subset(FLAGS_mismatchPath[0], filename, subsetDim.
c_str(), | 398 write_subset(FLAGS_mismatchPath[0], filename, subsetDim.
c_str(), |
| 396 &bitmapFromDecodeSubset, rect, bitmap); | 399 &bitmapFromDecodeSubset, rect, bitmap); |
| 397 } | 400 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 if(file.write(data->data(), data->size())) { | 462 if(file.write(data->data(), data->size())) { |
| 460 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_s
tr()); | 463 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_s
tr()); |
| 461 } else { | 464 } else { |
| 462 gEncodeFailures.push_back().printf("Failed to write %s", outPath
.c_str()); | 465 gEncodeFailures.push_back().printf("Failed to write %s", outPath
.c_str()); |
| 463 } | 466 } |
| 464 } | 467 } |
| 465 // Ensure that the reencoded data can still be decoded. | 468 // Ensure that the reencoded data can still be decoded. |
| 466 SkMemoryStream memStream(data); | 469 SkMemoryStream memStream(data); |
| 467 SkBitmap redecodedBitmap; | 470 SkBitmap redecodedBitmap; |
| 468 SkImageDecoder::Format formatOnSecondDecode; | 471 SkImageDecoder::Format formatOnSecondDecode; |
| 469 if (SkImageDecoder::DecodeStream(&memStream, &redecodedBitmap, SkBitmap:
:kNo_Config, | 472 if (SkImageDecoder::DecodeStream(&memStream, &redecodedBitmap, gPrefConf
ig, |
| 470 SkImageDecoder::kDecodePixels_Mode, | 473 SkImageDecoder::kDecodePixels_Mode, |
| 471 &formatOnSecondDecode)) { | 474 &formatOnSecondDecode)) { |
| 472 SkASSERT(format_to_type(formatOnSecondDecode) == type); | 475 SkASSERT(format_to_type(formatOnSecondDecode) == type); |
| 473 } else { | 476 } else { |
| 474 gDecodeFailures.push_back().printf("Failed to redecode %s after reen
coding to '%s'", | 477 gDecodeFailures.push_back().printf("Failed to redecode %s after reen
coding to '%s'", |
| 475 srcPath, suffix_for_type(type)); | 478 srcPath, suffix_for_type(type)); |
| 476 } | 479 } |
| 477 } | 480 } |
| 478 } | 481 } |
| 479 | 482 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 SkString* outDirPtr; | 546 SkString* outDirPtr; |
| 544 | 547 |
| 545 if (FLAGS_writePath.count() == 1) { | 548 if (FLAGS_writePath.count() == 1) { |
| 546 outDir.set(FLAGS_writePath[0]); | 549 outDir.set(FLAGS_writePath[0]); |
| 547 append_path_separator_if_necessary(&outDir); | 550 append_path_separator_if_necessary(&outDir); |
| 548 outDirPtr = &outDir; | 551 outDirPtr = &outDir; |
| 549 } else { | 552 } else { |
| 550 outDirPtr = NULL; | 553 outDirPtr = NULL; |
| 551 } | 554 } |
| 552 | 555 |
| 556 if (FLAGS_config.count() == 1) { |
| 557 // Only consider the first config specified on the command line. |
| 558 const char* config = FLAGS_config[0]; |
| 559 if (0 == strcmp(config, "8888")) { |
| 560 gPrefConfig = SkBitmap::kARGB_8888_Config; |
| 561 } else if (0 == strcmp(config, "565")) { |
| 562 gPrefConfig = SkBitmap::kRGB_565_Config; |
| 563 } else if (0 == strcmp(config, "A8")) { |
| 564 gPrefConfig = SkBitmap::kA8_Config; |
| 565 } else if (0 != strcmp(config, "None")) { |
| 566 SkDebugf("Invalid preferred config\n"); |
| 567 return -1; |
| 568 } |
| 569 } |
| 570 |
| 553 for (int i = 0; i < FLAGS_readPath.count(); i++) { | 571 for (int i = 0; i < FLAGS_readPath.count(); i++) { |
| 554 const char* readPath = FLAGS_readPath[i]; | 572 const char* readPath = FLAGS_readPath[i]; |
| 555 if (strlen(readPath) < 1) { | 573 if (strlen(readPath) < 1) { |
| 556 break; | 574 break; |
| 557 } | 575 } |
| 558 if (sk_isdir(readPath)) { | 576 if (sk_isdir(readPath)) { |
| 559 const char* dir = readPath; | 577 const char* dir = readPath; |
| 560 SkOSFile::Iter iter(dir); | 578 SkOSFile::Iter iter(dir); |
| 561 SkString filename; | 579 SkString filename; |
| 562 while (iter.next(&filename)) { | 580 while (iter.next(&filename)) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 } | 614 } |
| 597 | 615 |
| 598 return failed ? -1 : 0; | 616 return failed ? -1 : 0; |
| 599 } | 617 } |
| 600 | 618 |
| 601 #if !defined SK_BUILD_FOR_IOS | 619 #if !defined SK_BUILD_FOR_IOS |
| 602 int main(int argc, char * const argv[]) { | 620 int main(int argc, char * const argv[]) { |
| 603 return tool_main(argc, (char**) argv); | 621 return tool_main(argc, (char**) argv); |
| 604 } | 622 } |
| 605 #endif | 623 #endif |
| OLD | NEW |