OLD | NEW |
---|---|
(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 } | |
OLD | NEW |