Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / screenshot_testing / SkDiffPixelsMetric_cpu.cpp
1 // Copyright 2014 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 // WARNING! This file is copied from third_party/skia/tools/skpdiff and slightly
6 // modified to be compilable outside Skia and suit chromium style. Some comments
7 // can make no sense.
8 // TODO(elizavetai): remove this file and reuse the original one in Skia
9
10 #include "chrome/browser/chromeos/login/screenshot_testing/SkDiffPixelsMetric.h"
11 #include "third_party/skia/include/core/SkBitmap.h"
12
13 bool SkDifferentPixelsMetric::diff(
14     SkBitmap* baseline,
15     SkBitmap* test,
16     const SkImageDiffer::BitmapsToCreate& bitmapsToCreate,
17     SkImageDiffer::Result* result) {
18   // Ensure the images are comparable
19   if (baseline->width() != test->width() ||
20       baseline->height() != test->height() || baseline->width() <= 0 ||
21       baseline->height() <= 0 || baseline->colorType() != test->colorType()) {
22     DCHECK(baseline->width() == test->width());
23     DCHECK(baseline->height() == test->height());
24     DCHECK(baseline->width() > 0);
25     DCHECK(baseline->height() > 0);
26     DCHECK(baseline->colorType() == test->colorType());
27     return false;
28   }
29
30   int width = baseline->width();
31   int height = baseline->height();
32   int maxRedDiff = 0;
33   int maxGreenDiff = 0;
34   int maxBlueDiff = 0;
35
36   // Prepare any bitmaps we will be filling in
37   if (bitmapsToCreate.alphaMask) {
38     result->poiAlphaMask.allocPixels(SkImageInfo::MakeA8(width, height));
39     result->poiAlphaMask.eraseARGB(SK_AlphaOPAQUE, 0, 0, 0);
40   }
41   if (bitmapsToCreate.rgbDiff) {
42     result->rgbDiffBitmap.allocPixels(SkImageInfo::Make(
43         width, height, baseline->colorType(), kPremul_SkAlphaType));
44     result->rgbDiffBitmap.eraseARGB(SK_AlphaTRANSPARENT, 0, 0, 0);
45   }
46   if (bitmapsToCreate.whiteDiff) {
47     result->whiteDiffBitmap.allocPixels(
48         SkImageInfo::MakeN32Premul(width, height));
49     result->whiteDiffBitmap.eraseARGB(SK_AlphaOPAQUE, 0, 0, 0);
50   }
51
52   // Prepare the pixels for comparison
53   result->poiCount = 0;
54   baseline->lockPixels();
55   test->lockPixels();
56   for (int y = 0; y < height; y++) {
57     // Grab a row from each image for easy comparison
58     // TODO(epoger): The code below already assumes 4 bytes per pixel, so I
59     // think
60     // we could just call getAddr32() to save a little time.
61     // OR, if we want to play it safe, call ComputeBytesPerPixel instead
62     // of assuming 4 bytes per pixel.
63     uint32_t* baselineRow = static_cast<uint32_t*>(baseline->getAddr(0, y));
64     uint32_t* testRow = static_cast<uint32_t*>(test->getAddr(0, y));
65     for (int x = 0; x < width; x++) {
66       // Compare one pixel at a time so each differing pixel can be noted
67       // TODO(epoger): This loop looks like a good place to work on performance,
68       // but we should run the code through a profiler to be sure.
69       uint32_t baselinePixel = baselineRow[x];
70       uint32_t testPixel = testRow[x];
71       if (baselinePixel != testPixel) {
72         result->poiCount++;
73
74         int redDiff = abs(static_cast<int>(SkColorGetR(baselinePixel) -
75                                            SkColorGetR(testPixel)));
76         if (redDiff > maxRedDiff) {
77           maxRedDiff = redDiff;
78         }
79         int greenDiff = abs(static_cast<int>(SkColorGetG(baselinePixel) -
80                                              SkColorGetG(testPixel)));
81         if (greenDiff > maxGreenDiff) {
82           maxGreenDiff = greenDiff;
83         }
84         int blueDiff = abs(static_cast<int>(SkColorGetB(baselinePixel) -
85                                             SkColorGetB(testPixel)));
86         if (blueDiff > maxBlueDiff) {
87           maxBlueDiff = blueDiff;
88         }
89
90         if (bitmapsToCreate.alphaMask) {
91           *result->poiAlphaMask.getAddr8(x, y) = SK_AlphaTRANSPARENT;
92         }
93         if (bitmapsToCreate.rgbDiff) {
94           *result->rgbDiffBitmap.getAddr32(x, y) =
95               SkColorSetRGB(redDiff, greenDiff, blueDiff);
96         }
97         if (bitmapsToCreate.whiteDiff) {
98           *result->whiteDiffBitmap.getAddr32(x, y) = SK_ColorWHITE;
99         }
100       }
101     }
102   }
103   test->unlockPixels();
104   baseline->unlockPixels();
105
106   result->maxRedDiff = maxRedDiff;
107   result->maxGreenDiff = maxGreenDiff;
108   result->maxBlueDiff = maxBlueDiff;
109
110   if (bitmapsToCreate.alphaMask) {
111     result->poiAlphaMask.unlockPixels();
112   }
113   if (bitmapsToCreate.rgbDiff) {
114     result->rgbDiffBitmap.unlockPixels();
115   }
116   if (bitmapsToCreate.whiteDiff) {
117     result->whiteDiffBitmap.unlockPixels();
118   }
119
120   // Calculates the percentage of identical pixels
121   result->result = 1.0 - ((double)result->poiCount / (width * height));
122
123   return true;
124 }