| // Copyright 2026 The PDFium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef TESTING_UTILS_PIXEL_DIFF_UTIL_H_ | |
| #define TESTING_UTILS_PIXEL_DIFF_UTIL_H_ | |
| #include <stdint.h> | |
| #include "core/fxcrt/span.h" | |
| // Standard fuzzy matching limits, duplicated in testing/tools/pngdiffer.py. | |
| // Change one without the other and fuzzy tests silently judge by the wrong | |
| // limits. | |
| inline constexpr uint8_t kMaxFuzzyPixelDelta = 3; | |
| inline constexpr double kMaxFuzzyMeanSquaredError = 0.05; | |
| inline constexpr int kMaxFuzzyWindowSize = 8; | |
| inline constexpr double kMaxFuzzyWindowMeanSquaredError = 15.0; | |
| // Fontations fuzzy matching limits: allows a larger per-channel delta to | |
| // accommodate subpixel curve antialiasing variances while enforcing a tight | |
| // mean squared error bound. | |
| inline constexpr uint8_t kMaxFontationsPixelDelta = 12; | |
| inline constexpr double kMaxFontationsMeanSquaredError = 0.20; | |
| inline constexpr int kMaxFontationsWindowSize = kMaxFuzzyWindowSize; | |
| inline constexpr double kMaxFontationsWindowMeanSquaredError = | |
| kMaxFuzzyWindowMeanSquaredError; | |
| // Options controlling pixel difference comparisons. | |
| struct DiffOptions { | |
| int max_pixel_per_channel_delta = 0; | |
| double max_mean_squared_error = 0.0; | |
| int window_size = 0; | |
| double max_window_mean_squared_error = 0.0; | |
| }; | |
| inline constexpr DiffOptions kExactDiffOptions = {}; | |
| inline constexpr DiffOptions kFuzzyDiffOptions = { | |
| .max_pixel_per_channel_delta = kMaxFuzzyPixelDelta, | |
| .max_mean_squared_error = kMaxFuzzyMeanSquaredError, | |
| .window_size = kMaxFuzzyWindowSize, | |
| .max_window_mean_squared_error = kMaxFuzzyWindowMeanSquaredError, | |
| }; | |
| inline constexpr DiffOptions kFontationsDiffOptions = { | |
| .max_pixel_per_channel_delta = kMaxFontationsPixelDelta, | |
| .max_mean_squared_error = kMaxFontationsMeanSquaredError, | |
| .window_size = kMaxFontationsWindowSize, | |
| .max_window_mean_squared_error = kMaxFontationsWindowMeanSquaredError, | |
| }; | |
| struct SSIMMetrics { | |
| double mean_ssim; | |
| double min_window_ssim; | |
| }; | |
| // Returns the largest difference in pixel channels between `baseline_pixel` and | |
| // `actual_pixel`. Pixels are expected to be in 32-bit ARGB or BGRA format. | |
| uint8_t MaxPixelPerChannelDelta(uint32_t baseline_pixel, uint32_t actual_pixel); | |
| // Returns the sum of squared differences across color channels (R, G, B) | |
| // between `baseline_pixel` and `actual_pixel`. | |
| uint32_t PixelSquaredError(uint32_t baseline_pixel, uint32_t actual_pixel); | |
| // Computes the maximum local Mean Squared Error across all overlapping | |
| // (`window_size` x `window_size`) windows between two images of dimensions | |
| // (`w`, `h`) with respective row strides in pixels (`baseline_stride_pixels`, | |
| // `actual_stride_pixels`). Pixels are in 32-bit ARGB or BGRA format. | |
| double CalculateMaxWindowMSE(pdfium::span<const uint32_t> baseline, | |
| size_t baseline_stride_pixels, | |
| pdfium::span<const uint32_t> actual, | |
| size_t actual_stride_pixels, | |
| int w, | |
| int h, | |
| int window_size); | |
| // Computes the Structural Similarity (SSIM) index across the RGB channels. | |
| // Uses an 8x8 sliding window with a step size of 4 pixels. Returns both the | |
| // global mean SSIM, and the minimum local window SSIM (worst-case match). | |
| // Values are between 0.0 and 1.0, where 1.0 indicates perfect similarity. | |
| // See https://en.wikipedia.org/wiki/Structural_similarity_index_measure | |
| SSIMMetrics CalculateSSIM(pdfium::span<const uint32_t> baseline, | |
| size_t baseline_stride_pixels, | |
| pdfium::span<const uint32_t> actual, | |
| size_t actual_stride_pixels, | |
| int w, | |
| int h); | |
| // Returns the number of differing pixels between `baseline` and `actual` within | |
| // the overlap region of dimensions (`w`, `h`), taking into account maximum | |
| // per-channel delta, global mean squared error, and optional windowed mean | |
| // squared error. Pixels are in 32-bit ARGB or BGRA format. | |
| int CalculatePixelsDifferent(pdfium::span<const uint32_t> baseline, | |
| size_t baseline_stride_pixels, | |
| pdfium::span<const uint32_t> actual, | |
| size_t actual_stride_pixels, | |
| int w, | |
| int h, | |
| const DiffOptions& options = kExactDiffOptions); | |
| #endif // TESTING_UTILS_PIXEL_DIFF_UTIL_H_ |