* Extended skdiff to report alpha channel differences.
* Created a tools/tests/rebaseline.sh to copy output-actual into output-expected.
* Sample results are available here: http://www.corp.google.com/~rmistry/skia/gm-playback-windows/images-skdiff/
Review URL: https://codereview.appspot.com/7038048

git-svn-id: http://skia.googlecode.com/svn/trunk@7003 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/skdiff.cpp b/tools/skdiff.cpp
index a1783a4..ae6d72c 100644
--- a/tools/skdiff.cpp
+++ b/tools/skdiff.cpp
@@ -166,6 +166,7 @@
     SkAutoLockPixels alpDiff(dr->fDifference.fBitmap);
     SkAutoLockPixels alpWhite(dr->fWhite.fBitmap);
     int mismatchedPixels = 0;
+    int totalMismatchA = 0;
     int totalMismatchR = 0;
     int totalMismatchG = 0;
     int totalMismatchB = 0;
@@ -177,17 +178,21 @@
         for (int x = 0; x < w; x++) {
             SkPMColor c0 = *dr->fBase.fBitmap.getAddr32(x, y);
             SkPMColor c1 = *dr->fComparison.fBitmap.getAddr32(x, y);
-            SkPMColor trueDifference = compute_diff_pmcolor(c0, c1);
             SkPMColor outputDifference = diffFunction(c0, c1);
-            uint32_t thisR = SkGetPackedR32(trueDifference);
-            uint32_t thisG = SkGetPackedG32(trueDifference);
-            uint32_t thisB = SkGetPackedB32(trueDifference);
+            uint32_t thisA = SkAbs32(SkGetPackedA32(c0) - SkGetPackedA32(c1));
+            uint32_t thisR = SkAbs32(SkGetPackedR32(c0) - SkGetPackedR32(c1));
+            uint32_t thisG = SkAbs32(SkGetPackedG32(c0) - SkGetPackedG32(c1));
+            uint32_t thisB = SkAbs32(SkGetPackedB32(c0) - SkGetPackedB32(c1));
+            totalMismatchA += thisA;
             totalMismatchR += thisR;
             totalMismatchG += thisG;
             totalMismatchB += thisB;
             // In HSV, value is defined as max RGB component.
             int value = MAX3(thisR, thisG, thisB);
             dr->fWeightedFraction += ((float) value) / 255;
+            if (thisA > dr->fMaxMismatchA) {
+                dr->fMaxMismatchA = thisA;
+            }
             if (thisR > dr->fMaxMismatchR) {
                 dr->fMaxMismatchR = thisR;
             }
@@ -215,6 +220,8 @@
     int pixelCount = w * h;
     dr->fFractionDifference = ((float) mismatchedPixels) / pixelCount;
     dr->fWeightedFraction /= pixelCount;
+    dr->fTotalMismatchA = totalMismatchA;
+    dr->fAverageMismatchA = ((float) totalMismatchA) / pixelCount;
     dr->fAverageMismatchR = ((float) totalMismatchR) / pixelCount;
     dr->fAverageMismatchG = ((float) totalMismatchG) / pixelCount;
     dr->fAverageMismatchB = ((float) totalMismatchB) / pixelCount;
diff --git a/tools/skdiff.h b/tools/skdiff.h
index b9e69ce..6abaf6c 100644
--- a/tools/skdiff.h
+++ b/tools/skdiff.h
@@ -115,9 +115,12 @@
         , fWhite()
         , fFractionDifference(0)
         , fWeightedFraction(0)
+        , fAverageMismatchA(0)
         , fAverageMismatchR(0)
         , fAverageMismatchG(0)
         , fAverageMismatchB(0)
+        , fTotalMismatchA(0)
+        , fMaxMismatchA(0)
         , fMaxMismatchR(0)
         , fMaxMismatchG(0)
         , fMaxMismatchB(0)
@@ -135,10 +138,14 @@
     float fFractionDifference;
     float fWeightedFraction;
 
+    float fAverageMismatchA;
     float fAverageMismatchR;
     float fAverageMismatchG;
     float fAverageMismatchB;
 
+    uint32_t fTotalMismatchA;
+
+    uint32_t fMaxMismatchA;
     uint32_t fMaxMismatchR;
     uint32_t fMaxMismatchG;
     uint32_t fMaxMismatchB;
diff --git a/tools/skdiff_html.cpp b/tools/skdiff_html.cpp
index 85d8777..d83b736 100644
--- a/tools/skdiff_html.cpp
+++ b/tools/skdiff_html.cpp
@@ -124,6 +124,19 @@
         if (diff.fFractionDifference < 0.01) {
             print_pixel_count(stream, diff);
         }
+        stream->writeText("<br>");
+        if (static_cast<int>(diff.fAverageMismatchA) > 0) {
+          stream->writeText("<br>Average alpha channel mismatch ");
+          stream->writeDecAsText(static_cast<float>(diff.fAverageMismatchA));
+        }
+
+        stream->writeText("<br>Max alpha channel mismatch ");
+        stream->writeDecAsText(static_cast<int>(diff.fMaxMismatchA));
+
+        stream->writeText("<br>Total alpha channel mismatch ");
+        stream->writeDecAsText(static_cast<int>(diff.fTotalMismatchA));
+
+        stream->writeText("<br>");
         stream->writeText("<br>Average color mismatch ");
         stream->writeDecAsText(static_cast<int>(MAX3(diff.fAverageMismatchR,
                                                      diff.fAverageMismatchG,
diff --git a/tools/tests/rebaseline.sh b/tools/tests/rebaseline.sh
new file mode 100755
index 0000000..eee8db8
--- /dev/null
+++ b/tools/tests/rebaseline.sh
@@ -0,0 +1,73 @@
+#!/bin/bash
+
+# Rebaseline the skdiff/*/output-expected/ subdirectories used by the skdiff
+# self-tests.
+# Use with caution: are you sure the new results are actually correct?
+#
+# YOU MUST RE-RUN THIS UNTIL THE SELF-TESTS SUCCEED!
+#
+# TODO: currently, this must be run on Linux to generate baselines that match
+# the ones on the housekeeper bot (which runs on Linux... see
+# http://70.32.156.51:10117/builders/Skia_PerCommit_House_Keeping/builds/1417/steps/RunGmSelfTests/logs/stdio )
+# See https://code.google.com/p/skia/issues/detail?id=677
+# ('make tools/tests/run.sh work cross-platform')
+
+function replace_expected_with_actual {
+  # Delete all the expected output files
+  EXPECTED_FILES=$(find skdiff/*/output-expected -type f | grep -v /\.svn/)
+  for EXPECTED_FILE in $EXPECTED_FILES; do
+    rm $EXPECTED_FILE
+  done
+
+  # Copy all the actual output files into the "expected" directories,
+  # creating new subdirs as we go.
+  ACTUAL_FILES=$(find skdiff/*/output-actual -type f | grep -v /\.svn/)
+  for ACTUAL_FILE in $ACTUAL_FILES; do
+    EXPECTED_FILE=${ACTUAL_FILE//actual/expected}
+    mkdir -p $(dirname $EXPECTED_FILE)
+    cp $ACTUAL_FILE $EXPECTED_FILE
+  done
+}
+
+function svn_add_new_files {
+  # Delete all the "actual" directories, so we can svn-add any new "expected"
+  # directories without adding the "actual" ones.
+  rm -rf skdiff/*/output-actual
+  FILES=$(svn stat skdiff/* | grep ^\? | awk '{print $2}')
+  for FILE in $FILES; do
+    svn add $FILE
+  done
+  FILES=$(svn stat skdiff/*/output-expected | grep ^\? | awk '{print $2}')
+  for FILE in $FILES; do
+    svn add $FILE
+  done
+}
+
+function svn_delete_old_files {
+  FILES=$(svn stat skdiff/*/output-expected | grep ^\! | awk '{print $2}')
+  for FILE in $FILES; do
+    svn rm $FILE
+  done
+  FILES=$(svn stat skdiff/* | grep ^\! | awk '{print $2}')
+  for FILE in $FILES; do
+    svn rm $FILE
+  done
+}
+
+
+# cd into the gm self-test dir
+cd $(dirname $0)
+
+./run.sh
+SELFTEST_RESULT=$?
+echo
+if [ "$SELFTEST_RESULT" != "0" ]; then
+  replace_expected_with_actual
+  echo "Self-tests still failing, you should probably run this again..."
+else
+  svn_add_new_files
+  svn_delete_old_files
+  echo "Self-tests succeeded this time, you should be done!"
+fi
+exit $SELFTEST_RESULT
+
diff --git a/tools/tests/skdiff/test1/output-expected/index.html b/tools/tests/skdiff/test1/output-expected/index.html
index a3e192e..4bf8eee 100644
--- a/tools/tests/skdiff/test1/output-expected/index.html
+++ b/tools/tests/skdiff/test1/output-expected/index.html
@@ -39,10 +39,10 @@
 <td><input type="checkbox" name="different-bits/very-different-sizes.png" checked="yes"></td><td><b>different-bits/very-different-sizes.png</b><br>Image sizes differ</td><td>N/A</td><td>N/A</td><td><a href="../../../../../tools/tests/skdiff/baseDir/different-bits/very-different-sizes.png"><img src="../../../../../tools/tests/skdiff/baseDir/different-bits/very-different-sizes.png" height="240px"></a></td><td><a href="../../../../../tools/tests/skdiff/comparisonDir/different-bits/very-different-sizes.png"><img src="../../../../../tools/tests/skdiff/comparisonDir/different-bits/very-different-sizes.png" height="128px"></a></td></tr>
 <tr>
 <td><input type="checkbox" name="different-bits/very-different-pixels-same-size.png" checked="yes"></td><td><b>different-bits/very-different-pixels-same-size.png</b><br>97.9926% of pixels differ
-  (42.8911% weighted)<br>Average color mismatch 89<br>Max color mismatch 239</td><td><a href="different-bits_very-different-pixels-same-size-white.png"><img src="different-bits_very-different-pixels-same-size-white.png" height="240px"></a></td><td><a href="different-bits_very-different-pixels-same-size-diff.png"><img src="different-bits_very-different-pixels-same-size-diff.png" height="240px"></a></td><td><a href="../../../../../tools/tests/skdiff/baseDir/different-bits/very-different-pixels-same-size.png"><img src="../../../../../tools/tests/skdiff/baseDir/different-bits/very-different-pixels-same-size.png" height="240px"></a></td><td><a href="../../../../../tools/tests/skdiff/comparisonDir/different-bits/very-different-pixels-same-size.png"><img src="../../../../../tools/tests/skdiff/comparisonDir/different-bits/very-different-pixels-same-size.png" height="240px"></a></td></tr>
+  (42.8911% weighted)<br><br>Max alpha channel mismatch 0<br>Total alpha channel mismatch 0<br><br>Average color mismatch 89<br>Max color mismatch 239</td><td><a href="different-bits_very-different-pixels-same-size-white.png"><img src="different-bits_very-different-pixels-same-size-white.png" height="240px"></a></td><td><a href="different-bits_very-different-pixels-same-size-diff.png"><img src="different-bits_very-different-pixels-same-size-diff.png" height="240px"></a></td><td><a href="../../../../../tools/tests/skdiff/baseDir/different-bits/very-different-pixels-same-size.png"><img src="../../../../../tools/tests/skdiff/baseDir/different-bits/very-different-pixels-same-size.png" height="240px"></a></td><td><a href="../../../../../tools/tests/skdiff/comparisonDir/different-bits/very-different-pixels-same-size.png"><img src="../../../../../tools/tests/skdiff/comparisonDir/different-bits/very-different-pixels-same-size.png" height="240px"></a></td></tr>
 <tr>
 <td><input type="checkbox" name="different-bits/slightly-different-pixels-same-size.png" checked="yes"></td><td><b>different-bits/slightly-different-pixels-same-size.png</b><br>0.6630% of pixels differ
-  (0.1904% weighted)<br>(2164 pixels)<br>Average color mismatch 0<br>Max color mismatch 213</td><td><a href="different-bits_slightly-different-pixels-same-size-white.png"><img src="different-bits_slightly-different-pixels-same-size-white.png" height="240px"></a></td><td><a href="different-bits_slightly-different-pixels-same-size-diff.png"><img src="different-bits_slightly-different-pixels-same-size-diff.png" height="240px"></a></td><td><a href="../../../../../tools/tests/skdiff/baseDir/different-bits/slightly-different-pixels-same-size.png"><img src="../../../../../tools/tests/skdiff/baseDir/different-bits/slightly-different-pixels-same-size.png" height="240px"></a></td><td><a href="../../../../../tools/tests/skdiff/comparisonDir/different-bits/slightly-different-pixels-same-size.png"><img src="../../../../../tools/tests/skdiff/comparisonDir/different-bits/slightly-different-pixels-same-size.png" height="240px"></a></td></tr>
+  (0.1904% weighted)<br>(2164 pixels)<br><br>Max alpha channel mismatch 0<br>Total alpha channel mismatch 0<br><br>Average color mismatch 0<br>Max color mismatch 213</td><td><a href="different-bits_slightly-different-pixels-same-size-white.png"><img src="different-bits_slightly-different-pixels-same-size-white.png" height="240px"></a></td><td><a href="different-bits_slightly-different-pixels-same-size-diff.png"><img src="different-bits_slightly-different-pixels-same-size-diff.png" height="240px"></a></td><td><a href="../../../../../tools/tests/skdiff/baseDir/different-bits/slightly-different-pixels-same-size.png"><img src="../../../../../tools/tests/skdiff/baseDir/different-bits/slightly-different-pixels-same-size.png" height="240px"></a></td><td><a href="../../../../../tools/tests/skdiff/comparisonDir/different-bits/slightly-different-pixels-same-size.png"><img src="../../../../../tools/tests/skdiff/comparisonDir/different-bits/slightly-different-pixels-same-size.png" height="240px"></a></td></tr>
 </table>
 <input type="button" onclick="generateCheckedList()" value="Create Rebaseline List">
 <div id="checkedList"></div>