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

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: attempt to fix "'abs' : ambiguous call to overloaded function" on Windows Created 6 years, 5 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
« no previous file with comments | « tools/skpdiff/SkDiffContext.h ('k') | tools/skpdiff/SkDifferentPixelsMetric.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
11 #include "SkRunnable.h" 11 #include "SkRunnable.h"
12 #include "SkSize.h"
12 #include "SkStream.h" 13 #include "SkStream.h"
13 #include "SkTDict.h" 14 #include "SkTDict.h"
14 #include "SkThreadPool.h" 15 #include "SkThreadPool.h"
15 16
16 #include "SkDiffContext.h" 17 #include "SkDiffContext.h"
18 #include "SkImageDiffer.h"
17 #include "skpdiff_util.h" 19 #include "skpdiff_util.h"
18 20
19 SkDiffContext::SkDiffContext() { 21 SkDiffContext::SkDiffContext() {
20 fDiffers = NULL; 22 fDiffers = NULL;
21 fDifferCount = 0; 23 fDifferCount = 0;
22 fThreadCount = SkThreadPool::kThreadPerCore; 24 fThreadCount = SkThreadPool::kThreadPerCore;
23 } 25 }
24 26
25 SkDiffContext::~SkDiffContext() { 27 SkDiffContext::~SkDiffContext() {
26 if (NULL != fDiffers) { 28 if (NULL != fDiffers) {
27 SkDELETE_ARRAY(fDiffers); 29 SkDELETE_ARRAY(fDiffers);
28 } 30 }
29 } 31 }
30 32
31 void SkDiffContext::setDifferenceDir(const SkString& path) { 33 void SkDiffContext::setAlphaMaskDir(const SkString& path) {
32 if (!path.isEmpty() && sk_mkdir(path.c_str())) { 34 if (!path.isEmpty() && sk_mkdir(path.c_str())) {
33 fDifferenceDir = path; 35 fAlphaMaskDir = path;
34 } 36 }
35 } 37 }
36 38
39 void SkDiffContext::setRgbDiffDir(const SkString& path) {
40 if (!path.isEmpty() && sk_mkdir(path.c_str())) {
41 fRgbDiffDir = path;
42 }
43 }
44
45 void SkDiffContext::setWhiteDiffDir(const SkString& path) {
46 if (!path.isEmpty() && sk_mkdir(path.c_str())) {
47 fWhiteDiffDir = path;
48 }
49 }
50
37 void SkDiffContext::setDiffers(const SkTDArray<SkImageDiffer*>& differs) { 51 void SkDiffContext::setDiffers(const SkTDArray<SkImageDiffer*>& differs) {
38 // Delete whatever the last array of differs was 52 // Delete whatever the last array of differs was
39 if (NULL != fDiffers) { 53 if (NULL != fDiffers) {
40 SkDELETE_ARRAY(fDiffers); 54 SkDELETE_ARRAY(fDiffers);
41 fDiffers = NULL; 55 fDiffers = NULL;
42 fDifferCount = 0; 56 fDifferCount = 0;
43 } 57 }
44 58
45 // Copy over the new differs 59 // Copy over the new differs
46 fDifferCount = differs.count(); 60 fDifferCount = differs.count();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 DiffRecord* newRecord = fRecords.addToHead(DiffRecord()); 97 DiffRecord* newRecord = fRecords.addToHead(DiffRecord());
84 fRecordMutex.release(); 98 fRecordMutex.release();
85 99
86 // compute the common name 100 // compute the common name
87 SkString baseName = SkOSPath::SkBasename(baselinePath); 101 SkString baseName = SkOSPath::SkBasename(baselinePath);
88 SkString testName = SkOSPath::SkBasename(testPath); 102 SkString testName = SkOSPath::SkBasename(testPath);
89 newRecord->fCommonName = get_common_prefix(baseName, testName); 103 newRecord->fCommonName = get_common_prefix(baseName, testName);
90 104
91 newRecord->fBaselinePath = baselinePath; 105 newRecord->fBaselinePath = baselinePath;
92 newRecord->fTestPath = testPath; 106 newRecord->fTestPath = testPath;
107 newRecord->fSize = SkISize::Make(baselineBitmap.width(), baselineBitmap.heig ht());
93 108
94 bool alphaMaskPending = false; 109 // only generate diff images if we have a place to store them
95 110 SkImageDiffer::BitmapsToCreate bitmapsToCreate;
96 // only enable alpha masks if a difference dir has been provided 111 bitmapsToCreate.alphaMask = !fAlphaMaskDir.isEmpty();
97 if (!fDifferenceDir.isEmpty()) { 112 bitmapsToCreate.rgbDiff = !fRgbDiffDir.isEmpty();
98 alphaMaskPending = true; 113 bitmapsToCreate.whiteDiff = !fWhiteDiffDir.isEmpty();
99 }
100 114
101 // Perform each diff 115 // Perform each diff
102 for (int differIndex = 0; differIndex < fDifferCount; differIndex++) { 116 for (int differIndex = 0; differIndex < fDifferCount; differIndex++) {
103 SkImageDiffer* differ = fDiffers[differIndex]; 117 SkImageDiffer* differ = fDiffers[differIndex];
104 118
105 // Copy the results into data for this record 119 // Copy the results into data for this record
106 DiffData& diffData = newRecord->fDiffs.push_back(); 120 DiffData& diffData = newRecord->fDiffs.push_back();
107 diffData.fDiffName = differ->getName(); 121 diffData.fDiffName = differ->getName();
108 122
109 if (!differ->diff(&baselineBitmap, &testBitmap, alphaMaskPending, &diffD ata.fResult)) { 123 if (!differ->diff(&baselineBitmap, &testBitmap, bitmapsToCreate, &diffDa ta.fResult)) {
110 // if the diff failed record -1 as the result 124 // if the diff failed, record -1 as the result
125 // TODO(djsollen): Record more detailed information about exactly wh at failed.
126 // (Image dimension mismatch? etc.) See http://skbug.com/2710 ('mak e skpdiff
127 // report more detail when it fails to compare two images')
111 diffData.fResult.result = -1; 128 diffData.fResult.result = -1;
112 continue; 129 continue;
113 } 130 }
114 131
115 if (alphaMaskPending 132 if (bitmapsToCreate.alphaMask
116 && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result 133 && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
117 && !diffData.fResult.poiAlphaMask.empty() 134 && !diffData.fResult.poiAlphaMask.empty()
118 && !newRecord->fCommonName.isEmpty()) { 135 && !newRecord->fCommonName.isEmpty()) {
119 136
120 newRecord->fDifferencePath = SkOSPath::SkPathJoin(fDifferenceDir.c_s tr(), 137 newRecord->fAlphaMaskPath = SkOSPath::SkPathJoin(fAlphaMaskDir.c_str (),
121 newRecord->fCommon Name.c_str()); 138 newRecord->fCommonN ame.c_str());
122 139
123 // compute the image diff and output it 140 // compute the image diff and output it
124 SkBitmap copy; 141 SkBitmap copy;
125 diffData.fResult.poiAlphaMask.copyTo(&copy, kN32_SkColorType); 142 diffData.fResult.poiAlphaMask.copyTo(&copy, kN32_SkColorType);
126 SkImageEncoder::EncodeFile(newRecord->fDifferencePath.c_str(), copy, 143 SkImageEncoder::EncodeFile(newRecord->fAlphaMaskPath.c_str(), copy,
127 SkImageEncoder::kPNG_Type, 100); 144 SkImageEncoder::kPNG_Type, 100);
128 145
129 // cleanup the existing bitmap to free up resources; 146 // cleanup the existing bitmap to free up resources;
130 diffData.fResult.poiAlphaMask.reset(); 147 diffData.fResult.poiAlphaMask.reset();
131 148
132 alphaMaskPending = false; 149 bitmapsToCreate.alphaMask = false;
150 }
151
152 if (bitmapsToCreate.rgbDiff
153 && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
154 && !diffData.fResult.rgbDiffBitmap.empty()
155 && !newRecord->fCommonName.isEmpty()) {
156 // TODO(djsollen): Rather than taking the max r/g/b diffs that come back from
157 // a particular differ and storing them as toplevel fields within
158 // newRecord, we should extend outputRecords() to report optional
159 // fields for each differ (not just "result" and "pointsOfInterest") .
160 // See http://skbug.com/2712 ('allow skpdiff to report different set s
161 // of result fields for different comparison algorithms')
162 newRecord->fMaxRedDiff = diffData.fResult.maxRedDiff;
163 newRecord->fMaxGreenDiff = diffData.fResult.maxGreenDiff;
164 newRecord->fMaxBlueDiff = diffData.fResult.maxBlueDiff;
165
166 newRecord->fRgbDiffPath = SkOSPath::SkPathJoin(fRgbDiffDir.c_str(),
167 newRecord->fCommonNam e.c_str());
168 SkImageEncoder::EncodeFile(newRecord->fRgbDiffPath.c_str(),
169 diffData.fResult.rgbDiffBitmap,
170 SkImageEncoder::kPNG_Type, 100);
171 diffData.fResult.rgbDiffBitmap.reset();
172 bitmapsToCreate.rgbDiff = false;
173 }
174
175 if (bitmapsToCreate.whiteDiff
176 && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
177 && !diffData.fResult.whiteDiffBitmap.empty()
178 && !newRecord->fCommonName.isEmpty()) {
179 newRecord->fWhiteDiffPath = SkOSPath::SkPathJoin(fWhiteDiffDir.c_str (),
180 newRecord->fCommonN ame.c_str());
181 SkImageEncoder::EncodeFile(newRecord->fWhiteDiffPath.c_str(),
182 diffData.fResult.whiteDiffBitmap,
183 SkImageEncoder::kPNG_Type, 100);
184 diffData.fResult.whiteDiffBitmap.reset();
185 bitmapsToCreate.whiteDiff = false;
133 } 186 }
134 } 187 }
135 } 188 }
136 189
137 class SkThreadedDiff : public SkRunnable { 190 class SkThreadedDiff : public SkRunnable {
138 public: 191 public:
139 SkThreadedDiff() : fDiffContext(NULL) { } 192 SkThreadedDiff() : fDiffContext(NULL) { }
140 193
141 void setup(SkDiffContext* diffContext, const SkString& baselinePath, const S kString& testPath) { 194 void setup(SkDiffContext* diffContext, const SkString& baselinePath, const S kString& testPath) {
142 fDiffContext = diffContext; 195 fDiffContext = diffContext;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 275
223 void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) { 276 void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
224 SkTLList<DiffRecord>::Iter iter(fRecords, SkTLList<DiffRecord>::Iter::kHead_ IterStart); 277 SkTLList<DiffRecord>::Iter iter(fRecords, SkTLList<DiffRecord>::Iter::kHead_ IterStart);
225 DiffRecord* currentRecord = iter.get(); 278 DiffRecord* currentRecord = iter.get();
226 279
227 if (useJSONP) { 280 if (useJSONP) {
228 stream.writeText("var SkPDiffRecords = {\n"); 281 stream.writeText("var SkPDiffRecords = {\n");
229 } else { 282 } else {
230 stream.writeText("{\n"); 283 stream.writeText("{\n");
231 } 284 }
285
286 // TODO(djsollen): Would it be better to use the jsoncpp library to write ou t the JSON?
287 // This manual approach is probably more efficient, but it sure is ugly.
288 // See http://skbug.com/2713 ('make skpdiff use jsoncpp library to write out
289 // JSON output, instead of manual writeText() calls?')
232 stream.writeText(" \"records\": [\n"); 290 stream.writeText(" \"records\": [\n");
233 while (NULL != currentRecord) { 291 while (NULL != currentRecord) {
234 stream.writeText(" {\n"); 292 stream.writeText(" {\n");
235 293
236 SkString differenceAbsPath = get_absolute_path(currentRecord->fDiffe rencePath);
237 SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselin ePath); 294 SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselin ePath);
238 SkString testAbsPath = get_absolute_path(currentRecord->fTestPath); 295 SkString testAbsPath = get_absolute_path(currentRecord->fTestPath);
239 296
240 stream.writeText(" \"commonName\": \""); 297 stream.writeText(" \"commonName\": \"");
241 stream.writeText(currentRecord->fCommonName.c_str()); 298 stream.writeText(currentRecord->fCommonName.c_str());
242 stream.writeText("\",\n"); 299 stream.writeText("\",\n");
243 300
244 stream.writeText(" \"differencePath\": \""); 301 stream.writeText(" \"differencePath\": \"");
245 stream.writeText(differenceAbsPath.c_str()); 302 stream.writeText(get_absolute_path(currentRecord->fAlphaMaskPath).c_ str());
303 stream.writeText("\",\n");
304
305 stream.writeText(" \"rgbDiffPath\": \"");
306 stream.writeText(get_absolute_path(currentRecord->fRgbDiffPath).c_st r());
307 stream.writeText("\",\n");
308
309 stream.writeText(" \"whiteDiffPath\": \"");
310 stream.writeText(get_absolute_path(currentRecord->fWhiteDiffPath).c_ str());
246 stream.writeText("\",\n"); 311 stream.writeText("\",\n");
247 312
248 stream.writeText(" \"baselinePath\": \""); 313 stream.writeText(" \"baselinePath\": \"");
249 stream.writeText(baselineAbsPath.c_str()); 314 stream.writeText(baselineAbsPath.c_str());
250 stream.writeText("\",\n"); 315 stream.writeText("\",\n");
251 316
252 stream.writeText(" \"testPath\": \""); 317 stream.writeText(" \"testPath\": \"");
253 stream.writeText(testAbsPath.c_str()); 318 stream.writeText(testAbsPath.c_str());
254 stream.writeText("\",\n"); 319 stream.writeText("\",\n");
255 320
321 stream.writeText(" \"width\": ");
322 stream.writeDecAsText(currentRecord->fSize.width());
323 stream.writeText(",\n");
324 stream.writeText(" \"height\": ");
325 stream.writeDecAsText(currentRecord->fSize.height());
326 stream.writeText(",\n");
327
328 stream.writeText(" \"maxRedDiff\": ");
329 stream.writeDecAsText(currentRecord->fMaxRedDiff);
330 stream.writeText(",\n");
331 stream.writeText(" \"maxGreenDiff\": ");
332 stream.writeDecAsText(currentRecord->fMaxGreenDiff);
333 stream.writeText(",\n");
334 stream.writeText(" \"maxBlueDiff\": ");
335 stream.writeDecAsText(currentRecord->fMaxBlueDiff);
336 stream.writeText(",\n");
337
256 stream.writeText(" \"diffs\": [\n"); 338 stream.writeText(" \"diffs\": [\n");
257 for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); d iffIndex++) { 339 for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); d iffIndex++) {
258 DiffData& data = currentRecord->fDiffs[diffIndex]; 340 DiffData& data = currentRecord->fDiffs[diffIndex];
259 stream.writeText(" {\n"); 341 stream.writeText(" {\n");
260 342
261 stream.writeText(" \"differName\": \""); 343 stream.writeText(" \"differName\": \"");
262 stream.writeText(data.fDiffName); 344 stream.writeText(data.fDiffName);
263 stream.writeText("\",\n"); 345 stream.writeText("\",\n");
264 346
265 stream.writeText(" \"result\": "); 347 stream.writeText(" \"result\": ");
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 for (int i = 0; i < cntColumns; i++) { 433 for (int i = 0; i < cntColumns; i++) {
352 SkString str; 434 SkString str;
353 str.printf(", %f", values[i]); 435 str.printf(", %f", values[i]);
354 stream.writeText(str.c_str()); 436 stream.writeText(str.c_str());
355 } 437 }
356 stream.writeText("\n"); 438 stream.writeText("\n");
357 439
358 currentRecord = iter2.next(); 440 currentRecord = iter2.next();
359 } 441 }
360 } 442 }
OLDNEW
« no previous file with comments | « tools/skpdiff/SkDiffContext.h ('k') | tools/skpdiff/SkDifferentPixelsMetric.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698