blob: a72d7a2c4673433dcb8cb8553ab9161e350761b0 [file] [log] [blame]
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +00001/*
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"
commit-bot@chromium.orgabeb9582014-05-19 15:25:10 +000013#include "SkOSFile.h"
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +000014
15namespace sk_tools {
16
17 /**
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000018 * 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.
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +000021 */
epoger85b438d2014-08-21 23:21:32 -070022 class ImageDigest {
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +000023 public:
24 /**
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000025 * Create an ImageDigest of a bitmap.
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +000026 *
epoger85b438d2014-08-21 23:21:32 -070027 * Computes the hash of the bitmap lazily, since that is an expensive operation.
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000028 *
29 * @param bitmap image to get the digest of
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +000030 */
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000031 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, only
37 * kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 is allowed.
38 * @param hashValue the value generated by the hash algorithm for a particular image.
39 */
40 explicit ImageDigest(const SkString &hashType, uint64_t hashValue);
41
42 /**
epoger85b438d2014-08-21 23:21:32 -070043 * Returns true iff this and other ImageDigest represent identical images.
44 */
45 bool equals(ImageDigest &other);
46
47 /**
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000048 * Returns the hash digest type as an SkString.
49 *
50 * For now, this always returns kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 .
51 */
epoger85b438d2014-08-21 23:21:32 -070052 SkString getHashType();
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000053
54 /**
55 * Returns the hash digest value as a uint64_t.
epoger85b438d2014-08-21 23:21:32 -070056 *
57 * Since the hash is computed lazily, this may take some time, and it may modify
58 * some fields on this object.
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000059 */
epoger85b438d2014-08-21 23:21:32 -070060 uint64_t getHashValue();
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000061
62 private:
epoger85b438d2014-08-21 23:21:32 -070063 const SkBitmap fBitmap;
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000064 uint64_t fHashValue;
epoger85b438d2014-08-21 23:21:32 -070065 bool fComputedHashValue;
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000066 };
67
68 /**
epoger85b438d2014-08-21 23:21:32 -070069 * Container that holds a reference to an SkBitmap and its ImageDigest.
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000070 */
71 class BitmapAndDigest {
72 public:
73 explicit BitmapAndDigest(const SkBitmap &bitmap);
74
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000075 const SkBitmap *getBitmapPtr() const;
epoger85b438d2014-08-21 23:21:32 -070076
77 /**
78 * Returns a pointer to the ImageDigest.
79 *
80 * Since the hash is computed lazily within the ImageDigest object, we cannot mandate
81 * that it be held const.
82 */
83 ImageDigest *getImageDigestPtr();
commit-bot@chromium.org205ce482014-05-12 15:37:20 +000084 private:
85 const SkBitmap fBitmap;
epoger85b438d2014-08-21 23:21:32 -070086 ImageDigest fImageDigest;
87 };
88
89 /**
90 * Expected test result: expected image (if any), and whether we want to ignore 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 match it,
131 * this method will return false regardless of what ignoreFailure() would 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 hash lazily
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000142 };
143
144 /**
145 * Collects ImageDigests of actually rendered images, perhaps comparing to expectations.
146 */
147 class ImageResultsAndExpectations {
148 public:
149 /**
150 * Adds expectations from a JSON file, returning true if successful.
commit-bot@chromium.orgabeb9582014-05-19 15:25:10 +0000151 *
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.
154 *
155 * Reasoning:
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
159 * expectations!"
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.
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000165 */
166 bool readExpectationsFile(const char *jsonPath);
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +0000167
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
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000173 * @param digest description of the image's contents
halcanary96fcdcc2015-08-27 07:41:13 -0700174 * @param tileNumber if not nullptr, pointer to tile number
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +0000175 */
epoger85b438d2014-08-21 23:21:32 -0700176 void add(const char *sourceName, const char *fileName, ImageDigest &digest,
halcanary96fcdcc2015-08-27 07:41:13 -0700177 const int *tileNumber=nullptr);
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +0000178
179 /**
epogerb492c6f2014-08-14 07:32:49 -0700180 * 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 /**
rmistry2529f2e2014-08-22 04:46:30 -0700188 * 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 /**
epoger85b438d2014-08-21 23:21:32 -0700195 * Returns the Expectation for this test.
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000196 *
197 * @param sourceName name of the source file that generated this result
halcanary96fcdcc2015-08-27 07:41:13 -0700198 * @param tileNumber if not nullptr, pointer to tile number
epoger85b438d2014-08-21 23:21:32 -0700199 *
200 * TODO(stephana): To make this work for GMs, we will need to add parameters for
201 * config, and maybe renderMode/builder?
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000202 */
halcanary96fcdcc2015-08-27 07:41:13 -0700203 Expectation getExpectation(const char *sourceName, const int *tileNumber=nullptr);
commit-bot@chromium.org3f045172014-05-15 15:10:48 +0000204
205 /**
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +0000206 * Writes the summary (as constructed so far) to a file.
207 *
208 * @param filename path to write the summary to
209 */
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000210 void writeToFile(const char *filename) const;
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +0000211
212 private:
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000213
214 /**
commit-bot@chromium.orgabeb9582014-05-19 15:25:10 +0000215 * 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.
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000218 *
219 * Returns true if successful.
220 */
commit-bot@chromium.orgabeb9582014-05-19 15:25:10 +0000221 static bool Parse(SkFILE* filePtr, Json::Value *jsonRoot);
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000222
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +0000223 Json::Value fActualResults;
epogerb492c6f2014-08-14 07:32:49 -0700224 Json::Value fDescriptions;
commit-bot@chromium.org205ce482014-05-12 15:37:20 +0000225 Json::Value fExpectedJsonRoot;
226 Json::Value fExpectedResults;
rmistry2529f2e2014-08-22 04:46:30 -0700227 Json::Value fImageBaseGSUrl;
commit-bot@chromium.org90c0fbd2014-05-09 03:18:41 +0000228 };
229
230} // namespace sk_tools
231
232#endif // image_expectations_DEFINED