• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "SkRefCnt.h"
15 
16 namespace sk_tools {
17 
18     /**
19      * The digest of an image (either an image we have generated locally, or an image expectation).
20      *
21      * Currently, this is always a uint64_t hash digest of an SkBitmap.
22      */
23     class ImageDigest : public SkRefCnt {
24     public:
25         /**
26          * Create an ImageDigest of a bitmap.
27          *
28          * Note that this is an expensive operation, because it has to examine all pixels in
29          * the bitmap.  You may wish to consider using the BitmapAndDigest class, which will
30          * compute the ImageDigest lazily.
31          *
32          * @param bitmap image to get the digest of
33          */
34         explicit ImageDigest(const SkBitmap &bitmap);
35 
36         /**
37          * Create an ImageDigest using a hashType/hashValue pair.
38          *
39          * @param hashType the algorithm used to generate the hash; for now, only
40          *     kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 is allowed.
41          * @param hashValue the value generated by the hash algorithm for a particular image.
42          */
43         explicit ImageDigest(const SkString &hashType, uint64_t hashValue);
44 
45         /**
46          * Returns the hash digest type as an SkString.
47          *
48          * For now, this always returns kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 .
49          */
50         SkString getHashType() const;
51 
52         /**
53          * Returns the hash digest value as a uint64_t.
54          */
55         uint64_t getHashValue() const;
56 
57     private:
58         uint64_t fHashValue;
59     };
60 
61     /**
62      * Container that holds a reference to an SkBitmap and computes its ImageDigest lazily.
63      *
64      * Computing the ImageDigest can be expensive, so this can help you postpone (or maybe even
65      * avoid) that work.
66      */
67     class BitmapAndDigest {
68     public:
69         explicit BitmapAndDigest(const SkBitmap &bitmap);
70 
71         const ImageDigest *getImageDigestPtr();
72         const SkBitmap *getBitmapPtr() const;
73     private:
74         const SkBitmap fBitmap;
75         SkAutoTUnref<ImageDigest> fImageDigestRef;
76     };
77 
78     /**
79      * Collects ImageDigests of actually rendered images, perhaps comparing to expectations.
80      */
81     class ImageResultsAndExpectations {
82     public:
83         /**
84          * Adds expectations from a JSON file, returning true if successful.
85          *
86          * If the file exists but is empty, it succeeds, and there will be no expectations.
87          * If the file does not exist, this will fail.
88          *
89          * Reasoning:
90          * Generating expectations the first time can be a tricky chicken-and-egg
91          * proposition.  "I need actual results to turn into expectations... but the only
92          * way to get actual results is to run the tool, and the tool won't run without
93          * expectations!"
94          * We could make the tool run even if there is no expectations file at all, but it's
95          * better for the tool to fail if the expectations file is not found--that will tell us
96          * quickly if files are not being copied around as they should be.
97          * Creating an empty file is an easy way to break the chicken-and-egg cycle and generate
98          * the first real expectations.
99          */
100         bool readExpectationsFile(const char *jsonPath);
101 
102         /**
103          * Adds this image to the summary of results.
104          *
105          * @param sourceName name of the source file that generated this result
106          * @param fileName relative path to the image output file on local disk
107          * @param digest description of the image's contents
108          * @param tileNumber if not NULL, pointer to tile number
109          */
110         void add(const char *sourceName, const char *fileName, const ImageDigest &digest,
111                  const int *tileNumber=NULL);
112 
113         /**
114          * Returns true if this test result matches its expectations.
115          * If there are no expectations for this test result, this will return false.
116          *
117          * @param sourceName name of the source file that generated this result
118          * @param digest description of the image's contents
119          * @param tileNumber if not NULL, pointer to tile number
120          */
121         bool matchesExpectation(const char *sourceName, const ImageDigest &digest,
122                                 const int *tileNumber=NULL);
123 
124         /**
125          * Writes the summary (as constructed so far) to a file.
126          *
127          * @param filename path to write the summary to
128          */
129         void writeToFile(const char *filename) const;
130 
131     private:
132 
133         /**
134          * Read the file contents from filePtr and parse them into jsonRoot.
135          *
136          * It is up to the caller to close filePtr after this is done.
137          *
138          * Returns true if successful.
139          */
140         static bool Parse(SkFILE* filePtr, Json::Value *jsonRoot);
141 
142         Json::Value fActualResults;
143         Json::Value fExpectedJsonRoot;
144         Json::Value fExpectedResults;
145     };
146 
147 } // namespace sk_tools
148 
149 #endif  // image_expectations_DEFINED
150