1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CC_TEST_PIXEL_COMPARATOR_H_
6 #define CC_TEST_PIXEL_COMPARATOR_H_
7 
8 #include "base/compiler_specific.h"
9 #include "third_party/skia/include/core/SkBitmap.h"
10 
11 namespace cc {
12 
13 // Interface for pixel comparators.
14 class PixelComparator {
15  public:
16   virtual ~PixelComparator() = default;
17 
18   virtual bool Compare(const SkBitmap& actual_bmp,
19                        const SkBitmap& expected_bmp) const = 0;
20 };
21 
22 // Exact pixel comparator. Counts the number of pixel with an error.
23 class ExactPixelComparator : public PixelComparator {
24  public:
25   explicit ExactPixelComparator(const bool discard_alpha);
26   ~ExactPixelComparator() override = default;
27 
28   // Returns true if the two bitmaps are identical. Otherwise, returns false
29   // and report the number of pixels with an error on LOG(ERROR). Differences
30   // in the alpha channel are ignored.
31   bool Compare(const SkBitmap& actual_bmp,
32                const SkBitmap& expected_bmp) const override;
33 
34  private:
35   // Exclude alpha channel from comparison?
36   bool discard_alpha_;
37 };
38 
39 // Different platforms have slightly different pixel output, due to different
40 // graphics implementations. Slightly different pixels (in BGR space) are still
41 // counted as a matching pixel by this simple manhattan distance threshold.
42 // If, at any pixel, the sum of the absolute differences in each color component
43 // (excluding alpha) exceeds the threshold the test is failed.
44 class ManhattanDistancePixelComparator : public PixelComparator {
45  public:
46   explicit ManhattanDistancePixelComparator(int tolerance = 25);
47   ~ManhattanDistancePixelComparator() override = default;
48 
49   // Returns true if the two bitmaps are identical within the specified
50   // manhattan distance. Otherwise, returns false and report the first pixel
51   // that differed by more than the tolerance distance using a LOG(ERROR).
52   // Differences in the alpha channel are ignored.
53   bool Compare(const SkBitmap& actual_bmp,
54                const SkBitmap& expected_bmp) const override;
55 
56  private:
57   const int tolerance_;
58 };
59 
60 // Fuzzy pixel comparator. Counts small and arbitrary errors separately and
61 // computes average and maximum absolute errors per color channel.
62 class FuzzyPixelComparator : public PixelComparator {
63  public:
64   FuzzyPixelComparator(bool discard_alpha,
65                        float error_pixels_percentage_limit,
66                        float small_error_pixels_percentage_limit,
67                        float avg_abs_error_limit,
68                        int max_abs_error_limit,
69                        int small_error_threshold,
70                        bool check_critical_error = true);
71   ~FuzzyPixelComparator() override = default;
72 
73   // Computes error metrics and returns true if the errors don't exceed the
74   // specified limits. Otherwise, returns false and reports the error metrics on
75   // LOG(ERROR). Differences in the alpha channel are ignored.
76   bool Compare(const SkBitmap& actual_bmp,
77                const SkBitmap& expected_bmp) const override;
78 
79  private:
80   // Exclude alpha channel from comparison?
81   bool discard_alpha_;
82   // Limit for percentage of pixels with an error.
83   float error_pixels_percentage_limit_;
84   // Limit for percentage of pixels with a small error.
85   float small_error_pixels_percentage_limit_;
86   // Limit for average absolute error (excluding identical pixels).
87   float avg_abs_error_limit_;
88   // Limit for largest absolute error.
89   int max_abs_error_limit_;
90   // Threshold for small errors.
91   int small_error_threshold_;
92   // If true, comparator will report critical errors. For example:
93   // alpha value goes from 0 to 1 or 256 to 255.
94   bool check_critical_error_;
95 };
96 
97 // All pixels can be off by one, but any more than that is an error.
98 class FuzzyPixelOffByOneComparator : public FuzzyPixelComparator {
99  public:
FuzzyPixelOffByOneComparator(bool discard_alpha)100   explicit FuzzyPixelOffByOneComparator(bool discard_alpha)
101       : FuzzyPixelComparator(discard_alpha, 100.f, 0.f, 1.f, 1, 0) {}
102 };
103 
104 }  // namespace cc
105 
106 #endif  // CC_TEST_PIXEL_COMPARATOR_H_
107