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

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

Issue 18348011: add diff recording and output code (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 #include "SkBitmap.h"
bsalomon 2013/07/02 13:37:15 Need copyright
2 #include "SkImageDecoder.h"
3 #include "SkOSFile.h"
4 #include "SkStream.h"
5
6 #include "SkDiffContext.h"
7 #include "SkImageDiffer.h"
8 #include "skpdiff_util.h"
9
10 SkDiffContext::SkDiffContext()
bsalomon 2013/07/02 13:37:15 style nit: { goes on previous line, here and below
11 {
12 fRecords = NULL;
13 fDiffers = NULL;
14 fDifferCount = 0;
15 }
16
17 SkDiffContext::~SkDiffContext()
18 {
19 // Delete the record linked list
20 DiffRecord* currentRecord = fRecords;
21 while (currentRecord != NULL) {
bsalomon 2013/07/02 13:37:15 we usually write NULL != currentRecord and NULL ==
22 DiffRecord* nextRecord = currentRecord->fNext;
23 SkDELETE(currentRecord);
24 currentRecord = nextRecord;
25 }
26
27 if (fDiffers != NULL) {
28 SkDELETE_ARRAY(fDiffers);
29 }
30 }
31
32 void SkDiffContext::setDiffers(const SkTDArray<SkImageDiffer*>& differs) {
33 // Delete whatever the last array of differs was
34 if (fDiffers != NULL) {
35 SkDELETE_ARRAY(fDiffers);
36 fDiffers = NULL;
37 fDifferCount = 0;
38 }
39
40 // Copy over the new differs
41 fDifferCount = differs.count();
42 fDiffers = SkNEW_ARRAY(SkImageDiffer*, fDifferCount);
43 differs.copy(fDiffers);
44 }
45
46 void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) {
47 // Load the images at the paths
48 SkBitmap baselineBitmap;
49 SkBitmap testBitmap;
50 if (!SkImageDecoder::DecodeFile(baselinePath, &baselineBitmap)) {
51 SkDebugf("Failed to load bitmap \"%s\"\n", baselinePath);
52 return;
53 }
54 if (!SkImageDecoder::DecodeFile(testPath, &testBitmap)) {
55 SkDebugf("Failed to load bitmap \"%s\"\n", testPath);
56 return;
57 }
58
59 // Setup a record for this diff
60 DiffRecord* newRecord = SkNEW(DiffRecord);
61 newRecord->fBaselinePath = baselinePath;
62 newRecord->fTestPath = testPath;
63 newRecord->fNext = fRecords;
64 fRecords = newRecord;
65
66 // Perform each diff
67 for (unsigned differIndex = 0; differIndex < fDifferCount; differIndex++) {
bsalomon 2013/07/02 13:37:15 see above about fDifferCount
68 SkImageDiffer* differ = fDiffers[differIndex];
69 int diffID = differ->queueDiff(&baselineBitmap, &testBitmap);
70 if (diffID >= 0) {
71
72 // Copy the results into data for this record
73 DiffData& diffData = newRecord->fDiffs.push_back();
74
75 diffData.fDiffName = differ->getName();
76 diffData.fResult = differ->getResult(diffID);
77
78 int poiCount = differ->getPointsOfInterestCount(diffID);
79 SkIPoint* poi = differ->getPointsOfInterest(diffID);
80 diffData.fPointsOfInterest.append(poiCount, poi);
81
82 // Because we are doing everything synchronously for now, we are don e with the diff
83 // after reading it.
84 differ->deleteDiff(diffID);
85 }
86 }
87 }
88
89
90 void SkDiffContext::diffDirectories(const char baselinePath[], const char testPa th[]) {
91 // Get the files in the baseline, we will then look for those inside the tes t path
92 SkTArray<SkString> baselineEntries;
93 if (!get_directory(baselinePath, &baselineEntries)) {
94 SkDebugf("Unable to open path \"%s\"\n", baselinePath);
95 return;
96 }
97
98 for (int baselineIndex = 0; baselineIndex < baselineEntries.count(); baselin eIndex++) {
99 const char* baseFilename = baselineEntries[baselineIndex].c_str();
100
101 // Find the real location of each file to compare
102 SkString baselineFile = SkOSPath::SkPathJoin(baselinePath, baseFilename) ;
103 SkString testFile = SkOSPath::SkPathJoin(testPath, baseFilename);
104
105 // Check that the test file exists and is a file
106 if (sk_exists(testFile.c_str()) && !sk_isdir(testFile.c_str())) {
107 // Queue up the comparison with the differ
108 this->addDiff(baselineFile.c_str(), testFile.c_str());
109 } else {
110 SkDebugf("Baseline file \"%s\" has no corresponding test file\n", ba selineFile.c_str());
111 }
112 }
113 }
114
115
116 void SkDiffContext::diffPatterns(const char baselinePattern[], const char testPa ttern[]) {
117 // Get the files in the baseline and test patterns. Because they are in sort ed order, it's easy
118 // to find corresponding images by matching entry indices.
119
120 SkTArray<SkString> baselineEntries;
121 if (!glob_files(baselinePattern, &baselineEntries)) {
122 SkDebugf("Unable to get pattern \"%s\"\n", baselinePattern);
123 return;
124 }
125
126 SkTArray<SkString> testEntries;
127 if (!glob_files(testPattern, &testEntries)) {
128 SkDebugf("Unable to get pattern \"%s\"\n", testPattern);
129 return;
130 }
131
132 if (baselineEntries.count() != testEntries.count()) {
133 SkDebugf("Baseline and test patterns do not yield corresponding number o f files\n");
134 return;
135 }
136
137 for (int entryIndex = 0; entryIndex < baselineEntries.count(); entryIndex++) {
138 const char* baselineFilename = baselineEntries[entryIndex].c_str();
139 const char* testFilename = testEntries [entryIndex].c_str();
140
141 this->addDiff(baselineFilename, testFilename);
142 }
143 }
144
145 void SkDiffContext::outputRecords(SkWStream& stream) {
146 DiffRecord* currentRecord = fRecords;
147 stream.writeText("{\n");
148 stream.writeText(" \"records\": [\n");
bsalomon 2013/07/02 13:37:15 Maybe the format of the json should be documented
149 while (currentRecord != NULL) {
150 stream.writeText(" {\n");
151
152 stream.writeText(" \"baselinePath\": \"");
153 stream.writeText(currentRecord->fBaselinePath.c_str());
154 stream.writeText("\",\n");
155
156 stream.writeText(" \"testPath\": \"");
157 stream.writeText(currentRecord->fTestPath.c_str());
158 stream.writeText("\",\n");
159
160 stream.writeText(" \"diffs\": [\n");
161 for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); d iffIndex++) {
162 DiffData& data = currentRecord->fDiffs[diffIndex];
163 stream.writeText(" {\n");
164
165 stream.writeText(" \"differName\": \"");
166 stream.writeText(data.fDiffName);
167 stream.writeText("\",\n");
168
169 stream.writeText(" \"result\": ");
170 stream.writeScalarAsText(data.fResult);
171 stream.writeText(",\n");
172
173 stream.writeText(" \"pointsOfInterest\": [\n");
174 for (int poiIndex = 0; poiIndex < data.fPointsOfInterest.cou nt(); poiIndex++) {
175 SkIPoint poi = data.fPointsOfInterest[poiIndex];
176 stream.writeText(" [");
177 stream.writeDecAsText(poi.x());
178 stream.writeText(",");
179 stream.writeDecAsText(poi.y());
180 stream.writeText("]");
181
182 // JSON does not allow trailing commas
183 if (poiIndex + 1 < data.fPointsOfInterest.count())
184 {
185 stream.writeText(",");
186 }
187 stream.writeText("\n");
188 }
189 stream.writeText(" ]\n");
190 stream.writeText(" }");
191
192 // JSON does not allow trailing commas
193 if (diffIndex + 1 < currentRecord->fDiffs.count())
194 {
195 stream.writeText(",");
196 }
197 stream.writeText(" \n");
198 }
199 stream.writeText(" ]\n");
200
201 stream.writeText(" }");
202
203 // JSON does not allow trailing commas
204 if (NULL != currentRecord->fNext)
205 {
206 stream.writeText(",");
207 }
208 stream.writeText("\n");
209 currentRecord = currentRecord->fNext;
210 }
211 stream.writeText(" ]\n");
212 stream.writeText("}\n");
213 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698