Changeset 87367 in webkit


Ignore:
Timestamp:
May 26, 2011 12:44:43 AM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2011-05-26 Tom Hudson <tomhudson@google.com>

Reviewed by Tony Chang.

Add flags to Chromium ImageDiff to write image comparison metrics on
stdout.
https://bugs.webkit.org/show_bug.cgi?id=60569

  • DumpRenderTree/chromium/ImageDiff.cpp: (Image::createFromStdin): Fix spelling. (maxOf3): New function to do 3-way maximum. (getRedComponent): Extract red component from ABGR packed encoding. (getGreenComponent): Extract green component from ABGR packed encoding. (getBlueComponent): Extract blue component from ABGR packed encoding. (weightedPercentageDifferent): Determine % of pixels different in two images multiplied by intensity difference of each pixel. (printHelp): Document new arguments. (compareImages): Parameterize. (untestedCompareImages): Parameterize. (diffImages): Parameterize; write results on stdout if requested. (main): Parse new arguments.
Location:
trunk/Tools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r87348 r87367  
     12011-05-26  Tom Hudson  <tomhudson@google.com>
     2
     3        Reviewed by Tony Chang.
     4
     5        Add flags to Chromium ImageDiff to write image comparison metrics on
     6        stdout.
     7        https://bugs.webkit.org/show_bug.cgi?id=60569
     8
     9        * DumpRenderTree/chromium/ImageDiff.cpp:
     10        (Image::createFromStdin): Fix spelling.
     11        (maxOf3): New function to do 3-way maximum.
     12        (getRedComponent): Extract red component from ABGR packed encoding.
     13        (getGreenComponent): Extract green component from ABGR packed encoding.
     14        (getBlueComponent): Extract blue component from ABGR packed encoding.
     15        (weightedPercentageDifferent): Determine % of pixels different in two
     16        images multiplied by intensity difference of each pixel.
     17        (printHelp): Document new arguments.
     18        (compareImages): Parameterize.
     19        (untestedCompareImages): Parameterize.
     20        (diffImages): Parameterize; write results on stdout if requested.
     21        (main): Parse new arguments.
     22
    1232011-05-25  Qi Zhang  <qi.2.zhang@nokia.com>
    224
  • trunk/Tools/DumpRenderTree/chromium/ImageDiff.cpp

    r86930 r87367  
    5757static const char optionGenerateDiff[] = "--diff";
    5858
     59// If --diff is passed, causes the app to output the image difference
     60// metric (percentageDifferent()) on stdout.
     61static const char optionWrite[] = "--write-image-diff-metrics";
     62
     63// Use weightedPercentageDifferent() instead of the default image
     64// comparator proc.
     65static const char optionWeightedIntensity[] = "--weighted-intensity";
     66
    5967// Return codes used by this utility.
    6068static const int statusSame = 0;
     
    8492    // Creates the image from stdin with the given data length. On success, it
    8593    // will return true. On failure, no other methods should be accessed.
    86     bool craeteFromStdin(size_t byteLength)
     94    bool createFromStdin(size_t byteLength)
    8795    {
    8896        if (!byteLength)
     
    153161};
    154162
     163typedef float (*ImageComparisonProc) (const Image&, const Image&);
     164
    155165float percentageDifferent(const Image& baseline, const Image& actual)
    156166{
     
    160170    // Compute pixels different in the overlap
    161171    int pixelsDifferent = 0;
    162     for (int y = 0; y < h; y++) {
    163         for (int x = 0; x < w; x++) {
     172    for (int y = 0; y < h; ++y) {
     173        for (int x = 0; x < w; ++x) {
    164174            if (baseline.pixelAt(x, y) != actual.pixelAt(x, y))
    165175                pixelsDifferent++;
     
    184194    return static_cast<float>(pixelsDifferent) / totalPixels * 100;
    185195}
     196
     197inline uint32_t maxOf3(uint32_t a, uint32_t b, uint32_t c)
     198{
     199    if (a < b)
     200        return std::max(b, c);
     201    return std::max(a, c);
     202}
     203
     204inline uint32_t getRedComponent(uint32_t color)
     205{
     206    return (color << 24) >> 24;
     207}
     208
     209inline uint32_t getGreenComponent(uint32_t color)
     210{
     211    return (color << 16) >> 24;
     212}
     213
     214inline uint32_t getBlueComponent(uint32_t color)
     215{
     216    return (color << 8) >> 24;
     217}
     218
     219/// Rank small-pixel-count high-intensity changes as more important than
     220/// large-pixel-count low-intensity changes.
     221float weightedPercentageDifferent(const Image& baseline, const Image& actual)
     222{
     223    int w = min(baseline.width(), actual.width());
     224    int h = min(baseline.height(), actual.height());
     225
     226    float weightedPixelsDifferent = 0;
     227    for (int y = 0; y < h; ++y) {
     228        for (int x = 0; x < w; ++x) {
     229            uint32_t actualColor = actual.pixelAt(x, y);
     230            uint32_t baselineColor = baseline.pixelAt(x, y);
     231            if (baselineColor != actualColor) {
     232                uint32_t actualR = getRedComponent(actualColor);
     233                uint32_t actualG = getGreenComponent(actualColor);
     234                uint32_t actualB = getBlueComponent(actualColor);
     235                uint32_t baselineR = getRedComponent(baselineColor);
     236                uint32_t baselineG = getGreenComponent(baselineColor);
     237                uint32_t baselineB = getBlueComponent(baselineColor);
     238                uint32_t deltaR = std::max(actualR, baselineR)
     239                    - std::min(actualR, baselineR);
     240                uint32_t deltaG = std::max(actualG, baselineG)
     241                    - std::min(actualG, baselineG);
     242                uint32_t deltaB = std::max(actualB, baselineB)
     243                    - std::min(actualB, baselineB);
     244                weightedPixelsDifferent +=
     245                    static_cast<float>(maxOf3(deltaR, deltaG, deltaB)) / 255;
     246            }
     247        }
     248    }
     249
     250    int maxWidth = max(baseline.width(), actual.width());
     251    int maxHeight = max(baseline.height(), actual.height());
     252
     253    weightedPixelsDifferent += (maxWidth - w) * h;
     254
     255    weightedPixelsDifferent += (maxHeight - h) * maxWidth;
     256
     257    float totalPixels = static_cast<float>(actual.width())
     258        * static_cast<float>(actual.height());
     259    if (!totalPixels)
     260        return 100.0f;
     261    return weightedPixelsDifferent / totalPixels * 100;
     262}
     263
    186264
    187265void printHelp()
     
    196274            "  ImageDiff --diff <compare file> <reference file> <output file>\n"
    197275            "    Compares two files on disk, outputs an image that visualizes the"
    198             "    difference to <output file>\n");
     276            "    difference to <output file>\n"
     277            "    --write-image-diff-metrics prints a difference metric to stdout\n"
     278            "    --weighted-intensity weights the difference metric by intensity\n"
     279            "      at each pixel\n");
    199280    /* For unfinished webkit-like-mode (see below)
    200281       "\n"
     
    207288}
    208289
    209 int compareImages(const char* file1, const char* file2)
     290int compareImages(const char* file1, const char* file2,
     291                  ImageComparisonProc comparator)
    210292{
    211293    Image actualImage;
     
    221303    }
    222304
    223     float percent = percentageDifferent(actualImage, baselineImage);
     305    float percent = (*comparator)(actualImage, baselineImage);
    224306    if (percent > 0.0) {
    225307        // failure: The WebKit version also writes the difference image to
     
    237319// Untested mode that acts like WebKit's image comparator. I wrote this but
    238320// decided it's too complicated. We may use it in the future if it looks useful.
    239 int untestedCompareImages()
     321int untestedCompareImages(ImageComparisonProc comparator)
    240322{
    241323    Image actualImage;
     
    255337            bool success = false;
    256338            if (imageSize > 0 && !actualImage.hasImage()) {
    257                 if (!actualImage.craeteFromStdin(imageSize)) {
     339                if (!actualImage.createFromStdin(imageSize)) {
    258340                    fputs("Error, input image can't be decoded.\n", stderr);
    259341                    return 1;
    260342                }
    261343            } else if (imageSize > 0 && !baselineImage.hasImage()) {
    262                 if (!baselineImage.craeteFromStdin(imageSize)) {
     344                if (!baselineImage.createFromStdin(imageSize)) {
    263345                    fputs("Error, baseline image can't be decoded.\n", stderr);
    264346                    return 1;
     
    271353
    272354        if (actualImage.hasImage() && baselineImage.hasImage()) {
    273             float percent = percentageDifferent(actualImage, baselineImage);
     355            float percent = (*comparator)(actualImage, baselineImage);
    274356            if (percent > 0.0) {
    275357                // failure: The WebKit version also writes the difference image to
     
    296378
    297379    // FIXME: do something with the extra pixels if the image sizes are different.
    298     for (int y = 0; y < h; y++) {
    299         for (int x = 0; x < w; x++) {
     380    for (int y = 0; y < h; ++y) {
     381        for (int x = 0; x < w; ++x) {
    300382            uint32_t basePixel = image1.pixelAt(x, y);
    301383            if (basePixel != image2.pixelAt(x, y)) {
     
    331413}
    332414
    333 int diffImages(const char* file1, const char* file2, const char* outFile)
     415int diffImages(const char* file1, const char* file2, const char* outFile,
     416               bool shouldWritePercentages, ImageComparisonProc comparator)
    334417{
    335418    Image actualImage;
     
    355438    if (!writeFile(outFile, &pngData.front(), pngData.size()))
    356439        return statusError;
     440
     441    if (shouldWritePercentages) {
     442        float percent = (*comparator)(actualImage, baselineImage);
     443        fprintf(stdout, "%.3f\n", percent);
     444    }
     445
    357446    return statusDifferent;
    358447}
     
    363452    bool pollStdin = false;
    364453    bool generateDiff = false;
     454    bool shouldWritePercentages = false;
     455    ImageComparisonProc comparator = percentageDifferent;
    365456    for (int i = 1; i < argc; ++i) {
    366457        if (!strcmp(argv[i], optionPollStdin))
     
    368459        else if (!strcmp(argv[i], optionGenerateDiff))
    369460            generateDiff = true;
     461        else if (!strcmp(argv[i], optionWrite))
     462            shouldWritePercentages = true;
     463        else if (!strcmp(argv[i], optionWeightedIntensity))
     464            comparator = weightedPercentageDifferent;
    370465        else
    371466            values.append(argv[i]);
     
    384479            if (haveFirstName) {
    385480                // compareImages writes results to stdout unless an error occurred.
    386                 if (compareImages(firstName, stdinBuffer) == statusError)
     481                if (compareImages(firstName, stdinBuffer,
     482                                  comparator) == statusError)
    387483                    printf("error\n");
    388484                fflush(stdout);
     
    400496    if (generateDiff) {
    401497        if (values.size() == 3)
    402             return diffImages(values[0], values[1], values[2]);
     498            return diffImages(values[0], values[1], values[2],
     499                              shouldWritePercentages, comparator);
    403500    } else if (values.size() == 2)
    404         return compareImages(argv[1], argv[2]);
     501        return compareImages(argv[1], argv[2], comparator);
    405502
    406503    printHelp();
Note: See TracChangeset for help on using the changeset viewer.