⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 284764 in webkit


Ignore:
Timestamp:
Oct 24, 2021, 11:22:05 AM (5 years ago)
Author:
Simon Fraser
Message:

Add an ImageDiff option to print out WPT-style pixel differences
https://bugs.webkit.org/show_bug.cgi?id=232212

Reviewed by NOBODY (OOPS!).

When passed --difference, ImageDiff will compute and print out the "maxDifference=;totalPixels="
values documented at https://web-platform-tests.org/writing-tests/reftests.html. With these values,
there is no built-in tolerance as there is with the legacy difference computation.

Rename variables related to the legacy computation.

  • ImageDiff/ImageDiff.cpp:

(processImages):
(main):

  • ImageDiff/PlatformImage.cpp:

(ImageDiff::PlatformImage::difference):

  • ImageDiff/PlatformImage.h:
Location:
trunk/Tools
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r284762 r284764  
     12021-10-23  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Add an ImageDiff option to print out WPT-style pixel differences
     4        https://bugs.webkit.org/show_bug.cgi?id=232212
     5
     6        Reviewed by Darin Adler.
     7       
     8        When passed `--difference`, ImageDiff will compute and print out the "maxDifference=;totalPixels="
     9        values documented at https://web-platform-tests.org/writing-tests/reftests.html. With these values,
     10        there is no built-in tolerance as there is with the legacy difference computation.
     11
     12        Rename variables related to the legacy computation.
     13
     14        * ImageDiff/ImageDiff.cpp:
     15        (processImages):
     16        (main):
     17        * ImageDiff/PlatformImage.cpp:
     18        (ImageDiff::PlatformImage::difference):
     19        * ImageDiff/PlatformImage.h:
     20
    1212021-10-24  Simon Fraser  <simon.fraser@apple.com>
    222
  • trunk/Tools/ImageDiff/ImageDiff.cpp

    r284762 r284764  
    11/*
     2 * Copyright (C) 2021 Apple Inc. All rights reserved.
    23 * Copyright (C) 2017 Igalia S.L.
    34 * Copyright (C) 2005, 2007, 2015 Apple Inc. All rights reserved.
     
    4950#endif
    5051
    51 static int processImages(std::unique_ptr<PlatformImage>&& actualImage, std::unique_ptr<PlatformImage>&& baselineImage, float tolerance)
     52static int processImages(std::unique_ptr<PlatformImage>&& actualImage, std::unique_ptr<PlatformImage>&& baselineImage, float tolerance, bool printDifference)
    5253{
    5354    if (!actualImage->isCompatible(*baselineImage)) {
     
    6364    }
    6465
    65     float difference = 100.0f;
    66     auto diffImage = actualImage->difference(*baselineImage, difference);
    67     if (difference <= tolerance)
    68         difference = 0.0f;
     66    PlatformImage::Difference differenceData = { 100, 0, 0 };
     67    auto diffImage = actualImage->difference(*baselineImage, differenceData);
     68    float legacyDifference = differenceData.percentageDifference;
     69    if (legacyDifference <= tolerance)
     70        legacyDifference = 0.0f;
    6971    else {
    70         difference = roundf(difference * 100.0f) / 100.0f;
    71         difference = std::max<float>(difference, 0.01f); // round to 2 decimal places
    72     }
    73 
    74     if (difference > 0.0f) {
     72        legacyDifference = roundf(legacyDifference * 100.0f) / 100.0f;
     73        legacyDifference = std::max<float>(legacyDifference, 0.01f); // round to 2 decimal places
     74    }
     75
     76    if (legacyDifference > 0.0f) {
    7577        if (diffImage)
    7678            diffImage->writeAsPNGToStdout();
    77         fprintf(stdout, "diff: %01.2f%% failed\n", difference);
     79        fprintf(stdout, "diff: %01.2f%% failed\n", legacyDifference);
    7880    } else
    79         fprintf(stdout, "diff: %01.2f%% passed\n", difference);
     81        fprintf(stdout, "diff: %01.2f%% passed\n", legacyDifference);
     82
     83    if (printDifference)
     84        fprintf(stdout, "maxDifference=%u; totalPixels=%lu\n", differenceData.maxDifference, differenceData.totalPixels);
    8085
    8186    return EXIT_SUCCESS;
     
    9196    float tolerance = 0.0f;
    9297    bool verbose = false;
     98    bool printDifference = false;
    9399
    94100    for (int i = 1; i < argc; ++i) {
     
    112118        }
    113119
     120        if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--difference")) {
     121            printDifference = true;
     122            continue;
     123        }
     124
    114125        if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
    115126            fprintf(stdout,
    116                 "usage: ImageDiff [-h] [-t TOLERANCE] [-v] ([actualImage baselineImage] | <stdin>)\n" \
     127                "usage: ImageDiff [-h] [-v] [-d] [-t TOLERANCE] ([actualImage baselineImage] | <stdin>)\n" \
    117128                "\n" \
    118129                "Reads two PNG-encoded images and compares them. If two file path arguments are supplied, \n" \
     
    123134                "  -h, --help            show this help message and exit\n" \
    124135                "  -v, --verbose         print diagnostic information to stderr\n" \
     136                "  -d, --difference      print WPT-style maxDifference and totalPixels data\n" \
    125137                "  -t, --tolerance TOLERANCE\n" \
    126138                "                        compare the images with the given tolerance\n"
     
    159171                fprintf(stderr, "Comparing files actual: %s and baseline: %s\n", file1Path, file2Path);
    160172
    161             return processImages(std::move(actualImage), std::move(baselineImage), tolerance);
     173            return processImages(std::move(actualImage), std::move(baselineImage), tolerance, printDifference);
    162174        }
    163175    }
     
    207219            if (verbose)
    208220                fprintf(stderr, "ImageDiff: processing images\n");
    209             auto result = processImages(std::exchange(actualImage, { }), std::exchange(baselineImage, { }), tolerance);
     221            auto result = processImages(std::exchange(actualImage, { }), std::exchange(baselineImage, { }), tolerance, printDifference);
    210222            if (result != EXIT_SUCCESS)
    211223                return result;
  • trunk/Tools/ImageDiff/PlatformImage.cpp

    r216576 r284764  
    11/*
    2  * Copyright (C) 2005, 2007, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2005, 2007-2021 Apple Inc. All rights reserved.
    33 * Copyright (C) 2005 Ben La Monica <ben.lamonica@gmail.com>.  All rights reserved.
    44 * Copyright (C) 2011 Brent Fulgham. All rights reserved.
     
    4141}
    4242
    43 std::unique_ptr<PlatformImage> PlatformImage::difference(const PlatformImage& other, float& percentageDifference)
     43std::unique_ptr<PlatformImage> PlatformImage::difference(const PlatformImage& other, Difference& difference)
    4444{
    4545    size_t width = this->width();
     
    4848    // Compare the content of the 2 bitmaps
    4949    void* diffBuffer = malloc(width * height);
    50     float count = 0.0f;
    51     float sum = 0.0f;
    52     float maxDistance = 0.0f;
     50    size_t pixelCountWithSignificantDifference = 0;
     51    float legacyDistanceSum = 0.0f;
     52    float legacyDistanceMax = 0.0f;
     53
    5354    unsigned char* basePixel = this->pixels();
    5455    unsigned char* pixel = other.pixels();
    5556    unsigned char* diffPixel = reinterpret_cast<unsigned char*>(diffBuffer);
     57
    5658    for (size_t y = 0; y < height; ++y) {
    5759        for (size_t x = 0; x < width; ++x) {
    58             float red = (pixel[0] - basePixel[0]) / std::max<float>(255 - basePixel[0], basePixel[0]);
     60            float red   = (pixel[0] - basePixel[0]) / std::max<float>(255 - basePixel[0], basePixel[0]);
    5961            float green = (pixel[1] - basePixel[1]) / std::max<float>(255 - basePixel[1], basePixel[1]);
    60             float blue = (pixel[2] - basePixel[2]) / std::max<float>(255 - basePixel[2], basePixel[2]);
     62            float blue  = (pixel[2] - basePixel[2]) / std::max<float>(255 - basePixel[2], basePixel[2]);
    6163            float alpha = (pixel[3] - basePixel[3]) / std::max<float>(255 - basePixel[3], basePixel[3]);
    62             float distance = sqrtf(red * red + green * green + blue * blue + alpha * alpha) / 2.0f;
     64            float legacyDistance = sqrtf(red * red + green * green + blue * blue + alpha * alpha) / 2.0f;
    6365
    64             *diffPixel++ = static_cast<unsigned char>(distance * 255.0f);
     66            *diffPixel++ = static_cast<unsigned char>(legacyDistance * 255.0f);
     67           
     68            // WPT-style difference code.
     69            if (legacyDistance) {
     70                ++difference.totalPixels;
     71                unsigned redDiff    = std::abs(pixel[0] - basePixel[0]);
     72                unsigned greenDiff  = std::abs(pixel[1] - basePixel[1]);
     73                unsigned blueDiff   = std::abs(pixel[2] - basePixel[2]);
     74                unsigned maxDiff = std::max({ redDiff, greenDiff, blueDiff });
     75                difference.maxDifference = std::max(difference.maxDifference, maxDiff);
     76            }
    6577
    66             if (distance >= 1.0f / 255.0f) {
    67                 count += 1.0f;
    68                 sum += distance;
    69                 if (distance > maxDistance)
    70                     maxDistance = distance;
     78            // Legacy difference code. Note there is some built-in tolerance here.
     79            if (legacyDistance >= 1.0f / 255.0f) {
     80                ++pixelCountWithSignificantDifference;
     81                legacyDistanceSum += legacyDistance;
     82                legacyDistanceMax = std::max(legacyDistanceMax, legacyDistance);
    7183            }
    7284
     
    7688    }
    7789
    78     // 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
    79     if (count > 0.0f)
    80         percentageDifference = 100.0f * sum / (height * width);
     90    // 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.
     91    if (pixelCountWithSignificantDifference)
     92        difference.percentageDifference = 100.0f * legacyDistanceSum / (height * width);
    8193    else
    82         percentageDifference = 0.0f;
     94        difference.percentageDifference = 0.0f;
    8395
    84     if (!percentageDifference) {
     96    if (!pixelCountWithSignificantDifference) {
    8597        free(diffBuffer);
    8698        return nullptr;
    8799    }
    88100
    89     // Generate a normalized diff image if there is any difference
    90     if (maxDistance < 1.0f) {
     101    // Generate a normalized diff image if there is any difference.
     102    if (pixelCountWithSignificantDifference) {
    91103        diffPixel = reinterpret_cast<unsigned char*>(diffBuffer);
    92104        for (size_t p = 0; p < height * width; ++p)
    93             diffPixel[p] /= maxDistance;
     105            diffPixel[p] /= legacyDistanceMax;
    94106    }
    95107
  • trunk/Tools/ImageDiff/PlatformImage.h

    r284762 r284764  
    5252    size_t rowBytes() const;
    5353    bool hasAlpha() const;
     54
    5455    unsigned char* pixels() const;
    5556    bool isCompatible(const PlatformImage&) const;
    56     std::unique_ptr<PlatformImage> difference(const PlatformImage&, float& percentageDifference);
     57
     58    struct Difference {
     59        float percentageDifference { 0 }; // Legacy different measure.
     60
     61        // WPT-style difference: https://web-platform-tests.org/writing-tests/reftests.html.
     62        unsigned maxDifference { 0 };
     63        size_t totalPixels { 0 };
     64    };
     65    std::unique_ptr<PlatformImage> difference(const PlatformImage&, Difference&);
     66
    5767    void writeAsPNGToStdout();
    5868
Note: See TracChangeset for help on using the changeset viewer.