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

Side by Side Diff: tools/image_expectations.cpp

Issue 493363002: create sk_tools::Expectation class, similar to skiagm::Expectations class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: properly handle ignoreFailure using sk_tools::Expectation class, with unittest to exercise Created 6 years, 4 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/image_expectations.h ('k') | tools/render_pictures_main.cpp » ('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 2014 Google Inc. 2 * Copyright 2014 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 "SkBitmapHasher.h" 9 #include "SkBitmapHasher.h"
10 #include "SkData.h" 10 #include "SkData.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 const static char kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5[] = "bitmap- 64bitMD5"; 46 const static char kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5[] = "bitmap- 64bitMD5";
47 const static char kJsonValue_Image_ComparisonResult_Failed[] = "failed"; 47 const static char kJsonValue_Image_ComparisonResult_Failed[] = "failed";
48 const static char kJsonValue_Image_ComparisonResult_FailureIgnored[] = "failure- ignored"; 48 const static char kJsonValue_Image_ComparisonResult_FailureIgnored[] = "failure- ignored";
49 const static char kJsonValue_Image_ComparisonResult_NoComparison[] = "no-compari son"; 49 const static char kJsonValue_Image_ComparisonResult_NoComparison[] = "no-compari son";
50 const static char kJsonValue_Image_ComparisonResult_Succeeded[] = "succeeded"; 50 const static char kJsonValue_Image_ComparisonResult_Succeeded[] = "succeeded";
51 51
52 namespace sk_tools { 52 namespace sk_tools {
53 53
54 // ImageDigest class... 54 // ImageDigest class...
55 55
56 ImageDigest::ImageDigest(const SkBitmap &bitmap) { 56 ImageDigest::ImageDigest(const SkBitmap &bitmap) :
57 if (!SkBitmapHasher::ComputeDigest(bitmap, &fHashValue)) { 57 fBitmap(bitmap), fHashValue(0), fComputedHashValue(false) {}
58 SkFAIL("unable to compute image digest"); 58
59 ImageDigest::ImageDigest(const SkString &hashType, uint64_t hashValue) :
60 fBitmap(), fHashValue(hashValue), fComputedHashValue(true) {
61 if (!hashType.equals(kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5)) {
62 SkDebugf("unsupported hashType '%s'\n", hashType.c_str());
63 SkFAIL("unsupported hashType (see above)");
59 } 64 }
60 } 65 }
61 66
62 ImageDigest::ImageDigest(const SkString &hashType, uint64_t hashValue) { 67 bool ImageDigest::equals(ImageDigest &other) {
63 if (!hashType.equals(kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5)) { 68 // TODO(epoger): The current implementation assumes that this
64 SkFAIL((SkString("unsupported hashType ")+=hashType).c_str()); 69 // and other always have hashType kJsonKey_Hashtype_Bitmap_64bitMD5
65 } else { 70 return (this->getHashValue() == other.getHashValue());
66 fHashValue = hashValue;
67 }
68 } 71 }
69 72
70 SkString ImageDigest::getHashType() const { 73 SkString ImageDigest::getHashType() {
71 // TODO(epoger): The current implementation assumes that the 74 // TODO(epoger): The current implementation assumes that the
72 // result digest is always of type kJsonValue_Image_ChecksumAlgorithm_Bi tmap64bitMD5 . 75 // result digest is always of type kJsonValue_Image_ChecksumAlgorithm_Bi tmap64bitMD5 .
73 return SkString(kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5); 76 return SkString(kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5);
74 } 77 }
75 78
76 uint64_t ImageDigest::getHashValue() const { 79 uint64_t ImageDigest::getHashValue() {
77 return fHashValue; 80 if (!this->fComputedHashValue) {
81 if (!SkBitmapHasher::ComputeDigest(this->fBitmap, &this->fHashValue) ) {
82 SkFAIL("unable to compute image digest");
83 }
84 this->fComputedHashValue = true;
85 }
86 return this->fHashValue;
78 } 87 }
79 88
80 // BitmapAndDigest class... 89 // BitmapAndDigest class...
81 90
82 BitmapAndDigest::BitmapAndDigest(const SkBitmap &bitmap) : fBitmap(bitmap) { 91 BitmapAndDigest::BitmapAndDigest(const SkBitmap &bitmap) :
83 } 92 fBitmap(bitmap), fImageDigest(bitmap) {}
84 93
85 const ImageDigest *BitmapAndDigest::getImageDigestPtr() { 94 const SkBitmap *BitmapAndDigest::getBitmapPtr() const {return &fBitmap;}
86 if (NULL == fImageDigestRef.get()) {
87 fImageDigestRef.reset(SkNEW_ARGS(ImageDigest, (fBitmap)));
88 }
89 return fImageDigestRef.get();
90 }
91 95
92 const SkBitmap *BitmapAndDigest::getBitmapPtr() const { 96 ImageDigest *BitmapAndDigest::getImageDigestPtr() {return &fImageDigest;}
93 return &fBitmap; 97
98 // Expectation class...
99
100 // For when we need a valid ImageDigest, but we don't care what it is.
101 static const ImageDigest kDummyImageDigest(
102 SkString(kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5), 0);
103
104 Expectation::Expectation(bool ignoreFailure) :
105 fIsEmpty(true), fIgnoreFailure(ignoreFailure), fImageDigest(kDummyImageD igest) {}
106
107 Expectation::Expectation(const SkString &hashType, uint64_t hashValue, bool ignoreFailure) :
108 fIsEmpty(false), fIgnoreFailure(ignoreFailure), fImageDigest(hashType, h ashValue) {}
109
110 Expectation::Expectation(const SkBitmap& bitmap, bool ignoreFailure) :
111 fIsEmpty(false), fIgnoreFailure(ignoreFailure), fImageDigest(bitmap) {}
112
113 bool Expectation::ignoreFailure() const { return this->fIgnoreFailure; }
114
115 bool Expectation::empty() const { return this->fIsEmpty; }
116
117 bool Expectation::matches(ImageDigest &imageDigest) {
118 return !(this->fIsEmpty) && (this->fImageDigest.equals(imageDigest));
94 } 119 }
95 120
96 // ImageResultsAndExpectations class... 121 // ImageResultsAndExpectations class...
97 122
98 bool ImageResultsAndExpectations::readExpectationsFile(const char *jsonPath) { 123 bool ImageResultsAndExpectations::readExpectationsFile(const char *jsonPath) {
99 if (NULL == jsonPath) { 124 if (NULL == jsonPath) {
100 SkDebugf("JSON expectations filename not specified\n"); 125 SkDebugf("JSON expectations filename not specified\n");
101 return false; 126 return false;
102 } 127 }
103 SkFILE* filePtr = sk_fopen(jsonPath, kRead_SkFILE_Flag); 128 SkFILE* filePtr = sk_fopen(jsonPath, kRead_SkFILE_Flag);
(...skipping 25 matching lines...) Expand all
129 if (headerRevision.asInt() != kJsonValue_Header_Revision) { 154 if (headerRevision.asInt() != kJsonValue_Header_Revision) {
130 SkDebugf("JSON expectations file '%s': expected headerRevision %d, f ound %d\n", 155 SkDebugf("JSON expectations file '%s': expected headerRevision %d, f ound %d\n",
131 jsonPath, kJsonValue_Header_Revision, headerRevision.asInt( )); 156 jsonPath, kJsonValue_Header_Revision, headerRevision.asInt( ));
132 return false; 157 return false;
133 } 158 }
134 fExpectedResults = fExpectedJsonRoot[kJsonKey_ExpectedResults]; 159 fExpectedResults = fExpectedJsonRoot[kJsonKey_ExpectedResults];
135 return true; 160 return true;
136 } 161 }
137 162
138 void ImageResultsAndExpectations::add(const char *sourceName, const char *fi leName, 163 void ImageResultsAndExpectations::add(const char *sourceName, const char *fi leName,
139 const ImageDigest &digest, const int * tileNumber) { 164 ImageDigest &digest, const int *tileNu mber) {
140 // Get expectation, if any. 165 // Get expectation, if any.
141 Json::Value expectedImage; 166 Expectation expectation = this->getExpectation(sourceName, tileNumber);
142 if (!fExpectedResults.isNull()) {
143 if (NULL == tileNumber) {
144 expectedImage = fExpectedResults[sourceName][kJsonKey_Source_Who leImage];
145 } else {
146 expectedImage = fExpectedResults[sourceName][kJsonKey_Source_Til edImages]
147 [*tileNumber];
148 }
149 }
150 167
151 // Fill in info about the actual result itself. 168 // Fill in info about the actual result.
152 Json::Value actualChecksumAlgorithm = digest.getHashType().c_str(); 169 Json::Value actualChecksumAlgorithm = digest.getHashType().c_str();
153 Json::Value actualChecksumValue = Json::UInt64(digest.getHashValue()); 170 Json::Value actualChecksumValue = Json::UInt64(digest.getHashValue());
154 Json::Value actualImage; 171 Json::Value actualImage;
155 actualImage[kJsonKey_Image_ChecksumAlgorithm] = actualChecksumAlgorithm; 172 actualImage[kJsonKey_Image_ChecksumAlgorithm] = actualChecksumAlgorithm;
156 actualImage[kJsonKey_Image_ChecksumValue] = actualChecksumValue; 173 actualImage[kJsonKey_Image_ChecksumValue] = actualChecksumValue;
157 actualImage[kJsonKey_Image_Filepath] = fileName; 174 actualImage[kJsonKey_Image_Filepath] = fileName;
158 175
159 // Compare against expectedImage to fill in comparisonResult. 176 // Compare against expectedImage to fill in comparisonResult.
160 Json::Value comparisonResult = kJsonValue_Image_ComparisonResult_NoCompa rison; 177 Json::Value comparisonResult;
161 if (!expectedImage.isNull()) { 178 if (expectation.empty()) {
162 if ((actualChecksumAlgorithm == expectedImage[kJsonKey_Image_Checksu mAlgorithm]) && 179 comparisonResult = kJsonValue_Image_ComparisonResult_NoComparison;
163 (actualChecksumValue == expectedImage[kJsonKey_Image_ChecksumVal ue])) { 180 } else if (expectation.matches(digest)) {
164 comparisonResult = kJsonValue_Image_ComparisonResult_Succeeded; 181 comparisonResult = kJsonValue_Image_ComparisonResult_Succeeded;
165 } else if (expectedImage[kJsonKey_Image_IgnoreFailure] == true) { 182 } else if (expectation.ignoreFailure()) {
166 comparisonResult = kJsonValue_Image_ComparisonResult_FailureIgno red; 183 comparisonResult = kJsonValue_Image_ComparisonResult_FailureIgnored;
167 } else { 184 } else {
168 comparisonResult = kJsonValue_Image_ComparisonResult_Failed; 185 comparisonResult = kJsonValue_Image_ComparisonResult_Failed;
169 }
170 } 186 }
171 actualImage[kJsonKey_Image_ComparisonResult] = comparisonResult; 187 actualImage[kJsonKey_Image_ComparisonResult] = comparisonResult;
172 188
173 // Add this actual result to our collection. 189 // Add this actual result to our collection.
174 if (NULL == tileNumber) { 190 if (NULL == tileNumber) {
175 fActualResults[sourceName][kJsonKey_Source_WholeImage] = actualImage ; 191 fActualResults[sourceName][kJsonKey_Source_WholeImage] = actualImage ;
176 } else { 192 } else {
177 fActualResults[sourceName][kJsonKey_Source_TiledImages][*tileNumber] = actualImage; 193 fActualResults[sourceName][kJsonKey_Source_TiledImages][*tileNumber] = actualImage;
178 } 194 }
179 } 195 }
180 196
181 void ImageResultsAndExpectations::addDescription(const char *key, const char *value) { 197 void ImageResultsAndExpectations::addDescription(const char *key, const char *value) {
182 fDescriptions[key] = value; 198 fDescriptions[key] = value;
183 } 199 }
184 200
185 bool ImageResultsAndExpectations::matchesExpectation(const char *sourceName, 201 Expectation ImageResultsAndExpectations::getExpectation(const char *sourceNa me,
186 const ImageDigest &dige st, 202 const int *tileNumbe r) {
187 const int *tileNumber) {
188 if (fExpectedResults.isNull()) { 203 if (fExpectedResults.isNull()) {
189 return false; 204 return Expectation();
190 } 205 }
191 206
192 Json::Value expectedImage; 207 Json::Value expectedImage;
193 if (NULL == tileNumber) { 208 if (NULL == tileNumber) {
194 expectedImage = fExpectedResults[sourceName][kJsonKey_Source_WholeIm age]; 209 expectedImage = fExpectedResults[sourceName][kJsonKey_Source_WholeIm age];
195 } else { 210 } else {
196 expectedImage = fExpectedResults[sourceName][kJsonKey_Source_TiledIm ages][*tileNumber]; 211 expectedImage = fExpectedResults[sourceName][kJsonKey_Source_TiledIm ages][*tileNumber];
197 } 212 }
198 if (expectedImage.isNull()) { 213 if (expectedImage.isNull()) {
199 return false; 214 return Expectation();
200 } 215 }
201 216
202 Json::Value actualChecksumAlgorithm = digest.getHashType().c_str(); 217 bool ignoreFailure = (expectedImage[kJsonKey_Image_IgnoreFailure] == tru e);
203 Json::Value actualChecksumValue = Json::UInt64(digest.getHashValue()); 218 return Expectation(SkString(expectedImage[kJsonKey_Image_ChecksumAlgorit hm].asCString()),
204 return ((actualChecksumAlgorithm == expectedImage[kJsonKey_Image_Checksu mAlgorithm]) && 219 expectedImage[kJsonKey_Image_ChecksumValue].asUInt64( ),
205 (actualChecksumValue == expectedImage[kJsonKey_Image_ChecksumVal ue])); 220 ignoreFailure);
206 } 221 }
207 222
208 void ImageResultsAndExpectations::writeToFile(const char *filename) const { 223 void ImageResultsAndExpectations::writeToFile(const char *filename) const {
209 Json::Value header; 224 Json::Value header;
210 header[kJsonKey_Header_Type] = kJsonValue_Header_Type; 225 header[kJsonKey_Header_Type] = kJsonValue_Header_Type;
211 header[kJsonKey_Header_Revision] = kJsonValue_Header_Revision; 226 header[kJsonKey_Header_Revision] = kJsonValue_Header_Revision;
212 Json::Value root; 227 Json::Value root;
213 root[kJsonKey_ActualResults] = fActualResults; 228 root[kJsonKey_ActualResults] = fActualResults;
214 root[kJsonKey_Descriptions] = fDescriptions; 229 root[kJsonKey_Descriptions] = fDescriptions;
215 root[kJsonKey_Header] = header; 230 root[kJsonKey_Header] = header;
(...skipping 13 matching lines...) Expand all
229 size_t size = dataRef.get()->size(); 244 size_t size = dataRef.get()->size();
230 Json::Reader reader; 245 Json::Reader reader;
231 if (!reader.parse(bytes, bytes+size, *jsonRoot)) { 246 if (!reader.parse(bytes, bytes+size, *jsonRoot)) {
232 return false; 247 return false;
233 } 248 }
234 249
235 return true; 250 return true;
236 } 251 }
237 252
238 } // namespace sk_tools 253 } // namespace sk_tools
OLDNEW
« no previous file with comments | « tools/image_expectations.h ('k') | tools/render_pictures_main.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698