OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2013 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "gm_expectations.h" | |
9 #include "SkBitmapHasher.h" | |
10 #include "SkImageDecoder.h" | |
11 | |
12 #define DEBUGFAIL_SEE_STDERR SkDEBUGFAIL("see stderr for message") | |
13 | |
14 const static char kJsonKey_ActualResults[] = "actual-results"; | |
epoger
2013/04/25 19:17:42
patchset 3 moves all the json field names into gm_
| |
15 const static char kJsonKey_ActualResults_Failed[] = "failed"; | |
16 const static char kJsonKey_ActualResults_FailureIgnored[]= "failure-ignored"; | |
17 const static char kJsonKey_ActualResults_NoComparison[] = "no-comparison"; | |
18 const static char kJsonKey_ActualResults_Succeeded[] = "succeeded"; | |
19 const static char kJsonKey_ActualResults_AnyStatus_BitmapCityhash[] = "bitmap-c ityhash"; | |
20 | |
21 const static char kJsonKey_ExpectedResults[] = "expected-results"; | |
22 const static char kJsonKey_ExpectedResults_AllowedBitmapCityhashes[] = "allowed- bitmap-cityhashes"; | |
23 const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-f ailure"; | |
24 | |
25 // EPOGER: misc cleanup (including 100 char wraps) | |
26 namespace skiagm { | |
27 | |
28 Json::Value ActualResultAsJsonValue(const SkHashDigest& result) { | |
29 Json::Value jsonValue; | |
30 jsonValue[kJsonKey_ActualResults_AnyStatus_BitmapCityhash] = asJsonValue (result); | |
31 return jsonValue; | |
32 } | |
33 | |
34 Json::Value CreateJsonTree(Json::Value expectedResults, | |
35 Json::Value actualResultsFailed, | |
36 Json::Value actualResultsFailureIgnored, | |
37 Json::Value actualResultsNoComparison, | |
38 Json::Value actualResultsSucceeded) { | |
39 Json::Value actualResults; | |
40 actualResults[kJsonKey_ActualResults_Failed] = actualResultsFailed; | |
41 actualResults[kJsonKey_ActualResults_FailureIgnored] = actualResultsFail ureIgnored; | |
42 actualResults[kJsonKey_ActualResults_NoComparison] = actualResultsNoComp arison; | |
43 actualResults[kJsonKey_ActualResults_Succeeded] = actualResultsSucceeded ; | |
44 Json::Value root; | |
45 root[kJsonKey_ActualResults] = actualResults; | |
46 root[kJsonKey_ExpectedResults] = expectedResults; | |
47 return root; | |
48 } | |
49 | |
50 | |
51 // Expectations class... | |
52 | |
53 Expectations::Expectations(bool ignoreFailure) { | |
54 fIgnoreFailure = ignoreFailure; | |
55 } | |
56 | |
57 Expectations::Expectations(const SkBitmap& bitmap, bool ignoreFailure) { | |
58 fBitmap = bitmap; | |
59 fIgnoreFailure = ignoreFailure; | |
60 SkHashDigest digest; | |
61 // TODO(epoger): Better handling for error returned by ComputeDigest()? | |
62 // For now, we just report a digest of 0 in error cases, like before. | |
63 if (!SkBitmapHasher::ComputeDigest(bitmap, &digest)) { | |
64 digest = 0; | |
65 } | |
66 fAllowedBitmapCityhashes.push_back() = digest; | |
67 } | |
68 | |
69 Expectations::Expectations(Json::Value jsonElement) { | |
70 if (jsonElement.empty()) { | |
71 fIgnoreFailure = kDefaultIgnoreFailure; | |
72 } else { | |
73 Json::Value ignoreFailure = jsonElement[kJsonKey_ExpectedResults_Ign oreFailure]; | |
74 if (ignoreFailure.isNull()) { | |
75 fIgnoreFailure = kDefaultIgnoreFailure; | |
76 } else if (!ignoreFailure.isBool()) { | |
77 gm_fprintf(stderr, "found non-boolean json value" | |
78 " for key '%s' in element '%s'\n", | |
79 kJsonKey_ExpectedResults_IgnoreFailure, | |
80 jsonElement.toStyledString().c_str()); | |
81 DEBUGFAIL_SEE_STDERR; | |
82 fIgnoreFailure = kDefaultIgnoreFailure; | |
83 } else { | |
84 fIgnoreFailure = ignoreFailure.asBool(); | |
85 } | |
86 | |
87 Json::Value allowedChecksums = jsonElement[kJsonKey_ExpectedResults_ AllowedBitmapCityhashes]; | |
88 if (allowedChecksums.isNull()) { | |
89 // ok, we'll just assume there aren't any expected checksums to compare against | |
90 } else if (!allowedChecksums.isArray()) { | |
91 gm_fprintf(stderr, "found non-array json value" | |
92 " for key '%s' in element '%s'\n", | |
93 kJsonKey_ExpectedResults_AllowedBitmapCityhashes, | |
94 jsonElement.toStyledString().c_str()); | |
95 DEBUGFAIL_SEE_STDERR; | |
96 } else { | |
97 for (Json::ArrayIndex i=0; i<allowedChecksums.size(); i++) { | |
98 Json::Value checksumElement = allowedChecksums[i]; | |
99 if (!checksumElement.isIntegral()) { | |
100 gm_fprintf(stderr, "found non-integer checksum" | |
101 " in json element '%s'\n", | |
102 jsonElement.toStyledString().c_str()); | |
103 DEBUGFAIL_SEE_STDERR; | |
104 } else { | |
105 fAllowedBitmapCityhashes.push_back() = asChecksum(checks umElement); | |
106 } | |
107 } | |
108 } | |
109 } | |
110 } | |
111 | |
112 bool Expectations::match(Checksum actualChecksum) const { | |
113 for (int i=0; i < this->fAllowedBitmapCityhashes.count(); i++) { | |
114 Checksum allowedChecksum = this->fAllowedBitmapCityhashes[i]; | |
115 if (allowedChecksum == actualChecksum) { | |
116 return true; | |
117 } | |
118 } | |
119 return false; | |
120 } | |
121 | |
122 Json::Value Expectations::allowedChecksumsAsJson() const { | |
123 Json::Value allowedChecksumArray; | |
124 if (!this->fAllowedBitmapCityhashes.empty()) { | |
125 for (int i=0; i < this->fAllowedBitmapCityhashes.count(); i++) { | |
126 Checksum allowedChecksum = this->fAllowedBitmapCityhashes[i]; | |
127 allowedChecksumArray.append(Json::UInt64(allowedChecksum)); | |
128 } | |
129 } | |
130 return allowedChecksumArray; | |
131 } | |
132 | |
133 Json::Value Expectations::asJsonValue() const { | |
134 Json::Value jsonValue; | |
135 jsonValue[kJsonKey_ExpectedResults_AllowedBitmapCityhashes] = | |
136 this->allowedChecksumsAsJson(); | |
137 jsonValue[kJsonKey_ExpectedResults_IgnoreFailure] = | |
138 this->ignoreFailure(); | |
139 return jsonValue; | |
140 } | |
141 | |
142 | |
143 // IndividualImageExpectationsSource class... | |
144 | |
145 Expectations IndividualImageExpectationsSource::get(const char *testName) SK _OVERRIDE { | |
146 SkString path = make_filename(fRootDir.c_str(), "", testName, | |
147 "png"); | |
148 SkBitmap referenceBitmap; | |
149 bool decodedReferenceBitmap = | |
150 SkImageDecoder::DecodeFile(path.c_str(), &referenceBitmap, | |
151 SkBitmap::kARGB_8888_Config, | |
152 SkImageDecoder::kDecodePixels_Mode, | |
153 NULL); | |
154 if (decodedReferenceBitmap) { | |
155 return Expectations(referenceBitmap); | |
156 } else { | |
157 return Expectations(); | |
158 } | |
159 } | |
160 | |
161 | |
162 // JsonExpectationsSource class... | |
163 | |
164 JsonExpectationsSource::JsonExpectationsSource(const char *jsonPath) { | |
165 parse(jsonPath, &fJsonRoot); | |
166 fJsonExpectedResults = fJsonRoot[kJsonKey_ExpectedResults]; | |
167 } | |
168 | |
169 Expectations JsonExpectationsSource::get(const char *testName) SK_OVERRIDE { | |
170 return Expectations(fJsonExpectedResults[testName]); | |
171 } | |
172 | |
173 /*static*/ SkData* JsonExpectationsSource::readIntoSkData(SkStream &stream, size_t maxBytes) { | |
174 if (0 == maxBytes) { | |
175 return SkData::NewEmpty(); | |
176 } | |
177 char* bufStart = reinterpret_cast<char *>(sk_malloc_throw(maxBytes)); | |
178 char* bufPtr = bufStart; | |
179 size_t bytesRemaining = maxBytes; | |
180 while (bytesRemaining > 0) { | |
181 size_t bytesReadThisTime = stream.read(bufPtr, bytesRemaining); | |
182 if (0 == bytesReadThisTime) { | |
183 break; | |
184 } | |
185 bytesRemaining -= bytesReadThisTime; | |
186 bufPtr += bytesReadThisTime; | |
187 } | |
188 return SkData::NewFromMalloc(bufStart, maxBytes - bytesRemaining); | |
189 } | |
190 | |
191 /*static*/ bool JsonExpectationsSource::parse(const char *jsonPath, Json::Va lue *jsonRoot) { | |
192 SkFILEStream inFile(jsonPath); | |
193 if (!inFile.isValid()) { | |
194 gm_fprintf(stderr, "unable to read JSON file %s\n", jsonPath); | |
195 DEBUGFAIL_SEE_STDERR; | |
196 return false; | |
197 } | |
198 | |
199 SkAutoDataUnref dataRef(readFileIntoSkData(inFile)); | |
200 if (NULL == dataRef.get()) { | |
201 gm_fprintf(stderr, "error reading JSON file %s\n", jsonPath); | |
202 DEBUGFAIL_SEE_STDERR; | |
203 return false; | |
204 } | |
205 | |
206 const char *bytes = reinterpret_cast<const char *>(dataRef.get()->data() ); | |
207 size_t size = dataRef.get()->size(); | |
208 Json::Reader reader; | |
209 if (!reader.parse(bytes, bytes+size, *jsonRoot)) { | |
210 gm_fprintf(stderr, "error parsing JSON file %s\n", jsonPath); | |
211 DEBUGFAIL_SEE_STDERR; | |
212 return false; | |
213 } | |
214 return true; | |
215 } | |
216 | |
217 } | |
OLD | NEW |