190c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org/*
290c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org * Copyright 2014 Google Inc.
390c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org *
490c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
590c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org * found in the LICENSE file.
690c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org */
790c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org
890c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org#ifndef image_expectations_DEFINED
990c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org#define image_expectations_DEFINED
1090c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org
1190c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org#include "SkBitmap.h"
1290c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org#include "SkJSONCPP.h"
13abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org#include "SkOSFile.h"
14205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org#include "SkRefCnt.h"
1590c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org
1690c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.orgnamespace sk_tools {
1790c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org
1890c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org    /**
19205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     * The digest of an image (either an image we have generated locally, or an image expectation).
20205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     *
21205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     * Currently, this is always a uint64_t hash digest of an SkBitmap.
2290c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org     */
23205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    class ImageDigest : public SkRefCnt {
2490c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org    public:
2590c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org        /**
26205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * Create an ImageDigest of a bitmap.
2790c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         *
28205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * Note that this is an expensive operation, because it has to examine all pixels in
29205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * the bitmap.  You may wish to consider using the BitmapAndDigest class, which will
30205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * compute the ImageDigest lazily.
31205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         *
32205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * @param bitmap image to get the digest of
3390c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         */
34205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        explicit ImageDigest(const SkBitmap &bitmap);
35205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org
36205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        /**
37205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * Create an ImageDigest using a hashType/hashValue pair.
38205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         *
39205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * @param hashType the algorithm used to generate the hash; for now, only
40205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         *     kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 is allowed.
41205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * @param hashValue the value generated by the hash algorithm for a particular image.
42205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         */
43205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        explicit ImageDigest(const SkString &hashType, uint64_t hashValue);
44205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org
45205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        /**
46205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * Returns the hash digest type as an SkString.
47205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         *
48205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * For now, this always returns kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 .
49205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         */
50205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        SkString getHashType() const;
51205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org
52205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        /**
53205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * Returns the hash digest value as a uint64_t.
54205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         */
55205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        uint64_t getHashValue() const;
56205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org
57205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    private:
58205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        uint64_t fHashValue;
59205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    };
60205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org
61205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    /**
62205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     * Container that holds a reference to an SkBitmap and computes its ImageDigest lazily.
63205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     *
64205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     * Computing the ImageDigest can be expensive, so this can help you postpone (or maybe even
65205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     * avoid) that work.
66205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     */
67205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    class BitmapAndDigest {
68205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    public:
69205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        explicit BitmapAndDigest(const SkBitmap &bitmap);
70205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org
71205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        const ImageDigest *getImageDigestPtr();
72205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        const SkBitmap *getBitmapPtr() const;
73205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    private:
74205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        const SkBitmap fBitmap;
75205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        SkAutoTUnref<ImageDigest> fImageDigestRef;
76205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    };
77205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org
78205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    /**
79205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     * Collects ImageDigests of actually rendered images, perhaps comparing to expectations.
80205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org     */
81205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    class ImageResultsAndExpectations {
82205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org    public:
83205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        /**
84205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * Adds expectations from a JSON file, returning true if successful.
85abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         *
86abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * If the file exists but is empty, it succeeds, and there will be no expectations.
87abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * If the file does not exist, this will fail.
88abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         *
89abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * Reasoning:
90abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * Generating expectations the first time can be a tricky chicken-and-egg
91abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * proposition.  "I need actual results to turn into expectations... but the only
92abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * way to get actual results is to run the tool, and the tool won't run without
93abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * expectations!"
94abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * We could make the tool run even if there is no expectations file at all, but it's
95abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * better for the tool to fail if the expectations file is not found--that will tell us
96abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * quickly if files are not being copied around as they should be.
97abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * Creating an empty file is an easy way to break the chicken-and-egg cycle and generate
98abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * the first real expectations.
99205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         */
100205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        bool readExpectationsFile(const char *jsonPath);
10190c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org
10290c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org        /**
10390c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         * Adds this image to the summary of results.
10490c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         *
10590c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         * @param sourceName name of the source file that generated this result
10690c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         * @param fileName relative path to the image output file on local disk
107205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * @param digest description of the image's contents
1083f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org         * @param tileNumber if not NULL, pointer to tile number
10990c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         */
110205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        void add(const char *sourceName, const char *fileName, const ImageDigest &digest,
11190c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org                 const int *tileNumber=NULL);
11290c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org
11390c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org        /**
1143f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org         * Returns true if this test result matches its expectations.
1153f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org         * If there are no expectations for this test result, this will return false.
1163f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org         *
1173f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org         * @param sourceName name of the source file that generated this result
1183f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org         * @param digest description of the image's contents
1193f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org         * @param tileNumber if not NULL, pointer to tile number
1203f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org         */
1213f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org        bool matchesExpectation(const char *sourceName, const ImageDigest &digest,
1223f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org                                const int *tileNumber=NULL);
1233f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org
1243f0451772109959fcb79bacf2c9a03e0eb39ff27commit-bot@chromium.org        /**
12590c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         * Writes the summary (as constructed so far) to a file.
12690c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         *
12790c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         * @param filename path to write the summary to
12890c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org         */
129205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        void writeToFile(const char *filename) const;
13090c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org
13190c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org    private:
132205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org
133205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        /**
134abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * Read the file contents from filePtr and parse them into jsonRoot.
135abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         *
136abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org         * It is up to the caller to close filePtr after this is done.
137205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         *
138205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         * Returns true if successful.
139205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org         */
140abeb9589ec9e918203249652b15e7af6c9b33e18commit-bot@chromium.org        static bool Parse(SkFILE* filePtr, Json::Value *jsonRoot);
141205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org
14290c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org        Json::Value fActualResults;
143205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        Json::Value fExpectedJsonRoot;
144205ce48c38c55ec7527d26042b5cea689369be8bcommit-bot@chromium.org        Json::Value fExpectedResults;
14590c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org    };
14690c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org
14790c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org} // namespace sk_tools
14890c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org
14990c0fbd34947b6b644e90c5b2253752035f65b64commit-bot@chromium.org#endif  // image_expectations_DEFINED
150