1e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com/* 2e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com * Copyright 2012 Google Inc. 3e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com * 4e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com * Use of this source code is governed by a BSD-style license that can be 5e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com * found in the LICENSE file. 6e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com */ 7e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 8e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com#include "skdiff.h" 9e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com#include "SkBitmap.h" 10e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com#include "SkColor.h" 11e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com#include "SkColorPriv.h" 12e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com#include "SkTypes.h" 13e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 14e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com/*static*/ char const * const DiffRecord::ResultNames[DiffRecord::kResultCount] = { 15e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "EqualBits", 16e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "EqualPixels", 17e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "DifferentPixels", 18e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "DifferentSizes", 19e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "CouldNotCompare", 20e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "Unknown", 21e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com}; 22e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 23e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comDiffRecord::Result DiffRecord::getResultByName(const char *name) { 24e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com for (int result = 0; result < DiffRecord::kResultCount; ++result) { 25e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (0 == strcmp(DiffRecord::ResultNames[result], name)) { 26e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return static_cast<DiffRecord::Result>(result); 27e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 28e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 29e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return DiffRecord::kResultCount; 30e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com} 31e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 32e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comstatic char const * const ResultDescriptions[DiffRecord::kResultCount] = { 33e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "contain exactly the same bits", 34e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "contain the same pixel values, but not the same bits", 35e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "have identical dimensions but some differing pixels", 36e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "have differing dimensions", 37e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "could not be compared", 38e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "not compared yet", 39e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com}; 40e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 41e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comconst char* DiffRecord::getResultDescription(DiffRecord::Result result) { 42e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return ResultDescriptions[result]; 43e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com} 44e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 45e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com/*static*/ char const * const DiffResource::StatusNames[DiffResource::kStatusCount] = { 46e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "Decoded", 47e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "CouldNotDecode", 48e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 49e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "Read", 50e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "CouldNotRead", 51e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 52e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "Exists", 53e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "DoesNotExist", 54e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 55e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "Specified", 56e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "Unspecified", 57e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 58e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "Unknown", 59e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com}; 60e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 61e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comDiffResource::Status DiffResource::getStatusByName(const char *name) { 62e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com for (int status = 0; status < DiffResource::kStatusCount; ++status) { 63e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (0 == strcmp(DiffResource::StatusNames[status], name)) { 64e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return static_cast<DiffResource::Status>(status); 65e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 66e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 67e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return DiffResource::kStatusCount; 68e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com} 69e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 70e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comstatic char const * const StatusDescriptions[DiffResource::kStatusCount] = { 71e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "decoded", 72e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "could not be decoded", 73e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 74e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "read", 75e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "could not be read", 76e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 77e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "found", 78e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "not found", 79e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 80e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "specified", 81e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "unspecified", 82e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 83e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com "unknown", 84e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com}; 85e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 86e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comconst char* DiffResource::getStatusDescription(DiffResource::Status status) { 87e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return StatusDescriptions[status]; 88e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com} 89e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 90e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.combool DiffResource::isStatusFailed(DiffResource::Status status) { 91e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return DiffResource::kCouldNotDecode_Status == status || 92e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com DiffResource::kCouldNotRead_Status == status || 93e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com DiffResource::kDoesNotExist_Status == status || 94e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com DiffResource::kUnspecified_Status == status || 95e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com DiffResource::kUnknown_Status == status; 96e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com} 97e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 98e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.combool DiffResource::getMatchingStatuses(char* selector, bool statuses[kStatusCount]) { 99e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (!strcmp(selector, "any")) { 100e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com for (int statusIndex = 0; statusIndex < kStatusCount; ++statusIndex) { 101e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com statuses[statusIndex] = true; 102e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 103e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return true; 104e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 105e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 106e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com for (int statusIndex = 0; statusIndex < kStatusCount; ++statusIndex) { 107e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com statuses[statusIndex] = false; 108e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 109e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 110e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com static const char kDelimiterChar = ','; 111e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com bool understood = true; 112e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com while (true) { 113e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com char* delimiterPtr = strchr(selector, kDelimiterChar); 114e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 115e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (delimiterPtr) { 116e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com *delimiterPtr = '\0'; 117e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 118e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 119e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (!strcmp(selector, "failed")) { 120e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com for (int statusIndex = 0; statusIndex < kStatusCount; ++statusIndex) { 121e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com Status status = static_cast<Status>(statusIndex); 122e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com statuses[statusIndex] |= isStatusFailed(status); 123e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 124e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } else { 125e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com Status status = getStatusByName(selector); 126e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (status == kStatusCount) { 127e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com understood = false; 128e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } else { 129e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com statuses[status] = true; 130e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 131e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 132e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 133e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (!delimiterPtr) { 134e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com break; 135e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 136e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 137e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com *delimiterPtr = kDelimiterChar; 138e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com selector = delimiterPtr + 1; 139e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 140e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return understood; 141e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com} 142e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 143e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comstatic inline bool colors_match_thresholded(SkPMColor c0, SkPMColor c1, const int threshold) { 144e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int da = SkGetPackedA32(c0) - SkGetPackedA32(c1); 145e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int dr = SkGetPackedR32(c0) - SkGetPackedR32(c1); 146e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int dg = SkGetPackedG32(c0) - SkGetPackedG32(c1); 147e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int db = SkGetPackedB32(c0) - SkGetPackedB32(c1); 148e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 149e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return ((SkAbs32(da) <= threshold) && 150e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com (SkAbs32(dr) <= threshold) && 151e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com (SkAbs32(dg) <= threshold) && 152e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com (SkAbs32(db) <= threshold)); 153e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com} 154e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 155e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comconst SkPMColor PMCOLOR_WHITE = SkPreMultiplyColor(SK_ColorWHITE); 156e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comconst SkPMColor PMCOLOR_BLACK = SkPreMultiplyColor(SK_ColorBLACK); 157e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 158e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.comvoid compute_diff(DiffRecord* dr, DiffMetricProc diffFunction, const int colorThreshold) { 159e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com const int w = dr->fComparison.fBitmap.width(); 160e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com const int h = dr->fComparison.fBitmap.height(); 161e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (w != dr->fBase.fBitmap.width() || h != dr->fBase.fBitmap.height()) { 162e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fResult = DiffRecord::kDifferentSizes_Result; 163e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return; 164e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 165e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 166e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com SkAutoLockPixels alpDiff(dr->fDifference.fBitmap); 167e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com SkAutoLockPixels alpWhite(dr->fWhite.fBitmap); 168e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int mismatchedPixels = 0; 169ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com int totalMismatchA = 0; 170e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int totalMismatchR = 0; 171e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int totalMismatchG = 0; 172e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int totalMismatchB = 0; 173e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com 174e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com // Accumulate fractionally different pixels, then divide out 175e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com // # of pixels at the end. 176e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fWeightedFraction = 0; 177e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com for (int y = 0; y < h; y++) { 178e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com for (int x = 0; x < w; x++) { 179e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com SkPMColor c0 = *dr->fBase.fBitmap.getAddr32(x, y); 180e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com SkPMColor c1 = *dr->fComparison.fBitmap.getAddr32(x, y); 181e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com SkPMColor outputDifference = diffFunction(c0, c1); 182ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com uint32_t thisA = SkAbs32(SkGetPackedA32(c0) - SkGetPackedA32(c1)); 183ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com uint32_t thisR = SkAbs32(SkGetPackedR32(c0) - SkGetPackedR32(c1)); 184ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com uint32_t thisG = SkAbs32(SkGetPackedG32(c0) - SkGetPackedG32(c1)); 185ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com uint32_t thisB = SkAbs32(SkGetPackedB32(c0) - SkGetPackedB32(c1)); 186ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com totalMismatchA += thisA; 187e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com totalMismatchR += thisR; 188e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com totalMismatchG += thisG; 189e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com totalMismatchB += thisB; 190e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com // In HSV, value is defined as max RGB component. 191e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int value = MAX3(thisR, thisG, thisB); 192e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fWeightedFraction += ((float) value) / 255; 193ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com if (thisA > dr->fMaxMismatchA) { 194ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com dr->fMaxMismatchA = thisA; 195ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com } 196e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (thisR > dr->fMaxMismatchR) { 197e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fMaxMismatchR = thisR; 198e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 199e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (thisG > dr->fMaxMismatchG) { 200e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fMaxMismatchG = thisG; 201e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 202e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (thisB > dr->fMaxMismatchB) { 203e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fMaxMismatchB = thisB; 204e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 205e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (!colors_match_thresholded(c0, c1, colorThreshold)) { 206e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com mismatchedPixels++; 207e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com *dr->fDifference.fBitmap.getAddr32(x, y) = outputDifference; 208e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com *dr->fWhite.fBitmap.getAddr32(x, y) = PMCOLOR_WHITE; 209e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } else { 210e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com *dr->fDifference.fBitmap.getAddr32(x, y) = 0; 211e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com *dr->fWhite.fBitmap.getAddr32(x, y) = PMCOLOR_BLACK; 212e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 213e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 214e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 215e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com if (0 == mismatchedPixels) { 216e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fResult = DiffRecord::kEqualPixels_Result; 217e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com return; 218e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com } 219e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fResult = DiffRecord::kDifferentPixels_Result; 220e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com int pixelCount = w * h; 221e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fFractionDifference = ((float) mismatchedPixels) / pixelCount; 222e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fWeightedFraction /= pixelCount; 223ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com dr->fTotalMismatchA = totalMismatchA; 224ee5a5eee12b3befac33ed6c379f81bf749f57161rmistry@google.com dr->fAverageMismatchA = ((float) totalMismatchA) / pixelCount; 225e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fAverageMismatchR = ((float) totalMismatchR) / pixelCount; 226e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fAverageMismatchG = ((float) totalMismatchG) / pixelCount; 227e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com dr->fAverageMismatchB = ((float) totalMismatchB) / pixelCount; 228e3c8ddfd03fdf587b4d8400718ae4bb6e9aa8b6dbungeman@google.com} 229