Changeset 87367 in webkit
- Timestamp:
- May 26, 2011 12:44:43 AM (13 years ago)
- Location:
- trunk/Tools
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r87348 r87367 1 2011-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 1 23 2011-05-25 Qi Zhang <qi.2.zhang@nokia.com> 2 24 -
trunk/Tools/DumpRenderTree/chromium/ImageDiff.cpp
r86930 r87367 57 57 static const char optionGenerateDiff[] = "--diff"; 58 58 59 // If --diff is passed, causes the app to output the image difference 60 // metric (percentageDifferent()) on stdout. 61 static const char optionWrite[] = "--write-image-diff-metrics"; 62 63 // Use weightedPercentageDifferent() instead of the default image 64 // comparator proc. 65 static const char optionWeightedIntensity[] = "--weighted-intensity"; 66 59 67 // Return codes used by this utility. 60 68 static const int statusSame = 0; … … 84 92 // Creates the image from stdin with the given data length. On success, it 85 93 // will return true. On failure, no other methods should be accessed. 86 bool cr aeteFromStdin(size_t byteLength)94 bool createFromStdin(size_t byteLength) 87 95 { 88 96 if (!byteLength) … … 153 161 }; 154 162 163 typedef float (*ImageComparisonProc) (const Image&, const Image&); 164 155 165 float percentageDifferent(const Image& baseline, const Image& actual) 156 166 { … … 160 170 // Compute pixels different in the overlap 161 171 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) { 164 174 if (baseline.pixelAt(x, y) != actual.pixelAt(x, y)) 165 175 pixelsDifferent++; … … 184 194 return static_cast<float>(pixelsDifferent) / totalPixels * 100; 185 195 } 196 197 inline 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 204 inline uint32_t getRedComponent(uint32_t color) 205 { 206 return (color << 24) >> 24; 207 } 208 209 inline uint32_t getGreenComponent(uint32_t color) 210 { 211 return (color << 16) >> 24; 212 } 213 214 inline 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. 221 float 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 186 264 187 265 void printHelp() … … 196 274 " ImageDiff --diff <compare file> <reference file> <output file>\n" 197 275 " 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"); 199 280 /* For unfinished webkit-like-mode (see below) 200 281 "\n" … … 207 288 } 208 289 209 int compareImages(const char* file1, const char* file2) 290 int compareImages(const char* file1, const char* file2, 291 ImageComparisonProc comparator) 210 292 { 211 293 Image actualImage; … … 221 303 } 222 304 223 float percent = percentageDifferent(actualImage, baselineImage);305 float percent = (*comparator)(actualImage, baselineImage); 224 306 if (percent > 0.0) { 225 307 // failure: The WebKit version also writes the difference image to … … 237 319 // Untested mode that acts like WebKit's image comparator. I wrote this but 238 320 // decided it's too complicated. We may use it in the future if it looks useful. 239 int untestedCompareImages( )321 int untestedCompareImages(ImageComparisonProc comparator) 240 322 { 241 323 Image actualImage; … … 255 337 bool success = false; 256 338 if (imageSize > 0 && !actualImage.hasImage()) { 257 if (!actualImage.cr aeteFromStdin(imageSize)) {339 if (!actualImage.createFromStdin(imageSize)) { 258 340 fputs("Error, input image can't be decoded.\n", stderr); 259 341 return 1; 260 342 } 261 343 } else if (imageSize > 0 && !baselineImage.hasImage()) { 262 if (!baselineImage.cr aeteFromStdin(imageSize)) {344 if (!baselineImage.createFromStdin(imageSize)) { 263 345 fputs("Error, baseline image can't be decoded.\n", stderr); 264 346 return 1; … … 271 353 272 354 if (actualImage.hasImage() && baselineImage.hasImage()) { 273 float percent = percentageDifferent(actualImage, baselineImage);355 float percent = (*comparator)(actualImage, baselineImage); 274 356 if (percent > 0.0) { 275 357 // failure: The WebKit version also writes the difference image to … … 296 378 297 379 // 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) { 300 382 uint32_t basePixel = image1.pixelAt(x, y); 301 383 if (basePixel != image2.pixelAt(x, y)) { … … 331 413 } 332 414 333 int diffImages(const char* file1, const char* file2, const char* outFile) 415 int diffImages(const char* file1, const char* file2, const char* outFile, 416 bool shouldWritePercentages, ImageComparisonProc comparator) 334 417 { 335 418 Image actualImage; … … 355 438 if (!writeFile(outFile, &pngData.front(), pngData.size())) 356 439 return statusError; 440 441 if (shouldWritePercentages) { 442 float percent = (*comparator)(actualImage, baselineImage); 443 fprintf(stdout, "%.3f\n", percent); 444 } 445 357 446 return statusDifferent; 358 447 } … … 363 452 bool pollStdin = false; 364 453 bool generateDiff = false; 454 bool shouldWritePercentages = false; 455 ImageComparisonProc comparator = percentageDifferent; 365 456 for (int i = 1; i < argc; ++i) { 366 457 if (!strcmp(argv[i], optionPollStdin)) … … 368 459 else if (!strcmp(argv[i], optionGenerateDiff)) 369 460 generateDiff = true; 461 else if (!strcmp(argv[i], optionWrite)) 462 shouldWritePercentages = true; 463 else if (!strcmp(argv[i], optionWeightedIntensity)) 464 comparator = weightedPercentageDifferent; 370 465 else 371 466 values.append(argv[i]); … … 384 479 if (haveFirstName) { 385 480 // compareImages writes results to stdout unless an error occurred. 386 if (compareImages(firstName, stdinBuffer) == statusError) 481 if (compareImages(firstName, stdinBuffer, 482 comparator) == statusError) 387 483 printf("error\n"); 388 484 fflush(stdout); … … 400 496 if (generateDiff) { 401 497 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); 403 500 } else if (values.size() == 2) 404 return compareImages(argv[1], argv[2] );501 return compareImages(argv[1], argv[2], comparator); 405 502 406 503 printHelp();
Note: See TracChangeset
for help on using the changeset viewer.