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