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