2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef image_expectations_DEFINED
9 #define image_expectations_DEFINED
12 #include "SkJSONCPP.h"
18 * The digest of an image (either an image we have generated locally, or an image expectation).
20 * Currently, this is always a uint64_t hash digest of an SkBitmap.
25 * Create an ImageDigest of a bitmap.
27 * Computes the hash of the bitmap lazily, since that is an expensive operation.
29 * @param bitmap image to get the digest of
31 explicit ImageDigest(const SkBitmap &bitmap);
34 * Create an ImageDigest using a hashType/hashValue pair.
36 * @param hashType the algorithm used to generate the hash; for now, only
37 * kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 is allowed.
38 * @param hashValue the value generated by the hash algorithm for a particular image.
40 explicit ImageDigest(const SkString &hashType, uint64_t hashValue);
43 * Returns true iff this and other ImageDigest represent identical images.
45 bool equals(ImageDigest &other);
48 * Returns the hash digest type as an SkString.
50 * For now, this always returns kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 .
52 SkString getHashType();
55 * Returns the hash digest value as a uint64_t.
57 * Since the hash is computed lazily, this may take some time, and it may modify
58 * some fields on this object.
60 uint64_t getHashValue();
63 const SkBitmap fBitmap;
65 bool fComputedHashValue;
69 * Container that holds a reference to an SkBitmap and its ImageDigest.
71 class BitmapAndDigest {
73 explicit BitmapAndDigest(const SkBitmap &bitmap);
75 const SkBitmap *getBitmapPtr() const;
78 * Returns a pointer to the ImageDigest.
80 * Since the hash is computed lazily within the ImageDigest object, we cannot mandate
81 * that it be held const.
83 ImageDigest *getImageDigestPtr();
85 const SkBitmap fBitmap;
86 ImageDigest fImageDigest;
90 * Expected test result: expected image (if any), and whether we want to ignore failures on
93 * This is just an ImageDigest (or lack thereof, if there is no expectation) and a boolean
94 * telling us whether to ignore failures.
99 * No expectation at all.
101 explicit Expectation(bool ignoreFailure=kDefaultIgnoreFailure);
104 * Expect an image, passed as hashType/hashValue.
106 explicit Expectation(const SkString &hashType, uint64_t hashValue,
107 bool ignoreFailure=kDefaultIgnoreFailure);
110 * Expect an image, passed as a bitmap.
112 explicit Expectation(const SkBitmap& bitmap,
113 bool ignoreFailure=kDefaultIgnoreFailure);
116 * Returns true iff we want to ignore failed expectations.
118 bool ignoreFailure() const;
121 * Returns true iff there are no allowed results.
126 * Returns true iff we are expecting a particular image, and imageDigest matches it.
128 * If empty() returns true, this will return false.
130 * If this expectation DOES contain an image, and imageDigest doesn't match it,
131 * this method will return false regardless of what ignoreFailure() would return.
132 * (The caller can check that separately.)
134 bool matches(ImageDigest &imageDigest);
137 static const bool kDefaultIgnoreFailure = false;
140 const bool fIgnoreFailure;
141 ImageDigest fImageDigest; // cannot be const, because it computes its hash lazily
145 * Collects ImageDigests of actually rendered images, perhaps comparing to expectations.
147 class ImageResultsAndExpectations {
150 * Adds expectations from a JSON file, returning true if successful.
152 * If the file exists but is empty, it succeeds, and there will be no expectations.
153 * If the file does not exist, this will fail.
156 * Generating expectations the first time can be a tricky chicken-and-egg
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
160 * We could make the tool run even if there is no expectations file at all, but it's
161 * better for the tool to fail if the expectations file is not found--that 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 cycle and generate
164 * the first real expectations.
166 bool readExpectationsFile(const char *jsonPath);
169 * Adds this image to the summary of results.
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 NULL, pointer to tile number
176 void add(const char *sourceName, const char *fileName, ImageDigest &digest,
177 const int *tileNumber=NULL);
180 * Adds a key/value pair to the descriptions dict within the summary of results.
182 * @param key key within the descriptions dict
183 * @param value value to associate with that key
185 void addDescription(const char *key, const char *value);
188 * Adds the image base Google Storage URL to the summary of results.
190 * @param imageBaseGSUrl the image base Google Storage URL
192 void setImageBaseGSUrl(const char *imageBaseGSUrl);
195 * Returns the Expectation for this test.
197 * @param sourceName name of the source file that generated this result
198 * @param tileNumber if not NULL, pointer to tile number
200 * TODO(stephana): To make this work for GMs, we will need to add parameters for
201 * config, and maybe renderMode/builder?
203 Expectation getExpectation(const char *sourceName, const int *tileNumber=NULL);
206 * Writes the summary (as constructed so far) to a file.
208 * @param filename path to write the summary to
210 void writeToFile(const char *filename) const;
215 * Read the file contents from filePtr and parse them into jsonRoot.
217 * It is up to the caller to close filePtr after this is done.
219 * Returns true if successful.
221 static bool Parse(SkFILE* filePtr, Json::Value *jsonRoot);
223 Json::Value fActualResults;
224 Json::Value fDescriptions;
225 Json::Value fExpectedJsonRoot;
226 Json::Value fExpectedResults;
227 Json::Value fImageBaseGSUrl;
230 } // namespace sk_tools
232 #endif // image_expectations_DEFINED