Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: tools/skpdiff/SkDiffContext.cpp

Issue 325413003: rebaseline_server: use just skpdiff, not Python Image Library (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 10 matching lines...) Expand all
21 fDifferCount = 0; 21 fDifferCount = 0;
22 fThreadCount = SkThreadPool::kThreadPerCore; 22 fThreadCount = SkThreadPool::kThreadPerCore;
23 } 23 }
24 24
25 SkDiffContext::~SkDiffContext() { 25 SkDiffContext::~SkDiffContext() {
26 if (NULL != fDiffers) { 26 if (NULL != fDiffers) {
27 SkDELETE_ARRAY(fDiffers); 27 SkDELETE_ARRAY(fDiffers);
28 } 28 }
29 } 29 }
30 30
31 void SkDiffContext::setDifferenceDir(const SkString& path) { 31 void SkDiffContext::setAlphaMaskDir(const SkString& path) {
32 if (!path.isEmpty() && sk_mkdir(path.c_str())) { 32 if (!path.isEmpty() && sk_mkdir(path.c_str())) {
33 fDifferenceDir = path; 33 fAlphaMaskDir = path;
34 } 34 }
35 } 35 }
36 36
37 void SkDiffContext::setRgbDiffDir(const SkString& path) {
38 if (!path.isEmpty() && sk_mkdir(path.c_str())) {
39 fRgbDiffDir = path;
40 }
41 }
42
43 void SkDiffContext::setWhiteDiffDir(const SkString& path) {
44 if (!path.isEmpty() && sk_mkdir(path.c_str())) {
45 fWhiteDiffDir = path;
46 }
47 }
48
37 void SkDiffContext::setDiffers(const SkTDArray<SkImageDiffer*>& differs) { 49 void SkDiffContext::setDiffers(const SkTDArray<SkImageDiffer*>& differs) {
38 // Delete whatever the last array of differs was 50 // Delete whatever the last array of differs was
39 if (NULL != fDiffers) { 51 if (NULL != fDiffers) {
40 SkDELETE_ARRAY(fDiffers); 52 SkDELETE_ARRAY(fDiffers);
41 fDiffers = NULL; 53 fDiffers = NULL;
42 fDifferCount = 0; 54 fDifferCount = 0;
43 } 55 }
44 56
45 // Copy over the new differs 57 // Copy over the new differs
46 fDifferCount = differs.count(); 58 fDifferCount = differs.count();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 DiffRecord* newRecord = fRecords.addToHead(DiffRecord()); 95 DiffRecord* newRecord = fRecords.addToHead(DiffRecord());
84 fRecordMutex.release(); 96 fRecordMutex.release();
85 97
86 // compute the common name 98 // compute the common name
87 SkString baseName = SkOSPath::SkBasename(baselinePath); 99 SkString baseName = SkOSPath::SkBasename(baselinePath);
88 SkString testName = SkOSPath::SkBasename(testPath); 100 SkString testName = SkOSPath::SkBasename(testPath);
89 newRecord->fCommonName = get_common_prefix(baseName, testName); 101 newRecord->fCommonName = get_common_prefix(baseName, testName);
90 102
91 newRecord->fBaselinePath = baselinePath; 103 newRecord->fBaselinePath = baselinePath;
92 newRecord->fTestPath = testPath; 104 newRecord->fTestPath = testPath;
105 newRecord->fWidth = baselineBitmap.width();
106 newRecord->fHeight = baselineBitmap.height();
93 107
94 bool alphaMaskPending = false; 108 // only generate diff images if we have a place to store them
95 109 bool alphaMaskPending = !fAlphaMaskDir.isEmpty();
96 // only enable alpha masks if a difference dir has been provided 110 bool rgbDiffPending = !fRgbDiffDir.isEmpty();
97 if (!fDifferenceDir.isEmpty()) { 111 bool whiteDiffPending = !fWhiteDiffDir.isEmpty();
98 alphaMaskPending = true;
99 }
100 112
101 // Perform each diff 113 // Perform each diff
102 for (int differIndex = 0; differIndex < fDifferCount; differIndex++) { 114 for (int differIndex = 0; differIndex < fDifferCount; differIndex++) {
103 SkImageDiffer* differ = fDiffers[differIndex]; 115 SkImageDiffer* differ = fDiffers[differIndex];
104 116
105 // Copy the results into data for this record 117 // Copy the results into data for this record
106 DiffData& diffData = newRecord->fDiffs.push_back(); 118 DiffData& diffData = newRecord->fDiffs.push_back();
107 diffData.fDiffName = differ->getName(); 119 diffData.fDiffName = differ->getName();
108 120
109 if (!differ->diff(&baselineBitmap, &testBitmap, alphaMaskPending, &diffD ata.fResult)) { 121 if (!differ->diff(&baselineBitmap, &testBitmap, alphaMaskPending, rgbDif fPending,
110 // if the diff failed record -1 as the result 122 whiteDiffPending, &diffData.fResult)) {
123 // if the diff failed, record -1 as the result
111 diffData.fResult.result = -1; 124 diffData.fResult.result = -1;
112 continue; 125 continue;
113 } 126 }
114 127
115 if (alphaMaskPending 128 if (alphaMaskPending
116 && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result 129 && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
117 && !diffData.fResult.poiAlphaMask.empty() 130 && !diffData.fResult.poiAlphaMask.empty()
118 && !newRecord->fCommonName.isEmpty()) { 131 && !newRecord->fCommonName.isEmpty()) {
119 132
120 newRecord->fDifferencePath = SkOSPath::SkPathJoin(fDifferenceDir.c_s tr(), 133 newRecord->fAlphaMaskPath = SkOSPath::SkPathJoin(fAlphaMaskDir.c_str (),
121 newRecord->fCommon Name.c_str()); 134 newRecord->fCommonN ame.c_str());
122 135
123 // compute the image diff and output it 136 // compute the image diff and output it
124 SkBitmap copy; 137 SkBitmap copy;
125 diffData.fResult.poiAlphaMask.copyTo(&copy, kN32_SkColorType); 138 diffData.fResult.poiAlphaMask.copyTo(&copy, kN32_SkColorType);
126 SkImageEncoder::EncodeFile(newRecord->fDifferencePath.c_str(), copy, 139 SkImageEncoder::EncodeFile(newRecord->fAlphaMaskPath.c_str(), copy,
127 SkImageEncoder::kPNG_Type, 100); 140 SkImageEncoder::kPNG_Type, 100);
128 141
129 // cleanup the existing bitmap to free up resources; 142 // cleanup the existing bitmap to free up resources;
130 diffData.fResult.poiAlphaMask.reset(); 143 diffData.fResult.poiAlphaMask.reset();
131 144
132 alphaMaskPending = false; 145 alphaMaskPending = false;
133 } 146 }
147
148 if (rgbDiffPending
149 && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
150 && !diffData.fResult.rgbDiffBitmap.empty()
151 && !newRecord->fCommonName.isEmpty()) {
152 // EPOGER: This is a hack, based on the knowledge that the same
153 // differ which gives us rgbDiffBitmap will also give us the
154 // max r/g/b diffs.
155 newRecord->fMaxRedDiff = diffData.fResult.maxRedDiff;
156 newRecord->fMaxGreenDiff = diffData.fResult.maxGreenDiff;
157 newRecord->fMaxBlueDiff = diffData.fResult.maxBlueDiff;
158
159 newRecord->fRgbDiffPath = SkOSPath::SkPathJoin(fRgbDiffDir.c_str(),
160 newRecord->fCommonNam e.c_str());
161 SkImageEncoder::EncodeFile(newRecord->fRgbDiffPath.c_str(),
162 diffData.fResult.rgbDiffBitmap,
163 SkImageEncoder::kPNG_Type, 100);
164 diffData.fResult.rgbDiffBitmap.reset();
165 rgbDiffPending = false;
166 }
167
168 if (whiteDiffPending
169 && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
170 && !diffData.fResult.whiteDiffBitmap.empty()
171 && !newRecord->fCommonName.isEmpty()) {
172 newRecord->fWhiteDiffPath = SkOSPath::SkPathJoin(fWhiteDiffDir.c_str (),
173 newRecord->fCommonN ame.c_str());
174 SkImageEncoder::EncodeFile(newRecord->fWhiteDiffPath.c_str(),
175 diffData.fResult.whiteDiffBitmap,
176 SkImageEncoder::kPNG_Type, 100);
177 diffData.fResult.whiteDiffBitmap.reset();
178 whiteDiffPending = false;
179 }
134 } 180 }
135 } 181 }
136 182
137 class SkThreadedDiff : public SkRunnable { 183 class SkThreadedDiff : public SkRunnable {
138 public: 184 public:
139 SkThreadedDiff() : fDiffContext(NULL) { } 185 SkThreadedDiff() : fDiffContext(NULL) { }
140 186
141 void setup(SkDiffContext* diffContext, const SkString& baselinePath, const S kString& testPath) { 187 void setup(SkDiffContext* diffContext, const SkString& baselinePath, const S kString& testPath) {
142 fDiffContext = diffContext; 188 fDiffContext = diffContext;
143 fBaselinePath = baselinePath; 189 fBaselinePath = baselinePath;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 268
223 void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) { 269 void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
224 SkTLList<DiffRecord>::Iter iter(fRecords, SkTLList<DiffRecord>::Iter::kHead_ IterStart); 270 SkTLList<DiffRecord>::Iter iter(fRecords, SkTLList<DiffRecord>::Iter::kHead_ IterStart);
225 DiffRecord* currentRecord = iter.get(); 271 DiffRecord* currentRecord = iter.get();
226 272
227 if (useJSONP) { 273 if (useJSONP) {
228 stream.writeText("var SkPDiffRecords = {\n"); 274 stream.writeText("var SkPDiffRecords = {\n");
229 } else { 275 } else {
230 stream.writeText("{\n"); 276 stream.writeText("{\n");
231 } 277 }
278
279 // TODO: Would it be better to use the jsoncpp library to write out the JSON ?
280 // This manual approach is probably more efficient, but it sure is ugly.
232 stream.writeText(" \"records\": [\n"); 281 stream.writeText(" \"records\": [\n");
233 while (NULL != currentRecord) { 282 while (NULL != currentRecord) {
234 stream.writeText(" {\n"); 283 stream.writeText(" {\n");
235 284
236 SkString differenceAbsPath = get_absolute_path(currentRecord->fDiffe rencePath);
237 SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselin ePath); 285 SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselin ePath);
238 SkString testAbsPath = get_absolute_path(currentRecord->fTestPath); 286 SkString testAbsPath = get_absolute_path(currentRecord->fTestPath);
239 287
240 stream.writeText(" \"commonName\": \""); 288 stream.writeText(" \"commonName\": \"");
241 stream.writeText(currentRecord->fCommonName.c_str()); 289 stream.writeText(currentRecord->fCommonName.c_str());
242 stream.writeText("\",\n"); 290 stream.writeText("\",\n");
243 291
244 stream.writeText(" \"differencePath\": \""); 292 stream.writeText(" \"differencePath\": \"");
245 stream.writeText(differenceAbsPath.c_str()); 293 stream.writeText(get_absolute_path(currentRecord->fAlphaMaskPath).c_ str());
294 stream.writeText("\",\n");
295
296 stream.writeText(" \"rgbDiffPath\": \"");
297 stream.writeText(get_absolute_path(currentRecord->fRgbDiffPath).c_st r());
298 stream.writeText("\",\n");
299
300 stream.writeText(" \"whiteDiffPath\": \"");
301 stream.writeText(get_absolute_path(currentRecord->fWhiteDiffPath).c_ str());
246 stream.writeText("\",\n"); 302 stream.writeText("\",\n");
247 303
248 stream.writeText(" \"baselinePath\": \""); 304 stream.writeText(" \"baselinePath\": \"");
249 stream.writeText(baselineAbsPath.c_str()); 305 stream.writeText(baselineAbsPath.c_str());
250 stream.writeText("\",\n"); 306 stream.writeText("\",\n");
251 307
252 stream.writeText(" \"testPath\": \""); 308 stream.writeText(" \"testPath\": \"");
253 stream.writeText(testAbsPath.c_str()); 309 stream.writeText(testAbsPath.c_str());
254 stream.writeText("\",\n"); 310 stream.writeText("\",\n");
255 311
312 stream.writeText(" \"width\": ");
313 stream.writeDecAsText(currentRecord->fWidth);
314 stream.writeText(",\n");
315 stream.writeText(" \"height\": ");
316 stream.writeDecAsText(currentRecord->fHeight);
317 stream.writeText(",\n");
318
319 stream.writeText(" \"maxRedDiff\": ");
epoger 2014/06/12 07:02:07 Here I jammed in the various parameters that I had
320 stream.writeDecAsText(currentRecord->fMaxRedDiff);
321 stream.writeText(",\n");
322 stream.writeText(" \"maxGreenDiff\": ");
323 stream.writeDecAsText(currentRecord->fMaxGreenDiff);
324 stream.writeText(",\n");
325 stream.writeText(" \"maxBlueDiff\": ");
326 stream.writeDecAsText(currentRecord->fMaxBlueDiff);
327 stream.writeText(",\n");
328
256 stream.writeText(" \"diffs\": [\n"); 329 stream.writeText(" \"diffs\": [\n");
257 for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); d iffIndex++) { 330 for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); d iffIndex++) {
258 DiffData& data = currentRecord->fDiffs[diffIndex]; 331 DiffData& data = currentRecord->fDiffs[diffIndex];
259 stream.writeText(" {\n"); 332 stream.writeText(" {\n");
260 333
261 stream.writeText(" \"differName\": \""); 334 stream.writeText(" \"differName\": \"");
262 stream.writeText(data.fDiffName); 335 stream.writeText(data.fDiffName);
263 stream.writeText("\",\n"); 336 stream.writeText("\",\n");
264 337
265 stream.writeText(" \"result\": "); 338 stream.writeText(" \"result\": ");
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 for (int i = 0; i < cntColumns; i++) { 424 for (int i = 0; i < cntColumns; i++) {
352 SkString str; 425 SkString str;
353 str.printf(", %f", values[i]); 426 str.printf(", %f", values[i]);
354 stream.writeText(str.c_str()); 427 stream.writeText(str.c_str());
355 } 428 }
356 stream.writeText("\n"); 429 stream.writeText("\n");
357 430
358 currentRecord = iter2.next(); 431 currentRecord = iter2.next();
359 } 432 }
360 } 433 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698