| Index: tools/skpdiff/SkDiffContext.cpp
|
| diff --git a/tools/skpdiff/SkDiffContext.cpp b/tools/skpdiff/SkDiffContext.cpp
|
| index 6f0b09f0822e70c7d8d78626b945e0d9d45248ce..26898c92f38fc0168b1f998974a6228775c896b7 100644
|
| --- a/tools/skpdiff/SkDiffContext.cpp
|
| +++ b/tools/skpdiff/SkDiffContext.cpp
|
| @@ -9,11 +9,13 @@
|
| #include "SkImageDecoder.h"
|
| #include "SkOSFile.h"
|
| #include "SkRunnable.h"
|
| +#include "SkSize.h"
|
| #include "SkStream.h"
|
| #include "SkTDict.h"
|
| #include "SkThreadPool.h"
|
|
|
| #include "SkDiffContext.h"
|
| +#include "SkImageDiffer.h"
|
| #include "skpdiff_util.h"
|
|
|
| SkDiffContext::SkDiffContext() {
|
| @@ -28,9 +30,21 @@ SkDiffContext::~SkDiffContext() {
|
| }
|
| }
|
|
|
| -void SkDiffContext::setDifferenceDir(const SkString& path) {
|
| +void SkDiffContext::setAlphaMaskDir(const SkString& path) {
|
| if (!path.isEmpty() && sk_mkdir(path.c_str())) {
|
| - fDifferenceDir = path;
|
| + fAlphaMaskDir = path;
|
| + }
|
| +}
|
| +
|
| +void SkDiffContext::setRgbDiffDir(const SkString& path) {
|
| + if (!path.isEmpty() && sk_mkdir(path.c_str())) {
|
| + fRgbDiffDir = path;
|
| + }
|
| +}
|
| +
|
| +void SkDiffContext::setWhiteDiffDir(const SkString& path) {
|
| + if (!path.isEmpty() && sk_mkdir(path.c_str())) {
|
| + fWhiteDiffDir = path;
|
| }
|
| }
|
|
|
| @@ -90,13 +104,13 @@ void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) {
|
|
|
| newRecord->fBaselinePath = baselinePath;
|
| newRecord->fTestPath = testPath;
|
| + newRecord->fSize = SkISize::Make(baselineBitmap.width(), baselineBitmap.height());
|
|
|
| - bool alphaMaskPending = false;
|
| -
|
| - // only enable alpha masks if a difference dir has been provided
|
| - if (!fDifferenceDir.isEmpty()) {
|
| - alphaMaskPending = true;
|
| - }
|
| + // only generate diff images if we have a place to store them
|
| + SkImageDiffer::BitmapsToCreate bitmapsToCreate;
|
| + bitmapsToCreate.alphaMask = !fAlphaMaskDir.isEmpty();
|
| + bitmapsToCreate.rgbDiff = !fRgbDiffDir.isEmpty();
|
| + bitmapsToCreate.whiteDiff = !fWhiteDiffDir.isEmpty();
|
|
|
| // Perform each diff
|
| for (int differIndex = 0; differIndex < fDifferCount; differIndex++) {
|
| @@ -106,30 +120,69 @@ void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) {
|
| DiffData& diffData = newRecord->fDiffs.push_back();
|
| diffData.fDiffName = differ->getName();
|
|
|
| - if (!differ->diff(&baselineBitmap, &testBitmap, alphaMaskPending, &diffData.fResult)) {
|
| - // if the diff failed record -1 as the result
|
| + if (!differ->diff(&baselineBitmap, &testBitmap, bitmapsToCreate, &diffData.fResult)) {
|
| + // if the diff failed, record -1 as the result
|
| + // TODO(djsollen): Record more detailed information about exactly what failed.
|
| + // (Image dimension mismatch? etc.) See http://skbug.com/2710 ('make skpdiff
|
| + // report more detail when it fails to compare two images')
|
| diffData.fResult.result = -1;
|
| continue;
|
| }
|
|
|
| - if (alphaMaskPending
|
| + if (bitmapsToCreate.alphaMask
|
| && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
|
| && !diffData.fResult.poiAlphaMask.empty()
|
| && !newRecord->fCommonName.isEmpty()) {
|
|
|
| - newRecord->fDifferencePath = SkOSPath::SkPathJoin(fDifferenceDir.c_str(),
|
| - newRecord->fCommonName.c_str());
|
| + newRecord->fAlphaMaskPath = SkOSPath::SkPathJoin(fAlphaMaskDir.c_str(),
|
| + newRecord->fCommonName.c_str());
|
|
|
| // compute the image diff and output it
|
| SkBitmap copy;
|
| diffData.fResult.poiAlphaMask.copyTo(©, kN32_SkColorType);
|
| - SkImageEncoder::EncodeFile(newRecord->fDifferencePath.c_str(), copy,
|
| + SkImageEncoder::EncodeFile(newRecord->fAlphaMaskPath.c_str(), copy,
|
| SkImageEncoder::kPNG_Type, 100);
|
|
|
| // cleanup the existing bitmap to free up resources;
|
| diffData.fResult.poiAlphaMask.reset();
|
|
|
| - alphaMaskPending = false;
|
| + bitmapsToCreate.alphaMask = false;
|
| + }
|
| +
|
| + if (bitmapsToCreate.rgbDiff
|
| + && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
|
| + && !diffData.fResult.rgbDiffBitmap.empty()
|
| + && !newRecord->fCommonName.isEmpty()) {
|
| + // TODO(djsollen): Rather than taking the max r/g/b diffs that come back from
|
| + // a particular differ and storing them as toplevel fields within
|
| + // newRecord, we should extend outputRecords() to report optional
|
| + // fields for each differ (not just "result" and "pointsOfInterest").
|
| + // See http://skbug.com/2712 ('allow skpdiff to report different sets
|
| + // of result fields for different comparison algorithms')
|
| + newRecord->fMaxRedDiff = diffData.fResult.maxRedDiff;
|
| + newRecord->fMaxGreenDiff = diffData.fResult.maxGreenDiff;
|
| + newRecord->fMaxBlueDiff = diffData.fResult.maxBlueDiff;
|
| +
|
| + newRecord->fRgbDiffPath = SkOSPath::SkPathJoin(fRgbDiffDir.c_str(),
|
| + newRecord->fCommonName.c_str());
|
| + SkImageEncoder::EncodeFile(newRecord->fRgbDiffPath.c_str(),
|
| + diffData.fResult.rgbDiffBitmap,
|
| + SkImageEncoder::kPNG_Type, 100);
|
| + diffData.fResult.rgbDiffBitmap.reset();
|
| + bitmapsToCreate.rgbDiff = false;
|
| + }
|
| +
|
| + if (bitmapsToCreate.whiteDiff
|
| + && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
|
| + && !diffData.fResult.whiteDiffBitmap.empty()
|
| + && !newRecord->fCommonName.isEmpty()) {
|
| + newRecord->fWhiteDiffPath = SkOSPath::SkPathJoin(fWhiteDiffDir.c_str(),
|
| + newRecord->fCommonName.c_str());
|
| + SkImageEncoder::EncodeFile(newRecord->fWhiteDiffPath.c_str(),
|
| + diffData.fResult.whiteDiffBitmap,
|
| + SkImageEncoder::kPNG_Type, 100);
|
| + diffData.fResult.whiteDiffBitmap.reset();
|
| + bitmapsToCreate.whiteDiff = false;
|
| }
|
| }
|
| }
|
| @@ -229,11 +282,15 @@ void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
|
| } else {
|
| stream.writeText("{\n");
|
| }
|
| +
|
| + // TODO(djsollen): Would it be better to use the jsoncpp library to write out the JSON?
|
| + // This manual approach is probably more efficient, but it sure is ugly.
|
| + // See http://skbug.com/2713 ('make skpdiff use jsoncpp library to write out
|
| + // JSON output, instead of manual writeText() calls?')
|
| stream.writeText(" \"records\": [\n");
|
| while (NULL != currentRecord) {
|
| stream.writeText(" {\n");
|
|
|
| - SkString differenceAbsPath = get_absolute_path(currentRecord->fDifferencePath);
|
| SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselinePath);
|
| SkString testAbsPath = get_absolute_path(currentRecord->fTestPath);
|
|
|
| @@ -242,7 +299,15 @@ void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
|
| stream.writeText("\",\n");
|
|
|
| stream.writeText(" \"differencePath\": \"");
|
| - stream.writeText(differenceAbsPath.c_str());
|
| + stream.writeText(get_absolute_path(currentRecord->fAlphaMaskPath).c_str());
|
| + stream.writeText("\",\n");
|
| +
|
| + stream.writeText(" \"rgbDiffPath\": \"");
|
| + stream.writeText(get_absolute_path(currentRecord->fRgbDiffPath).c_str());
|
| + stream.writeText("\",\n");
|
| +
|
| + stream.writeText(" \"whiteDiffPath\": \"");
|
| + stream.writeText(get_absolute_path(currentRecord->fWhiteDiffPath).c_str());
|
| stream.writeText("\",\n");
|
|
|
| stream.writeText(" \"baselinePath\": \"");
|
| @@ -253,6 +318,23 @@ void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
|
| stream.writeText(testAbsPath.c_str());
|
| stream.writeText("\",\n");
|
|
|
| + stream.writeText(" \"width\": ");
|
| + stream.writeDecAsText(currentRecord->fSize.width());
|
| + stream.writeText(",\n");
|
| + stream.writeText(" \"height\": ");
|
| + stream.writeDecAsText(currentRecord->fSize.height());
|
| + stream.writeText(",\n");
|
| +
|
| + stream.writeText(" \"maxRedDiff\": ");
|
| + stream.writeDecAsText(currentRecord->fMaxRedDiff);
|
| + stream.writeText(",\n");
|
| + stream.writeText(" \"maxGreenDiff\": ");
|
| + stream.writeDecAsText(currentRecord->fMaxGreenDiff);
|
| + stream.writeText(",\n");
|
| + stream.writeText(" \"maxBlueDiff\": ");
|
| + stream.writeDecAsText(currentRecord->fMaxBlueDiff);
|
| + stream.writeText(",\n");
|
| +
|
| stream.writeText(" \"diffs\": [\n");
|
| for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); diffIndex++) {
|
| DiffData& data = currentRecord->fDiffs[diffIndex];
|
|
|