| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
| 9 #include "SkImageDecoder.h" | 9 #include "SkImageDecoder.h" |
| 10 #include "SkOSFile.h" | 10 #include "SkOSFile.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 DiffRecord* nextRecord = currentRecord->fNext; | 34 DiffRecord* nextRecord = currentRecord->fNext; |
| 35 SkDELETE(currentRecord); | 35 SkDELETE(currentRecord); |
| 36 currentRecord = nextRecord; | 36 currentRecord = nextRecord; |
| 37 } | 37 } |
| 38 | 38 |
| 39 if (NULL != fDiffers) { | 39 if (NULL != fDiffers) { |
| 40 SkDELETE_ARRAY(fDiffers); | 40 SkDELETE_ARRAY(fDiffers); |
| 41 } | 41 } |
| 42 } | 42 } |
| 43 | 43 |
| 44 void SkDiffContext::setDifferenceDir(const SkString& path) { |
| 45 if (!path.isEmpty() && sk_mkdir(path.c_str())) { |
| 46 fDifferenceDir = path; |
| 47 } |
| 48 } |
| 49 |
| 44 void SkDiffContext::setDiffers(const SkTDArray<SkImageDiffer*>& differs) { | 50 void SkDiffContext::setDiffers(const SkTDArray<SkImageDiffer*>& differs) { |
| 45 // Delete whatever the last array of differs was | 51 // Delete whatever the last array of differs was |
| 46 if (NULL != fDiffers) { | 52 if (NULL != fDiffers) { |
| 47 SkDELETE_ARRAY(fDiffers); | 53 SkDELETE_ARRAY(fDiffers); |
| 48 fDiffers = NULL; | 54 fDiffers = NULL; |
| 49 fDifferCount = 0; | 55 fDifferCount = 0; |
| 50 } | 56 } |
| 51 | 57 |
| 52 // Copy over the new differs | 58 // Copy over the new differs |
| 53 fDifferCount = differs.count(); | 59 fDifferCount = differs.count(); |
| 54 fDiffers = SkNEW_ARRAY(SkImageDiffer*, fDifferCount); | 60 fDiffers = SkNEW_ARRAY(SkImageDiffer*, fDifferCount); |
| 55 differs.copy(fDiffers); | 61 differs.copy(fDiffers); |
| 56 } | 62 } |
| 57 | 63 |
| 64 static SkString get_common_prefix(const SkString& a, const SkString& b) { |
| 65 const size_t maxPrefixLength = SkTMin(a.size(), b.size()); |
| 66 SkASSERT(maxPrefixLength > 0); |
| 67 for (size_t x = 0; x < maxPrefixLength; ++x) { |
| 68 if (a[x] != b[x]) { |
| 69 SkString result; |
| 70 result.set(a.c_str(), x); |
| 71 return result; |
| 72 } |
| 73 } |
| 74 if (a.size() > b.size()) { |
| 75 return b; |
| 76 } else { |
| 77 return a; |
| 78 } |
| 79 } |
| 80 |
| 58 void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) { | 81 void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) { |
| 59 // Load the images at the paths | 82 // Load the images at the paths |
| 60 SkBitmap baselineBitmap; | 83 SkBitmap baselineBitmap; |
| 61 SkBitmap testBitmap; | 84 SkBitmap testBitmap; |
| 62 if (!SkImageDecoder::DecodeFile(baselinePath, &baselineBitmap)) { | 85 if (!SkImageDecoder::DecodeFile(baselinePath, &baselineBitmap)) { |
| 63 SkDebugf("Failed to load bitmap \"%s\"\n", baselinePath); | 86 SkDebugf("Failed to load bitmap \"%s\"\n", baselinePath); |
| 64 return; | 87 return; |
| 65 } | 88 } |
| 66 if (!SkImageDecoder::DecodeFile(testPath, &testBitmap)) { | 89 if (!SkImageDecoder::DecodeFile(testPath, &testBitmap)) { |
| 67 SkDebugf("Failed to load bitmap \"%s\"\n", testPath); | 90 SkDebugf("Failed to load bitmap \"%s\"\n", testPath); |
| 68 return; | 91 return; |
| 69 } | 92 } |
| 70 | 93 |
| 71 // Setup a record for this diff | 94 // Setup a record for this diff |
| 72 DiffRecord* newRecord = SkNEW(DiffRecord); | 95 DiffRecord* newRecord = SkNEW(DiffRecord); |
| 73 newRecord->fBaselinePath = baselinePath; | 96 newRecord->fBaselinePath = baselinePath; |
| 74 newRecord->fTestPath = testPath; | 97 newRecord->fTestPath = testPath; |
| 75 newRecord->fNext = fRecords; | 98 newRecord->fNext = fRecords; |
| 76 fRecords = newRecord; | 99 fRecords = newRecord; |
| 77 | 100 |
| 101 // compute the common name |
| 102 SkString baseName = SkOSPath::SkBasename(baselinePath); |
| 103 SkString testName = SkOSPath::SkBasename(testPath); |
| 104 newRecord->fCommonName = get_common_prefix(baseName, testName); |
| 105 |
| 106 bool alphaMaskPending = false; |
| 107 bool alphaMaskCreated = false; |
| 108 |
| 78 // Perform each diff | 109 // Perform each diff |
| 79 for (int differIndex = 0; differIndex < fDifferCount; differIndex++) { | 110 for (int differIndex = 0; differIndex < fDifferCount; differIndex++) { |
| 80 SkImageDiffer* differ = fDiffers[differIndex]; | 111 SkImageDiffer* differ = fDiffers[differIndex]; |
| 112 // TODO only enable for one differ |
| 113 if (!alphaMaskCreated && !fDifferenceDir.isEmpty()) { |
| 114 alphaMaskPending = differ->enablePOIAlphaMask(); |
| 115 } |
| 81 int diffID = differ->queueDiff(&baselineBitmap, &testBitmap); | 116 int diffID = differ->queueDiff(&baselineBitmap, &testBitmap); |
| 82 if (diffID >= 0) { | 117 if (diffID >= 0) { |
| 83 | 118 |
| 84 // Copy the results into data for this record | 119 // Copy the results into data for this record |
| 85 DiffData& diffData = newRecord->fDiffs.push_back(); | 120 DiffData& diffData = newRecord->fDiffs.push_back(); |
| 86 | 121 |
| 87 diffData.fDiffName = differ->getName(); | 122 diffData.fDiffName = differ->getName(); |
| 88 diffData.fResult = differ->getResult(diffID); | 123 diffData.fResult = differ->getResult(diffID); |
| 89 | 124 |
| 90 int poiCount = differ->getPointsOfInterestCount(diffID); | 125 int poiCount = differ->getPointsOfInterestCount(diffID); |
| 91 SkIPoint* poi = differ->getPointsOfInterest(diffID); | 126 SkIPoint* poi = differ->getPointsOfInterest(diffID); |
| 92 diffData.fPointsOfInterest.append(poiCount, poi); | 127 diffData.fPointsOfInterest.append(poiCount, poi); |
| 93 | 128 |
| 129 if (alphaMaskPending |
| 130 && SkImageDiffer::RESULT_CORRECT != diffData.fResult |
| 131 && newRecord->fDifferencePath.isEmpty()) { |
| 132 newRecord->fDifferencePath = SkOSPath::SkPathJoin(fDifferenceDir
.c_str(), |
| 133 newRecord->fCo
mmonName.c_str()); |
| 134 |
| 135 // compute the image diff and output it |
| 136 SkBitmap* alphaMask = differ->getPointsOfInterestAlphaMask(diffI
D); |
| 137 SkBitmap copy; |
| 138 alphaMask->copyTo(©, SkBitmap::kARGB_8888_Config); |
| 139 SkImageEncoder::EncodeFile(newRecord->fDifferencePath.c_str(), c
opy, |
| 140 SkImageEncoder::kPNG_Type, 100); |
| 141 } |
| 142 |
| 143 if (alphaMaskPending) { |
| 144 alphaMaskPending = false; |
| 145 alphaMaskCreated = true; |
| 146 } |
| 147 |
| 94 // Because we are doing everything synchronously for now, we are don
e with the diff | 148 // Because we are doing everything synchronously for now, we are don
e with the diff |
| 95 // after reading it. | 149 // after reading it. |
| 96 differ->deleteDiff(diffID); | 150 differ->deleteDiff(diffID); |
| 97 } | 151 } |
| 98 } | 152 } |
| 99 | 153 |
| 100 // if we get a difference and we want the alpha mask then compute it here. | 154 // if we get a difference and we want the alpha mask then compute it here. |
| 101 } | 155 } |
| 102 | 156 |
| 103 class SkThreadedDiff : public SkRunnable { | 157 class SkThreadedDiff : public SkRunnable { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 stream.writeText("{\n"); | 248 stream.writeText("{\n"); |
| 195 } | 249 } |
| 196 stream.writeText(" \"records\": [\n"); | 250 stream.writeText(" \"records\": [\n"); |
| 197 while (NULL != currentRecord) { | 251 while (NULL != currentRecord) { |
| 198 stream.writeText(" {\n"); | 252 stream.writeText(" {\n"); |
| 199 | 253 |
| 200 SkString differenceAbsPath = get_absolute_path(currentRecord->fDiffe
rencePath); | 254 SkString differenceAbsPath = get_absolute_path(currentRecord->fDiffe
rencePath); |
| 201 SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselin
ePath); | 255 SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselin
ePath); |
| 202 SkString testAbsPath = get_absolute_path(currentRecord->fTestPath); | 256 SkString testAbsPath = get_absolute_path(currentRecord->fTestPath); |
| 203 | 257 |
| 204 // strip off directory structure and find the common part of the fil
ename | |
| 205 SkString baseName = SkOSPath::SkBasename(baselineAbsPath.c_str()); | |
| 206 SkString testName = SkOSPath::SkBasename(testAbsPath.c_str()); | |
| 207 for (size_t x = 0; x < baseName.size(); ++x) { | |
| 208 if (baseName[x] != testName[x]) { | |
| 209 baseName.insertUnichar(x, '\n'); | |
| 210 break; | |
| 211 } | |
| 212 } | |
| 213 | |
| 214 stream.writeText(" \"commonName\": \""); | 258 stream.writeText(" \"commonName\": \""); |
| 215 stream.writeText(baseName.c_str()); | 259 stream.writeText(currentRecord->fCommonName.c_str()); |
| 216 stream.writeText("\",\n"); | 260 stream.writeText("\",\n"); |
| 217 | 261 |
| 218 stream.writeText(" \"differencePath\": \""); | 262 stream.writeText(" \"differencePath\": \""); |
| 219 stream.writeText(differenceAbsPath.c_str()); | 263 stream.writeText(differenceAbsPath.c_str()); |
| 220 stream.writeText("\",\n"); | 264 stream.writeText("\",\n"); |
| 221 | 265 |
| 222 stream.writeText(" \"baselinePath\": \""); | 266 stream.writeText(" \"baselinePath\": \""); |
| 223 stream.writeText(baselineAbsPath.c_str()); | 267 stream.writeText(baselineAbsPath.c_str()); |
| 224 stream.writeText("\",\n"); | 268 stream.writeText("\",\n"); |
| 225 | 269 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 for (int i = 0; i < cntColumns; i++) { | 380 for (int i = 0; i < cntColumns; i++) { |
| 337 SkString str; | 381 SkString str; |
| 338 str.printf(", %f", values[i]); | 382 str.printf(", %f", values[i]); |
| 339 stream.writeText(str.c_str()); | 383 stream.writeText(str.c_str()); |
| 340 } | 384 } |
| 341 stream.writeText("\n"); | 385 stream.writeText("\n"); |
| 342 | 386 |
| 343 currentRecord = currentRecord->fNext; | 387 currentRecord = currentRecord->fNext; |
| 344 } | 388 } |
| 345 } | 389 } |
| OLD | NEW |