OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2014 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 #ifndef image_expectations_DEFINED | |
9 #define image_expectations_DEFINED | |
10 | |
11 #include "SkBitmap.h" | |
12 #include "SkJSONCPP.h" | |
13 #include "SkOSFile.h" | |
14 | |
15 namespace sk_tools { | |
16 | |
17 /** | |
18 * The digest of an image (either an image we have generated locally, or an
image expectation). | |
19 * | |
20 * Currently, this is always a uint64_t hash digest of an SkBitmap. | |
21 */ | |
22 class ImageDigest { | |
23 public: | |
24 /** | |
25 * Create an ImageDigest of a bitmap. | |
26 * | |
27 * Computes the hash of the bitmap lazily, since that is an expensive op
eration. | |
28 * | |
29 * @param bitmap image to get the digest of | |
30 */ | |
31 explicit ImageDigest(const SkBitmap &bitmap); | |
32 | |
33 /** | |
34 * Create an ImageDigest using a hashType/hashValue pair. | |
35 * | |
36 * @param hashType the algorithm used to generate the hash; for now, onl
y | |
37 * kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 is allowed. | |
38 * @param hashValue the value generated by the hash algorithm for a part
icular image. | |
39 */ | |
40 explicit ImageDigest(const SkString &hashType, uint64_t hashValue); | |
41 | |
42 /** | |
43 * Returns true iff this and other ImageDigest represent identical image
s. | |
44 */ | |
45 bool equals(ImageDigest &other); | |
46 | |
47 /** | |
48 * Returns the hash digest type as an SkString. | |
49 * | |
50 * For now, this always returns kJsonValue_Image_ChecksumAlgorithm_Bitma
p64bitMD5 . | |
51 */ | |
52 SkString getHashType(); | |
53 | |
54 /** | |
55 * Returns the hash digest value as a uint64_t. | |
56 * | |
57 * Since the hash is computed lazily, this may take some time, and it ma
y modify | |
58 * some fields on this object. | |
59 */ | |
60 uint64_t getHashValue(); | |
61 | |
62 private: | |
63 const SkBitmap fBitmap; | |
64 uint64_t fHashValue; | |
65 bool fComputedHashValue; | |
66 }; | |
67 | |
68 /** | |
69 * Container that holds a reference to an SkBitmap and its ImageDigest. | |
70 */ | |
71 class BitmapAndDigest { | |
72 public: | |
73 explicit BitmapAndDigest(const SkBitmap &bitmap); | |
74 | |
75 const SkBitmap *getBitmapPtr() const; | |
76 | |
77 /** | |
78 * Returns a pointer to the ImageDigest. | |
79 * | |
80 * Since the hash is computed lazily within the ImageDigest object, we c
annot mandate | |
81 * that it be held const. | |
82 */ | |
83 ImageDigest *getImageDigestPtr(); | |
84 private: | |
85 const SkBitmap fBitmap; | |
86 ImageDigest fImageDigest; | |
87 }; | |
88 | |
89 /** | |
90 * Expected test result: expected image (if any), and whether we want to ign
ore failures on | |
91 * this test or not. | |
92 * | |
93 * This is just an ImageDigest (or lack thereof, if there is no expectation)
and a boolean | |
94 * telling us whether to ignore failures. | |
95 */ | |
96 class Expectation { | |
97 public: | |
98 /** | |
99 * No expectation at all. | |
100 */ | |
101 explicit Expectation(bool ignoreFailure=kDefaultIgnoreFailure); | |
102 | |
103 /** | |
104 * Expect an image, passed as hashType/hashValue. | |
105 */ | |
106 explicit Expectation(const SkString &hashType, uint64_t hashValue, | |
107 bool ignoreFailure=kDefaultIgnoreFailure); | |
108 | |
109 /** | |
110 * Expect an image, passed as a bitmap. | |
111 */ | |
112 explicit Expectation(const SkBitmap& bitmap, | |
113 bool ignoreFailure=kDefaultIgnoreFailure); | |
114 | |
115 /** | |
116 * Returns true iff we want to ignore failed expectations. | |
117 */ | |
118 bool ignoreFailure() const; | |
119 | |
120 /** | |
121 * Returns true iff there are no allowed results. | |
122 */ | |
123 bool empty() const; | |
124 | |
125 /** | |
126 * Returns true iff we are expecting a particular image, and imageDigest
matches it. | |
127 * | |
128 * If empty() returns true, this will return false. | |
129 * | |
130 * If this expectation DOES contain an image, and imageDigest doesn't ma
tch it, | |
131 * this method will return false regardless of what ignoreFailure() woul
d return. | |
132 * (The caller can check that separately.) | |
133 */ | |
134 bool matches(ImageDigest &imageDigest); | |
135 | |
136 private: | |
137 static const bool kDefaultIgnoreFailure = false; | |
138 | |
139 const bool fIsEmpty; | |
140 const bool fIgnoreFailure; | |
141 ImageDigest fImageDigest; // cannot be const, because it computes its h
ash lazily | |
142 }; | |
143 | |
144 /** | |
145 * Collects ImageDigests of actually rendered images, perhaps comparing to e
xpectations. | |
146 */ | |
147 class ImageResultsAndExpectations { | |
148 public: | |
149 /** | |
150 * Adds expectations from a JSON file, returning true if successful. | |
151 * | |
152 * If the file exists but is empty, it succeeds, and there will be no ex
pectations. | |
153 * If the file does not exist, this will fail. | |
154 * | |
155 * Reasoning: | |
156 * Generating expectations the first time can be a tricky chicken-and-eg
g | |
157 * proposition. "I need actual results to turn into expectations... but
the only | |
158 * way to get actual results is to run the tool, and the tool won't run
without | |
159 * expectations!" | |
160 * We could make the tool run even if there is no expectations file at a
ll, but it's | |
161 * better for the tool to fail if the expectations file is not found--th
at will tell us | |
162 * quickly if files are not being copied around as they should be. | |
163 * Creating an empty file is an easy way to break the chicken-and-egg cy
cle and generate | |
164 * the first real expectations. | |
165 */ | |
166 bool readExpectationsFile(const char *jsonPath); | |
167 | |
168 /** | |
169 * Adds this image to the summary of results. | |
170 * | |
171 * @param sourceName name of the source file that generated this result | |
172 * @param fileName relative path to the image output file on local disk | |
173 * @param digest description of the image's contents | |
174 * @param tileNumber if not nullptr, pointer to tile number | |
175 */ | |
176 void add(const char *sourceName, const char *fileName, ImageDigest &dige
st, | |
177 const int *tileNumber=nullptr); | |
178 | |
179 /** | |
180 * Adds a key/value pair to the descriptions dict within the summary of
results. | |
181 * | |
182 * @param key key within the descriptions dict | |
183 * @param value value to associate with that key | |
184 */ | |
185 void addDescription(const char *key, const char *value); | |
186 | |
187 /** | |
188 * Adds the image base Google Storage URL to the summary of results. | |
189 * | |
190 * @param imageBaseGSUrl the image base Google Storage URL | |
191 */ | |
192 void setImageBaseGSUrl(const char *imageBaseGSUrl); | |
193 | |
194 /** | |
195 * Returns the Expectation for this test. | |
196 * | |
197 * @param sourceName name of the source file that generated this result | |
198 * @param tileNumber if not nullptr, pointer to tile number | |
199 * | |
200 * TODO(stephana): To make this work for GMs, we will need to add parame
ters for | |
201 * config, and maybe renderMode/builder? | |
202 */ | |
203 Expectation getExpectation(const char *sourceName, const int *tileNumber
=nullptr); | |
204 | |
205 /** | |
206 * Writes the summary (as constructed so far) to a file. | |
207 * | |
208 * @param filename path to write the summary to | |
209 */ | |
210 void writeToFile(const char *filename) const; | |
211 | |
212 private: | |
213 | |
214 /** | |
215 * Read the file contents from filePtr and parse them into jsonRoot. | |
216 * | |
217 * It is up to the caller to close filePtr after this is done. | |
218 * | |
219 * Returns true if successful. | |
220 */ | |
221 static bool Parse(SkFILE* filePtr, Json::Value *jsonRoot); | |
222 | |
223 Json::Value fActualResults; | |
224 Json::Value fDescriptions; | |
225 Json::Value fExpectedJsonRoot; | |
226 Json::Value fExpectedResults; | |
227 Json::Value fImageBaseGSUrl; | |
228 }; | |
229 | |
230 } // namespace sk_tools | |
231 | |
232 #endif // image_expectations_DEFINED | |
OLD | NEW |