diff options
author | Andras Becsi <andras.becsi@digia.com> | 2014-03-18 13:16:26 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-03-20 15:55:39 +0100 |
commit | 3f0f86b0caed75241fa71c95a5d73bc0164348c5 (patch) | |
tree | 92b9fb00f2e9e90b0be2262093876d4f43b6cd13 /chromium/tools/imagediff | |
parent | e90d7c4b152c56919d963987e2503f9909a666d2 (diff) | |
download | qtwebengine-chromium-3f0f86b0caed75241fa71c95a5d73bc0164348c5.tar.gz |
Update to new stable branch 1750
This also includes an updated ninja and chromium dependencies
needed on Windows.
Change-Id: Icd597d80ed3fa4425933c9f1334c3c2e31291c42
Reviewed-by: Zoltan Arvai <zarvai@inf.u-szeged.hu>
Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Diffstat (limited to 'chromium/tools/imagediff')
-rw-r--r-- | chromium/tools/imagediff/image_diff.cc | 106 |
1 files changed, 87 insertions, 19 deletions
diff --git a/chromium/tools/imagediff/image_diff.cc b/chromium/tools/imagediff/image_diff.cc index 8d31795446a..604f27e88df 100644 --- a/chromium/tools/imagediff/image_diff.cc +++ b/chromium/tools/imagediff/image_diff.cc @@ -15,6 +15,7 @@ #include "base/basictypes.h" #include "base/command_line.h" +#include "base/containers/hash_tables.h" #include "base/file_util.h" #include "base/files/file_path.h" #include "base/logging.h" @@ -32,6 +33,10 @@ // Causes the app to remain open, waiting for pairs of filenames on stdin. // The caller is then responsible for terminating this app. static const char kOptionPollStdin[] = "use-stdin"; +// Causes the app to additionally calculate a diff of the color histograms +// (which is resistant to shifts in layout). +static const char kOptionCompareHistograms[] = "histogram"; +// Causes the app to output an image that visualizes the difference. static const char kOptionGenerateDiff[] = "diff"; // Return codes used by this utility. @@ -91,7 +96,7 @@ class Image { // Creates the image from the given filename on disk, and returns true on // success. bool CreateFromFilename(const base::FilePath& path) { - FILE* f = file_util::OpenFile(path, "rb"); + FILE* f = base::OpenFile(path, "rb"); if (!f) return false; @@ -103,7 +108,7 @@ class Image { compressed.insert(compressed.end(), buf, buf + num_read); } - file_util::CloseFile(f); + base::CloseFile(f); if (!image_diff_png::DecodePNG(&compressed[0], compressed.size(), &data_, &w_, &h_)) { @@ -143,7 +148,7 @@ float PercentageDifferent(const Image& baseline, const Image& actual) { int w = std::min(baseline.w(), actual.w()); int h = std::min(baseline.h(), actual.h()); - // compute pixels different in the overlap + // Compute pixels different in the overlap. int pixels_different = 0; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { @@ -152,35 +157,88 @@ float PercentageDifferent(const Image& baseline, const Image& actual) { } } - // count pixels that are a difference in size as also being different + // Count pixels that are a difference in size as also being different. int max_w = std::max(baseline.w(), actual.w()); int max_h = std::max(baseline.h(), actual.h()); - - // ...pixels off the right side, but not including the lower right corner + // These pixels are off the right side, not including the lower right corner. pixels_different += (max_w - w) * h; + // These pixels are along the bottom, including the lower right corner. + pixels_different += (max_h - h) * max_w; + + // Like the WebKit ImageDiff tool, we define percentage different in terms + // of the size of the 'actual' bitmap. + float total_pixels = static_cast<float>(actual.w()) * + static_cast<float>(actual.h()); + if (total_pixels == 0) { + // When the bitmap is empty, they are 100% different. + return 100.0f; + } + return 100.0f * pixels_different / total_pixels; +} - // ...pixels along the bottom, including the lower right corner +typedef base::hash_map<uint32, int32> RgbaToCountMap; + +float HistogramPercentageDifferent(const Image& baseline, const Image& actual) { + // TODO(johnme): Consider using a joint histogram instead, as described in + // "Comparing Images Using Joint Histograms" by Pass & Zabih + // http://www.cs.cornell.edu/~rdz/papers/pz-jms99.pdf + + int w = std::min(baseline.w(), actual.w()); + int h = std::min(baseline.h(), actual.h()); + + // Count occurences of each RGBA pixel value of baseline in the overlap. + RgbaToCountMap baseline_histogram; + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + // hash_map operator[] inserts a 0 (default constructor) if key not found. + baseline_histogram[baseline.pixel_at(x, y)]++; + } + } + + // Compute pixels different in the histogram of the overlap. + int pixels_different = 0; + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + uint32 actual_rgba = actual.pixel_at(x, y); + RgbaToCountMap::iterator it = baseline_histogram.find(actual_rgba); + if (it != baseline_histogram.end() && it->second > 0) + it->second--; + else + pixels_different++; + } + } + + // Count pixels that are a difference in size as also being different. + int max_w = std::max(baseline.w(), actual.w()); + int max_h = std::max(baseline.h(), actual.h()); + // These pixels are off the right side, not including the lower right corner. + pixels_different += (max_w - w) * h; + // These pixels are along the bottom, including the lower right corner. pixels_different += (max_h - h) * max_w; // Like the WebKit ImageDiff tool, we define percentage different in terms // of the size of the 'actual' bitmap. float total_pixels = static_cast<float>(actual.w()) * static_cast<float>(actual.h()); - if (total_pixels == 0) - return 100.0f; // when the bitmap is empty, they are 100% different - return static_cast<float>(pixels_different) / total_pixels * 100; + if (total_pixels == 0) { + // When the bitmap is empty, they are 100% different. + return 100.0f; + } + return 100.0f * pixels_different / total_pixels; } void PrintHelp() { fprintf(stderr, "Usage:\n" - " image_diff <compare file> <reference file>\n" - " Compares two files on disk, returning 0 when they are the same\n" + " image_diff [--histogram] <compare file> <reference file>\n" + " Compares two files on disk, returning 0 when they are the same;\n" + " passing \"--histogram\" additionally calculates a diff of the\n" + " RGBA value histograms (which is resistant to shifts in layout)\n" " image_diff --use-stdin\n" " Stays open reading pairs of filenames from stdin, comparing them,\n" " and sending 0 to stdout when they are the same\n" " image_diff --diff <compare file> <reference file> <output file>\n" - " Compares two files on disk, outputs an image that visualizes the" + " Compares two files on disk, outputs an image that visualizes the\n" " difference to <output file>\n"); /* For unfinished webkit-like-mode (see below) "\n" @@ -192,7 +250,9 @@ void PrintHelp() { */ } -int CompareImages(const base::FilePath& file1, const base::FilePath& file2) { +int CompareImages(const base::FilePath& file1, + const base::FilePath& file2, + bool compare_histograms) { Image actual_image; Image baseline_image; @@ -207,16 +267,22 @@ int CompareImages(const base::FilePath& file1, const base::FilePath& file2) { return kStatusError; } + if (compare_histograms) { + float percent = HistogramPercentageDifferent(actual_image, baseline_image); + const char* passed = percent > 0.0 ? "failed" : "passed"; + printf("histogram diff: %01.2f%% %s\n", percent, passed); + } + + const char* diff_name = compare_histograms ? "exact diff" : "diff"; float percent = PercentageDifferent(actual_image, baseline_image); + const char* passed = percent > 0.0 ? "failed" : "passed"; + printf("%s: %01.2f%% %s\n", diff_name, percent, passed); if (percent > 0.0) { // failure: The WebKit version also writes the difference image to // stdout, which seems excessive for our needs. - printf("diff: %01.2f%% failed\n", percent); return kStatusDifferent; } - // success - printf("diff: %01.2f%% passed\n", percent); return kStatusSame; /* Untested mode that acts like WebKit's image comparator. I wrote this but @@ -341,6 +407,7 @@ int main(int argc, const char* argv[]) { base::EnableTerminationOnHeapCorruption(); CommandLine::Init(argc, argv); const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); + bool histograms = parsed_command_line.HasSwitch(kOptionCompareHistograms); if (parsed_command_line.HasSwitch(kOptionPollStdin)) { // Watch stdin for filenames. std::string stdin_buffer; @@ -352,7 +419,7 @@ int main(int argc, const char* argv[]) { if (!filename1.empty()) { // CompareImages writes results to stdout unless an error occurred. base::FilePath filename2 = FilePathFromASCII(stdin_buffer); - if (CompareImages(filename1, filename2) == kStatusError) + if (CompareImages(filename1, filename2, histograms) == kStatusError) printf("error\n"); fflush(stdout); filename1 = base::FilePath(); @@ -373,7 +440,8 @@ int main(int argc, const char* argv[]) { base::FilePath(args[2])); } } else if (args.size() == 2) { - return CompareImages(base::FilePath(args[0]), base::FilePath(args[1])); + return CompareImages( + base::FilePath(args[0]), base::FilePath(args[1]), histograms); } PrintHelp(); |