Modified: trunk/Tools/ImageDiff/ImageDiff.cpp (284763 => 284764)
--- trunk/Tools/ImageDiff/ImageDiff.cpp 2021-10-24 18:13:21 UTC (rev 284763)
+++ trunk/Tools/ImageDiff/ImageDiff.cpp 2021-10-24 18:22:05 UTC (rev 284764)
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
* Copyright (C) 2017 Igalia S.L.
* Copyright (C) 2005, 2007, 2015 Apple Inc. All rights reserved.
* Copyright (C) 2005 Ben La Monica <[email protected]>. All rights reserved.
@@ -48,7 +49,7 @@
#define FORMAT_SIZE_T "zu"
#endif
-static int processImages(std::unique_ptr<PlatformImage>&& actualImage, std::unique_ptr<PlatformImage>&& baselineImage, float tolerance)
+static int processImages(std::unique_ptr<PlatformImage>&& actualImage, std::unique_ptr<PlatformImage>&& baselineImage, float tolerance, bool printDifference)
{
if (!actualImage->isCompatible(*baselineImage)) {
if (actualImage->width() != baselineImage->width() || actualImage->height() != baselineImage->height()) {
@@ -62,22 +63,26 @@
return EXIT_FAILURE;
}
- float difference = 100.0f;
- auto diffImage = actualImage->difference(*baselineImage, difference);
- if (difference <= tolerance)
- difference = 0.0f;
+ PlatformImage::Difference differenceData = { 100, 0, 0 };
+ auto diffImage = actualImage->difference(*baselineImage, differenceData);
+ float legacyDifference = differenceData.percentageDifference;
+ if (legacyDifference <= tolerance)
+ legacyDifference = 0.0f;
else {
- difference = roundf(difference * 100.0f) / 100.0f;
- difference = std::max<float>(difference, 0.01f); // round to 2 decimal places
+ legacyDifference = roundf(legacyDifference * 100.0f) / 100.0f;
+ legacyDifference = std::max<float>(legacyDifference, 0.01f); // round to 2 decimal places
}
- if (difference > 0.0f) {
+ if (legacyDifference > 0.0f) {
if (diffImage)
diffImage->writeAsPNGToStdout();
- fprintf(stdout, "diff: %01.2f%% failed\n", difference);
+ fprintf(stdout, "diff: %01.2f%% failed\n", legacyDifference);
} else
- fprintf(stdout, "diff: %01.2f%% passed\n", difference);
+ fprintf(stdout, "diff: %01.2f%% passed\n", legacyDifference);
+ if (printDifference)
+ fprintf(stdout, "maxDifference=%u; totalPixels=%lu\n", differenceData.maxDifference, differenceData.totalPixels);
+
return EXIT_SUCCESS;
}
@@ -90,6 +95,7 @@
float tolerance = 0.0f;
bool verbose = false;
+ bool printDifference = false;
for (int i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--tolerance")) {
@@ -111,9 +117,14 @@
continue;
}
+ if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--difference")) {
+ printDifference = true;
+ continue;
+ }
+
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
fprintf(stdout,
- "usage: ImageDiff [-h] [-t TOLERANCE] [-v] ([actualImage baselineImage] | <stdin>)\n" \
+ "usage: ImageDiff [-h] [-v] [-d] [-t TOLERANCE] ([actualImage baselineImage] | <stdin>)\n" \
"\n" \
"Reads two PNG-encoded images and compares them. If two file path arguments are supplied, \n" \
"reads from the specified files, otherwise from <stdin> where each file is preceded by \n" \
@@ -122,6 +133,7 @@
"optional arguments:\n" \
" -h, --help show this help message and exit\n" \
" -v, --verbose print diagnostic information to stderr\n" \
+ " -d, --difference print WPT-style maxDifference and totalPixels data\n" \
" -t, --tolerance TOLERANCE\n" \
" compare the images with the given tolerance\n"
);
@@ -158,7 +170,7 @@
if (verbose)
fprintf(stderr, "Comparing files actual: %s and baseline: %s\n", file1Path, file2Path);
- return processImages(std::move(actualImage), std::move(baselineImage), tolerance);
+ return processImages(std::move(actualImage), std::move(baselineImage), tolerance, printDifference);
}
}
@@ -206,7 +218,7 @@
if (actualImage && baselineImage) {
if (verbose)
fprintf(stderr, "ImageDiff: processing images\n");
- auto result = processImages(std::exchange(actualImage, { }), std::exchange(baselineImage, { }), tolerance);
+ auto result = processImages(std::exchange(actualImage, { }), std::exchange(baselineImage, { }), tolerance, printDifference);
if (result != EXIT_SUCCESS)
return result;
}
Modified: trunk/Tools/ImageDiff/PlatformImage.cpp (284763 => 284764)
--- trunk/Tools/ImageDiff/PlatformImage.cpp 2021-10-24 18:13:21 UTC (rev 284763)
+++ trunk/Tools/ImageDiff/PlatformImage.cpp 2021-10-24 18:22:05 UTC (rev 284764)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2007, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2007-2021 Apple Inc. All rights reserved.
* Copyright (C) 2005 Ben La Monica <[email protected]>. All rights reserved.
* Copyright (C) 2011 Brent Fulgham. All rights reserved.
*
@@ -40,7 +40,7 @@
&& hasAlpha() == other.hasAlpha();
}
-std::unique_ptr<PlatformImage> PlatformImage::difference(const PlatformImage& other, float& percentageDifference)
+std::unique_ptr<PlatformImage> PlatformImage::difference(const PlatformImage& other, Difference& difference)
{
size_t width = this->width();
size_t height = this->height();
@@ -47,27 +47,39 @@
// Compare the content of the 2 bitmaps
void* diffBuffer = malloc(width * height);
- float count = 0.0f;
- float sum = 0.0f;
- float maxDistance = 0.0f;
+ size_t pixelCountWithSignificantDifference = 0;
+ float legacyDistanceSum = 0.0f;
+ float legacyDistanceMax = 0.0f;
+
unsigned char* basePixel = this->pixels();
unsigned char* pixel = other.pixels();
unsigned char* diffPixel = reinterpret_cast<unsigned char*>(diffBuffer);
+
for (size_t y = 0; y < height; ++y) {
for (size_t x = 0; x < width; ++x) {
- float red = (pixel[0] - basePixel[0]) / std::max<float>(255 - basePixel[0], basePixel[0]);
+ float red = (pixel[0] - basePixel[0]) / std::max<float>(255 - basePixel[0], basePixel[0]);
float green = (pixel[1] - basePixel[1]) / std::max<float>(255 - basePixel[1], basePixel[1]);
- float blue = (pixel[2] - basePixel[2]) / std::max<float>(255 - basePixel[2], basePixel[2]);
+ float blue = (pixel[2] - basePixel[2]) / std::max<float>(255 - basePixel[2], basePixel[2]);
float alpha = (pixel[3] - basePixel[3]) / std::max<float>(255 - basePixel[3], basePixel[3]);
- float distance = sqrtf(red * red + green * green + blue * blue + alpha * alpha) / 2.0f;
+ float legacyDistance = sqrtf(red * red + green * green + blue * blue + alpha * alpha) / 2.0f;
- *diffPixel++ = static_cast<unsigned char>(distance * 255.0f);
+ *diffPixel++ = static_cast<unsigned char>(legacyDistance * 255.0f);
+
+ // WPT-style difference code.
+ if (legacyDistance) {
+ ++difference.totalPixels;
+ unsigned redDiff = std::abs(pixel[0] - basePixel[0]);
+ unsigned greenDiff = std::abs(pixel[1] - basePixel[1]);
+ unsigned blueDiff = std::abs(pixel[2] - basePixel[2]);
+ unsigned maxDiff = std::max({ redDiff, greenDiff, blueDiff });
+ difference.maxDifference = std::max(difference.maxDifference, maxDiff);
+ }
- if (distance >= 1.0f / 255.0f) {
- count += 1.0f;
- sum += distance;
- if (distance > maxDistance)
- maxDistance = distance;
+ // Legacy difference code. Note there is some built-in tolerance here.
+ if (legacyDistance >= 1.0f / 255.0f) {
+ ++pixelCountWithSignificantDifference;
+ legacyDistanceSum += legacyDistance;
+ legacyDistanceMax = std::max(legacyDistanceMax, legacyDistance);
}
basePixel += 4;
@@ -75,22 +87,22 @@
}
}
- // Compute the difference as a percentage combining both the number of different pixels and their difference amount i.e. the average distance over the entire image
- if (count > 0.0f)
- percentageDifference = 100.0f * sum / (height * width);
+ // Compute the difference as a percentage combining both the number of different pixels and their difference amount i.e. the average distance over the entire image.
+ if (pixelCountWithSignificantDifference)
+ difference.percentageDifference = 100.0f * legacyDistanceSum / (height * width);
else
- percentageDifference = 0.0f;
+ difference.percentageDifference = 0.0f;
- if (!percentageDifference) {
+ if (!pixelCountWithSignificantDifference) {
free(diffBuffer);
return nullptr;
}
- // Generate a normalized diff image if there is any difference
- if (maxDistance < 1.0f) {
+ // Generate a normalized diff image if there is any difference.
+ if (pixelCountWithSignificantDifference) {
diffPixel = reinterpret_cast<unsigned char*>(diffBuffer);
for (size_t p = 0; p < height * width; ++p)
- diffPixel[p] /= maxDistance;
+ diffPixel[p] /= legacyDistanceMax;
}
return PlatformImage::createFromDiffData(diffBuffer, width, height);