Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / cc / test / pixel_comparator.cc
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 #include "cc/test/pixel_comparator.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10 #include "ui/gfx/geometry/rect.h"
11
12 namespace cc {
13
14 ExactPixelComparator::ExactPixelComparator(const bool discard_alpha)
15     : discard_alpha_(discard_alpha) {
16 }
17
18 bool ExactPixelComparator::Compare(const SkBitmap& actual_bmp,
19                                    const SkBitmap& expected_bmp) const {
20   // Number of pixels with an error
21   int error_pixels_count = 0;
22
23   gfx::Rect error_bounding_rect = gfx::Rect();
24
25   // Check that bitmaps have identical dimensions.
26   DCHECK(actual_bmp.width() == expected_bmp.width() &&
27          actual_bmp.height() == expected_bmp.height());
28
29   SkAutoLockPixels lock_actual_bmp(actual_bmp);
30   SkAutoLockPixels lock_expected_bmp(expected_bmp);
31
32   for (int x = 0; x < actual_bmp.width(); ++x) {
33     for (int y = 0; y < actual_bmp.height(); ++y) {
34       SkColor actual_color = actual_bmp.getColor(x, y);
35       SkColor expected_color = expected_bmp.getColor(x, y);
36       if (discard_alpha_) {
37         actual_color = SkColorSetA(actual_color, 0);
38         expected_color = SkColorSetA(expected_color, 0);
39       }
40       if (actual_color != expected_color) {
41         ++error_pixels_count;
42         error_bounding_rect.Union(gfx::Rect(x, y, 1, 1));
43       }
44     }
45   }
46
47   if (error_pixels_count != 0) {
48     LOG(ERROR) << "Number of pixel with an error: " << error_pixels_count;
49     LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString();
50     return false;
51   }
52
53   return true;
54 }
55
56 FuzzyPixelComparator::FuzzyPixelComparator(
57     const bool discard_alpha,
58     const float error_pixels_percentage_limit,
59     const float small_error_pixels_percentage_limit,
60     const float avg_abs_error_limit,
61     const int max_abs_error_limit,
62     const int small_error_threshold)
63     : discard_alpha_(discard_alpha),
64       error_pixels_percentage_limit_(error_pixels_percentage_limit),
65       small_error_pixels_percentage_limit_(small_error_pixels_percentage_limit),
66       avg_abs_error_limit_(avg_abs_error_limit),
67       max_abs_error_limit_(max_abs_error_limit),
68       small_error_threshold_(small_error_threshold) {
69 }
70
71 bool FuzzyPixelComparator::Compare(const SkBitmap& actual_bmp,
72                                    const SkBitmap& expected_bmp) const {
73   // Number of pixels with an error
74   int error_pixels_count = 0;
75   // Number of pixels with a small error
76   int small_error_pixels_count = 0;
77   // The per channel sums of absolute errors over all pixels.
78   int64 sum_abs_error_r = 0;
79   int64 sum_abs_error_g = 0;
80   int64 sum_abs_error_b = 0;
81   int64 sum_abs_error_a = 0;
82   // The per channel maximum absolute errors over all pixels.
83   int max_abs_error_r = 0;
84   int max_abs_error_g = 0;
85   int max_abs_error_b = 0;
86   int max_abs_error_a = 0;
87
88   gfx::Rect error_bounding_rect = gfx::Rect();
89
90   // Check that bitmaps have identical dimensions.
91   DCHECK(actual_bmp.width() == expected_bmp.width() &&
92          actual_bmp.height() == expected_bmp.height());
93
94   // Check that bitmaps are not empty.
95   DCHECK(actual_bmp.width() > 0 && actual_bmp.height() > 0);
96
97   SkAutoLockPixels lock_actual_bmp(actual_bmp);
98   SkAutoLockPixels lock_expected_bmp(expected_bmp);
99
100   for (int x = 0; x < actual_bmp.width(); ++x) {
101     for (int y = 0; y < actual_bmp.height(); ++y) {
102       SkColor actual_color = actual_bmp.getColor(x, y);
103       SkColor expected_color = expected_bmp.getColor(x, y);
104       if (discard_alpha_) {
105         actual_color = SkColorSetA(actual_color, 0);
106         expected_color = SkColorSetA(expected_color, 0);
107       }
108
109       if (actual_color != expected_color) {
110         ++error_pixels_count;
111
112         // Compute per channel errors
113         int error_r = SkColorGetR(actual_color) - SkColorGetR(expected_color);
114         int error_g = SkColorGetG(actual_color) - SkColorGetG(expected_color);
115         int error_b = SkColorGetB(actual_color) - SkColorGetB(expected_color);
116         int error_a = SkColorGetA(actual_color) - SkColorGetA(expected_color);
117         int abs_error_r = std::abs(error_r);
118         int abs_error_g = std::abs(error_g);
119         int abs_error_b = std::abs(error_b);
120         int abs_error_a = std::abs(error_a);
121
122         // Increment small error counter if error is below threshold
123         if (abs_error_r <= small_error_threshold_ &&
124             abs_error_g <= small_error_threshold_ &&
125             abs_error_b <= small_error_threshold_ &&
126             abs_error_a <= small_error_threshold_)
127           ++small_error_pixels_count;
128
129         // Update per channel maximum absolute errors
130         max_abs_error_r = std::max(max_abs_error_r, abs_error_r);
131         max_abs_error_g = std::max(max_abs_error_g, abs_error_g);
132         max_abs_error_b = std::max(max_abs_error_b, abs_error_b);
133         max_abs_error_a = std::max(max_abs_error_a, abs_error_a);
134
135         // Update per channel absolute error sums
136         sum_abs_error_r += abs_error_r;
137         sum_abs_error_g += abs_error_g;
138         sum_abs_error_b += abs_error_b;
139         sum_abs_error_a += abs_error_a;
140       }
141     }
142   }
143
144   // Compute error metrics from collected data
145   int pixels_count = actual_bmp.width() * actual_bmp.height();
146   float error_pixels_percentage = 0.0f;
147   float small_error_pixels_percentage = 0.0f;
148   if (pixels_count > 0) {
149     error_pixels_percentage = static_cast<float>(error_pixels_count) /
150         pixels_count * 100.0f;
151     small_error_pixels_percentage =
152         static_cast<float>(small_error_pixels_count) / pixels_count * 100.0f;
153   }
154   float avg_abs_error_r = 0.0f;
155   float avg_abs_error_g = 0.0f;
156   float avg_abs_error_b = 0.0f;
157   float avg_abs_error_a = 0.0f;
158   if (error_pixels_count > 0) {
159     avg_abs_error_r = static_cast<float>(sum_abs_error_r) / error_pixels_count;
160     avg_abs_error_g = static_cast<float>(sum_abs_error_g) / error_pixels_count;
161     avg_abs_error_b = static_cast<float>(sum_abs_error_b) / error_pixels_count;
162     avg_abs_error_a = static_cast<float>(sum_abs_error_a) / error_pixels_count;
163   }
164
165   if (error_pixels_percentage > error_pixels_percentage_limit_ ||
166       small_error_pixels_percentage > small_error_pixels_percentage_limit_ ||
167       avg_abs_error_r > avg_abs_error_limit_ ||
168       avg_abs_error_g > avg_abs_error_limit_ ||
169       avg_abs_error_b > avg_abs_error_limit_ ||
170       avg_abs_error_a > avg_abs_error_limit_ ||
171       max_abs_error_r > max_abs_error_limit_ ||
172       max_abs_error_g > max_abs_error_limit_ ||
173       max_abs_error_b > max_abs_error_limit_ ||
174       max_abs_error_a > max_abs_error_limit_) {
175     LOG(ERROR) << "Percentage of pixels with an error: "
176                << error_pixels_percentage;
177     LOG(ERROR) << "Percentage of pixels with errors not greater than "
178                << small_error_threshold_ << ": "
179                << small_error_pixels_percentage;
180     LOG(ERROR) << "Average absolute error (excluding identical pixels): "
181                << "R=" << avg_abs_error_r << " "
182                << "G=" << avg_abs_error_g << " "
183                << "B=" << avg_abs_error_b << " "
184                << "A=" << avg_abs_error_a;
185     LOG(ERROR) << "Largest absolute error: "
186                << "R=" << max_abs_error_r << " "
187                << "G=" << max_abs_error_g << " "
188                << "B=" << max_abs_error_b << " "
189                << "A=" << max_abs_error_a;
190
191       for (int x = 0; x < actual_bmp.width(); ++x) {
192         for (int y = 0; y < actual_bmp.height(); ++y) {
193           SkColor actual_color = actual_bmp.getColor(x, y);
194           SkColor expected_color = expected_bmp.getColor(x, y);
195           if (discard_alpha_) {
196             actual_color = SkColorSetA(actual_color, 0);
197             expected_color = SkColorSetA(expected_color, 0);
198           }
199           if (actual_color != expected_color)
200             error_bounding_rect.Union(gfx::Rect(x, y, 1, 1));
201         }
202       }
203       LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString();
204     return false;
205   } else {
206     return true;
207   }
208 }
209
210 }  // namespace cc