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 |