File: image_visual_diff.cc

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (80 lines) | stat: -rw-r--r-- 2,274 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <cstdlib>

#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"

namespace {

// Calculates how different two colors are, by comparing how far apart each of
// the RGBA channels are (in terms of percentages) and averaging that across all
// channels.
float ColorPercentDiff(SkColor color1, SkColor color2) {
  float diff_red =
      std::abs(static_cast<float>(SkColorGetR(color1)) - SkColorGetR(color2)) /
      255.0f;
  float diff_green =
      std::abs(static_cast<float>(SkColorGetG(color1)) - SkColorGetG(color2)) /
      255.0f;
  float diff_blue =
      std::abs(static_cast<float>(SkColorGetB(color1)) - SkColorGetB(color2)) /
      255.0f;
  float diff_alpha =
      std::abs(static_cast<float>(SkColorGetA(color1)) - SkColorGetA(color2)) /
      255.0f;

  return (diff_red + diff_green + diff_blue + diff_alpha) / 4.0f;
}

}  // namespace

namespace web_app {

bool HasMoreThanTenPercentImageDiff(const SkBitmap* before,
                                    const SkBitmap* after) {
  const bool before_null_or_empty = (before == nullptr || before->empty());
  const bool after_null_or_empty = (after == nullptr || after->empty());

  if (before_null_or_empty && after_null_or_empty) {
    return false;
  }
  if (before_null_or_empty || after_null_or_empty) {
    return true;
  }

  if (before->width() != after->width() ||
      before->height() != after->height()) {
    return true;
  }

  if (before->colorType() != after->colorType()) {
    return true;
  }

  float difference = 0;
  float num_pixels = static_cast<float>(before->height()) * before->width();
  if (num_pixels == 0) {
    return false;
  }

  // 10% of the total pixels that form the image
  const float max_allowed_pixel_difference = 0.10f * num_pixels;

  for (int y = 0; y < before->height(); ++y) {
    for (int x = 0; x < before->width(); ++x) {
      difference +=
          ColorPercentDiff(before->getColor(x, y), after->getColor(x, y));

      if (difference >= max_allowed_pixel_difference) {
        return true;
      }
    }
  }

  return false;
}

}  // namespace web_app