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" |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 static SkTArray<SkString, false> gSuccessfulSubsetDecodes; | 110 static SkTArray<SkString, false> gSuccessfulSubsetDecodes; |
111 static SkTArray<SkString, false> gFailedSubsetDecodes; | 111 static SkTArray<SkString, false> gFailedSubsetDecodes; |
112 // Files/subsets that do not have expectations. Not reported as a failure of the
test so | 112 // Files/subsets that do not have expectations. Not reported as a failure of the
test so |
113 // the bots will not turn red with each new image test. | 113 // the bots will not turn red with each new image test. |
114 static SkTArray<SkString, false> gMissingExpectations; | 114 static SkTArray<SkString, false> gMissingExpectations; |
115 static SkTArray<SkString, false> gMissingSubsetExpectations; | 115 static SkTArray<SkString, false> gMissingSubsetExpectations; |
116 // For files that are expected to fail. | 116 // For files that are expected to fail. |
117 static SkTArray<SkString, false> gKnownFailures; | 117 static SkTArray<SkString, false> gKnownFailures; |
118 static SkTArray<SkString, false> gKnownSubsetFailures; | 118 static SkTArray<SkString, false> gKnownSubsetFailures; |
119 | 119 |
120 static SkBitmap::Config gPrefConfig(SkBitmap::kNo_Config); | 120 static SkColorType gPrefColorType(kUnknown_SkColorType); |
121 | 121 |
122 // Expections read from a file specified by readExpectationsPath. The expectatio
ns must have been | 122 // Expections read from a file specified by readExpectationsPath. The expectatio
ns must have been |
123 // previously written using createExpectationsPath. | 123 // previously written using createExpectationsPath. |
124 SkAutoTUnref<skiagm::JsonExpectationsSource> gJsonExpectations; | 124 SkAutoTUnref<skiagm::JsonExpectationsSource> gJsonExpectations; |
125 | 125 |
126 /** | 126 /** |
127 * Encode the bitmap to a file, written one of two ways, depending on | 127 * Encode the bitmap to a file, written one of two ways, depending on |
128 * FLAGS_writeChecksumBasedFilenames. If true, the final image will be | 128 * FLAGS_writeChecksumBasedFilenames. If true, the final image will be |
129 * written to: | 129 * written to: |
130 * outDir/hashType/src/digestValue.png | 130 * outDir/hashType/src/digestValue.png |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 // An error was already reported. | 438 // An error was already reported. |
439 return; | 439 return; |
440 } | 440 } |
441 SkASSERT(srcPath); | 441 SkASSERT(srcPath); |
442 SkASSERT(codec); | 442 SkASSERT(codec); |
443 FILEStreamWithoutLength stream(srcPath); | 443 FILEStreamWithoutLength stream(srcPath); |
444 // This will only be called after a successful decode. Creating a stream fro
m the same | 444 // This will only be called after a successful decode. Creating a stream fro
m the same |
445 // path should never fail. | 445 // path should never fail. |
446 SkASSERT(stream.isValid()); | 446 SkASSERT(stream.isValid()); |
447 SkBitmap bm; | 447 SkBitmap bm; |
448 if (!codec->decode(&stream, &bm, gPrefConfig, SkImageDecoder::kDecodePixels_
Mode)) { | 448 if (!codec->decode(&stream, &bm, gPrefColorType, SkImageDecoder::kDecodePixe
ls_Mode)) { |
449 gDecodeFailures.push_back().appendf("Without using getLength, %s failed
to decode\n", | 449 gDecodeFailures.push_back().appendf("Without using getLength, %s failed
to decode\n", |
450 srcPath); | 450 srcPath); |
451 return; | 451 return; |
452 } | 452 } |
453 skiagm::GmResultDigest lengthLessDigest(bm); | 453 skiagm::GmResultDigest lengthLessDigest(bm); |
454 if (!lengthLessDigest.isValid()) { | 454 if (!lengthLessDigest.isValid()) { |
455 gDecodeFailures.push_back().appendf("Without using getLength, %s failed
to build " | 455 gDecodeFailures.push_back().appendf("Without using getLength, %s failed
to build " |
456 "a digest\n", srcPath); | 456 "a digest\n", srcPath); |
457 return; | 457 return; |
458 } | 458 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 | 503 |
504 // Create a string representing just the filename itself, for use in json ex
pectations. | 504 // Create a string representing just the filename itself, for use in json ex
pectations. |
505 SkString basename = SkOSPath::SkBasename(srcPath); | 505 SkString basename = SkOSPath::SkBasename(srcPath); |
506 // Replace '_' with '-', so that the names can fit gm_json.py's IMAGE_FILENA
ME_PATTERN | 506 // Replace '_' with '-', so that the names can fit gm_json.py's IMAGE_FILENA
ME_PATTERN |
507 replace_char(&basename, '_', '-'); | 507 replace_char(&basename, '_', '-'); |
508 // Replace '.' with '-', so the output filename can still retain the origina
l file extension, | 508 // Replace '.' with '-', so the output filename can still retain the origina
l file extension, |
509 // but still end up with only one '.', which denotes the actual extension of
the final file. | 509 // but still end up with only one '.', which denotes the actual extension of
the final file. |
510 replace_char(&basename, '.', '-'); | 510 replace_char(&basename, '.', '-'); |
511 const char* filename = basename.c_str(); | 511 const char* filename = basename.c_str(); |
512 | 512 |
513 if (!codec->decode(&stream, &bitmap, gPrefConfig, | 513 if (!codec->decode(&stream, &bitmap, gPrefColorType, SkImageDecoder::kDecode
Pixels_Mode)) { |
514 SkImageDecoder::kDecodePixels_Mode)) { | |
515 if (NULL != gJsonExpectations.get()) { | 514 if (NULL != gJsonExpectations.get()) { |
516 const SkString name_config = create_json_key(filename); | 515 const SkString name_config = create_json_key(filename); |
517 skiagm::Expectations jsExpectations = gJsonExpectations->get(name_co
nfig.c_str()); | 516 skiagm::Expectations jsExpectations = gJsonExpectations->get(name_co
nfig.c_str()); |
518 if (jsExpectations.ignoreFailure()) { | 517 if (jsExpectations.ignoreFailure()) { |
519 // This is a known failure. | 518 // This is a known failure. |
520 gKnownFailures.push_back().appendf( | 519 gKnownFailures.push_back().appendf( |
521 "failed to decode %s, which is a known failure.", srcPath); | 520 "failed to decode %s, which is a known failure.", srcPath); |
522 return; | 521 return; |
523 } | 522 } |
524 if (jsExpectations.empty()) { | 523 if (jsExpectations.empty()) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 if (codec->buildTileIndex(&stream, &width, &height) && width > 1 && heig
ht > 1) { | 589 if (codec->buildTileIndex(&stream, &width, &height) && width > 1 && heig
ht > 1) { |
591 SkASSERT(bitmap.width() == width && bitmap.height() == height); | 590 SkASSERT(bitmap.width() == width && bitmap.height() == height); |
592 // Call decodeSubset multiple times: | 591 // Call decodeSubset multiple times: |
593 SkRandom rand(0); | 592 SkRandom rand(0); |
594 for (int i = 0; i < 5; i++) { | 593 for (int i = 0; i < 5; i++) { |
595 SkBitmap bitmapFromDecodeSubset; | 594 SkBitmap bitmapFromDecodeSubset; |
596 // FIXME: Come up with a more representative set of rectangles. | 595 // FIXME: Come up with a more representative set of rectangles. |
597 SkIRect rect = generate_random_rect(&rand, width, height); | 596 SkIRect rect = generate_random_rect(&rand, width, height); |
598 SkString subsetDim = SkStringPrintf("%d_%d_%d_%d", rect.fLeft, r
ect.fTop, | 597 SkString subsetDim = SkStringPrintf("%d_%d_%d_%d", rect.fLeft, r
ect.fTop, |
599 rect.fRight, rect.fBottom); | 598 rect.fRight, rect.fBottom); |
600 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, gPrefConf
ig)) { | 599 if (codec->decodeSubset(&bitmapFromDecodeSubset, rect, gPrefColo
rType)) { |
601 SkString subsetName = SkStringPrintf("%s-%s", filename, subs
etDim.c_str()); | 600 SkString subsetName = SkStringPrintf("%s-%s", filename, subs
etDim.c_str()); |
602 skiagm::BitmapAndDigest subsetBitmapAndDigest(bitmapFromDeco
deSubset); | 601 skiagm::BitmapAndDigest subsetBitmapAndDigest(bitmapFromDeco
deSubset); |
603 if (compare_to_expectations_if_necessary(subsetBitmapAndDige
st.fDigest, | 602 if (compare_to_expectations_if_necessary(subsetBitmapAndDige
st.fDigest, |
604 subsetName.c_str(), | 603 subsetName.c_str(), |
605 &gFailedSubsetDecod
es, | 604 &gFailedSubsetDecod
es, |
606 &gMissingSubsetExpe
ctations, | 605 &gMissingSubsetExpe
ctations, |
607 &gKnownSubsetFailur
es)) { | 606 &gKnownSubsetFailur
es)) { |
608 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub
set %s from %s", | 607 gSuccessfulSubsetDecodes.push_back().printf("Decoded sub
set %s from %s", |
609 subsetDim.c_str(),
srcPath); | 608 subsetDim.c_str(),
srcPath); |
610 } else if (!FLAGS_mismatchPath.isEmpty()) { | 609 } else if (!FLAGS_mismatchPath.isEmpty()) { |
611 write_subset(FLAGS_mismatchPath[0], subsetName, | 610 write_subset(FLAGS_mismatchPath[0], subsetName, |
612 subsetBitmapAndDigest, rect, bitmap); | 611 subsetBitmapAndDigest, rect, bitmap); |
613 } | 612 } |
614 | 613 |
615 write_expectations(subsetBitmapAndDigest, subsetName.c_str()
); | 614 write_expectations(subsetBitmapAndDigest, subsetName.c_str()
); |
616 | 615 |
617 if (writePath != NULL) { | 616 if (writePath != NULL) { |
618 write_subset(writePath->c_str(), subsetName, | 617 write_subset(writePath->c_str(), subsetName, |
619 subsetBitmapAndDigest, rect, bitmap); | 618 subsetBitmapAndDigest, rect, bitmap); |
620 } | 619 } |
621 } else { | 620 } else { |
622 gFailedSubsetDecodes.push_back().printf("Failed to decode re
gion %s from %s", | 621 gFailedSubsetDecodes.push_back().printf("Failed to decode re
gion %s from %s", |
623 subsetDim.c_str(), s
rcPath); | 622 subsetDim.c_str(), s
rcPath); |
624 } | 623 } |
625 } | 624 } |
626 } | 625 } |
627 } | 626 } |
628 | 627 |
629 // Do not attempt to re-encode A8, since our image encoders do not support e
ncoding to A8. | 628 // Do not attempt to re-encode A8, since our image encoders do not support e
ncoding to A8. |
630 if (FLAGS_reencode && bitmap.config() != SkBitmap::kA8_Config) { | 629 if (FLAGS_reencode && bitmap.colorType() != kAlpha_8_SkColorType) { |
631 // Encode to the format the file was originally in, or PNG if the encode
r for the same | 630 // Encode to the format the file was originally in, or PNG if the encode
r for the same |
632 // format is unavailable. | 631 // format is unavailable. |
633 SkImageDecoder::Format format = codec->getFormat(); | 632 SkImageDecoder::Format format = codec->getFormat(); |
634 if (SkImageDecoder::kUnknown_Format == format) { | 633 if (SkImageDecoder::kUnknown_Format == format) { |
635 if (stream.rewind()) { | 634 if (stream.rewind()) { |
636 format = SkImageDecoder::GetStreamFormat(&stream); | 635 format = SkImageDecoder::GetStreamFormat(&stream); |
637 } | 636 } |
638 if (SkImageDecoder::kUnknown_Format == format) { | 637 if (SkImageDecoder::kUnknown_Format == format) { |
639 const char* dot = strrchr(srcPath, '.'); | 638 const char* dot = strrchr(srcPath, '.'); |
640 if (NULL != dot) { | 639 if (NULL != dot) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 if(file.write(data->data(), data->size())) { | 676 if(file.write(data->data(), data->size())) { |
678 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_s
tr()); | 677 gSuccessfulDecodes.push_back().appendf("\twrote %s", outPath.c_s
tr()); |
679 } else { | 678 } else { |
680 gEncodeFailures.push_back().printf("Failed to write %s", outPath
.c_str()); | 679 gEncodeFailures.push_back().printf("Failed to write %s", outPath
.c_str()); |
681 } | 680 } |
682 } | 681 } |
683 // Ensure that the reencoded data can still be decoded. | 682 // Ensure that the reencoded data can still be decoded. |
684 SkMemoryStream memStream(data); | 683 SkMemoryStream memStream(data); |
685 SkBitmap redecodedBitmap; | 684 SkBitmap redecodedBitmap; |
686 SkImageDecoder::Format formatOnSecondDecode; | 685 SkImageDecoder::Format formatOnSecondDecode; |
687 if (SkImageDecoder::DecodeStream(&memStream, &redecodedBitmap, gPrefConf
ig, | 686 if (SkImageDecoder::DecodeStream(&memStream, &redecodedBitmap, gPrefColo
rType, |
688 SkImageDecoder::kDecodePixels_Mode, | 687 SkImageDecoder::kDecodePixels_Mode, |
689 &formatOnSecondDecode)) { | 688 &formatOnSecondDecode)) { |
690 SkASSERT(format_to_type(formatOnSecondDecode) == type); | 689 SkASSERT(format_to_type(formatOnSecondDecode) == type); |
691 } else { | 690 } else { |
692 gDecodeFailures.push_back().printf("Failed to redecode %s after reen
coding to '%s'", | 691 gDecodeFailures.push_back().printf("Failed to redecode %s after reen
coding to '%s'", |
693 srcPath, suffix_for_type(type)); | 692 srcPath, suffix_for_type(type)); |
694 } | 693 } |
695 } | 694 } |
696 } | 695 } |
697 | 696 |
698 /////////////////////////////////////////////////////////////////////////////// | 697 /////////////////////////////////////////////////////////////////////////////// |
699 | 698 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 append_path_separator_if_necessary(&outDir); | 764 append_path_separator_if_necessary(&outDir); |
766 outDirPtr = &outDir; | 765 outDirPtr = &outDir; |
767 } else { | 766 } else { |
768 outDirPtr = NULL; | 767 outDirPtr = NULL; |
769 } | 768 } |
770 | 769 |
771 if (FLAGS_config.count() == 1) { | 770 if (FLAGS_config.count() == 1) { |
772 // Only consider the first config specified on the command line. | 771 // Only consider the first config specified on the command line. |
773 const char* config = FLAGS_config[0]; | 772 const char* config = FLAGS_config[0]; |
774 if (0 == strcmp(config, "8888")) { | 773 if (0 == strcmp(config, "8888")) { |
775 gPrefConfig = SkBitmap::kARGB_8888_Config; | 774 gPrefColorType = kN32_SkColorType; |
776 } else if (0 == strcmp(config, "565")) { | 775 } else if (0 == strcmp(config, "565")) { |
777 gPrefConfig = SkBitmap::kRGB_565_Config; | 776 gPrefColorType = kRGB_565_SkColorType; |
778 } else if (0 == strcmp(config, "A8")) { | 777 } else if (0 == strcmp(config, "A8")) { |
779 gPrefConfig = SkBitmap::kA8_Config; | 778 gPrefColorType = kAlpha_8_SkColorType; |
780 } else if (0 != strcmp(config, "None")) { | 779 } else if (0 != strcmp(config, "None")) { |
781 SkDebugf("Invalid preferred config\n"); | 780 SkDebugf("Invalid preferred config\n"); |
782 return -1; | 781 return -1; |
783 } | 782 } |
784 } | 783 } |
785 | 784 |
786 for (int i = 0; i < FLAGS_readPath.count(); i++) { | 785 for (int i = 0; i < FLAGS_readPath.count(); i++) { |
787 const char* readPath = FLAGS_readPath[i]; | 786 const char* readPath = FLAGS_readPath[i]; |
788 if (strlen(readPath) < 1) { | 787 if (strlen(readPath) < 1) { |
789 break; | 788 break; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 print_strings("Known failures", gKnownFailures); | 833 print_strings("Known failures", gKnownFailures); |
835 | 834 |
836 return failed ? -1 : 0; | 835 return failed ? -1 : 0; |
837 } | 836 } |
838 | 837 |
839 #if !defined SK_BUILD_FOR_IOS | 838 #if !defined SK_BUILD_FOR_IOS |
840 int main(int argc, char * const argv[]) { | 839 int main(int argc, char * const argv[]) { |
841 return tool_main(argc, (char**) argv); | 840 return tool_main(argc, (char**) argv); |
842 } | 841 } |
843 #endif | 842 #endif |
OLD | NEW |