Skip to content

Commit

Permalink
Add fuzzy image matching tool for Linux pixel tests
Browse files Browse the repository at this point in the history
Review URL: http://codereview.chromium.org/13159


git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6444 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
agl@chromium.org committed Dec 5, 2008
1 parent e1a6d0a commit d8b258c
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
1 change: 1 addition & 0 deletions third_party/fuzzymatch/SConstruct
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Program('fuzzymatch.c', LIBS = ['lept', 'png', 'jpeg', 'tiff', 'z', 'm'])
98 changes: 98 additions & 0 deletions third_party/fuzzymatch/fuzzymatch.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/* Fuzzy pixel test matching.
*
* This is designed to compare two layout test images (RGB 800x600) and manage
* to ignore the noise caused by the font renderers choosing slightly different
* pixels.
*
* A B
* | |
* |--->delta<---|
* |
* V
* gray
* |
* V
* binary
* |
* |-------------|
* | |
* 1x3 3x1 Morphological openings
* | |
* |-----OR------|
* |
* V
* count pixels
*
* The result is that three different pixels in a row (vertically or
* horizontally) will cause the match to fail and the binary exits with code 1.
* Otherwise the binary exists with code 0.
*
* This requires leptonica to be installed. On Ubuntu do
* # apt-get install libleptonica libleptonica-dev
*
* Build with:
* % gcc -o fuzzymatch fuzzymatch.c -llept -ljpeg -ltiff -lpng -lz -lm -Wall -O2
*/

#include <unistd.h>
#include <stdio.h>
#include <leptonica/allheaders.h>

static int
usage(const char *argv0) {
fprintf(stderr, "Usage: %s <input a> <input b>\n", argv0);
return 1;
}

int
main(int argc, char **argv) {
if (argc != 3)
return usage(argv[0]);

PIX *a = pixRead(argv[1]);
PIX *b = pixRead(argv[2]);

if (!a) {
fprintf(stderr, "Failed to open %s\n", argv[1]);
return 1;
}

if (!b) {
fprintf(stderr, "Failed to open %s\n", argv[1]);
return 1;
}

if (pixGetWidth(a) != pixGetWidth(b) ||
pixGetHeight(a) != pixGetHeight(b)) {
fprintf(stderr, "Inputs are difference sizes\n");
return 1;
}

PIX *delta = pixAbsDifference(a, b);
pixInvert(delta, delta);
pixDestroy(&a);
pixDestroy(&b);

PIX *deltagray = pixConvertRGBToGray(delta, 0, 0, 0);
pixDestroy(&delta);

PIX *deltabinary = pixThresholdToBinary(deltagray, 254);

PIX *hopened = pixOpenBrick(NULL, deltabinary, 3, 1);
PIX *vopened = pixOpenBrick(NULL, deltabinary, 1, 3);
pixDestroy(&deltabinary);

PIX *opened = pixOr(NULL, hopened, vopened);
pixDestroy(&hopened);
pixDestroy(&vopened);

l_int32 count;
pixCountPixels(opened, &count, NULL);
fprintf(stderr, "%d\n", count);

return count;
}
7 changes: 7 additions & 0 deletions webkit/tools/layout_tests/layout_package/test_failures.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,10 @@ def Message():
# to the PNGs rather than the checksums.
return "Image mismatch"

class FailureFuzzyFailure(FailureWithType):
"""Image hashes didn't match."""
OUT_FILENAMES = ["-actual-win.png", "-expected.png"]

@staticmethod
def Message():
return "Fuzzy image match also failed"
7 changes: 7 additions & 0 deletions webkit/tools/layout_tests/run_webkit_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from layout_package import path_utils
from layout_package import test_failures
from layout_package import test_shell_thread
from test_types import fuzzy_image_diff
from test_types import image_diff
from test_types import test_type_base
from test_types import text_diff
Expand Down Expand Up @@ -597,6 +598,8 @@ def main(options, args):
test_runner.AddTestType(simplified_text_diff.SimplifiedTextDiff)
if not options.no_pixel_tests:
test_runner.AddTestType(image_diff.ImageDiff)
if options.fuzzy_pixel_tests:
test_runner.AddTestType(fuzzy_image_diff.FuzzyImageDiff)
has_new_failures = test_runner.Run()
logging.info("Exit status: %d" % has_new_failures)
sys.exit(has_new_failures)
Expand All @@ -606,6 +609,10 @@ def main(options, args):
option_parser.add_option("", "--no-pixel-tests", action="store_true",
default=False,
help="disable pixel-to-pixel PNG comparisons")
option_parser.add_option("", "--fuzzy-pixel-tests", action="store_true",
default=False,
help="Also use fuzzy matching to compare pixel test "
"outputs.")
option_parser.add_option("", "--results-directory",
default="layout-test-results",
help="Output results directory source dir,"
Expand Down

0 comments on commit d8b258c

Please sign in to comment.