SkDiffContext.h revision 54f1ad8bb5bdd2ac2ea7981427abeb193383d449
1945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com/*
2945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * Copyright 2013 Google Inc.
3945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com *
4945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * Use of this source code is governed by a BSD-style license that can be
5945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * found in the LICENSE file.
6945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com */
7945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
8945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com#ifndef SkDiffContext_DEFINED
9945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com#define SkDiffContext_DEFINED
10945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
11efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com#include "SkImageDiffer.h"
12945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com#include "SkString.h"
13945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com#include "SkTArray.h"
14945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com#include "SkTDArray.h"
15efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com#include "SkTLList.h"
16efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com#include "SkThread.h"
17945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
18945708ad9494322e2bc26776ccb741776205b4b8zachr@google.comclass SkWStream;
19945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
20945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com/**
21945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * Collects records of diffs and outputs them as JSON.
22945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com */
23945708ad9494322e2bc26776ccb741776205b4b8zachr@google.comclass SkDiffContext {
24945708ad9494322e2bc26776ccb741776205b4b8zachr@google.compublic:
25945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    SkDiffContext();
26945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    ~SkDiffContext();
27945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
28cbbf1ca304d35e3acd944609cf7a1c5127d0ca56djsollen@google.com    void setThreadCount(int threadCount) { fThreadCount = threadCount; }
29cbbf1ca304d35e3acd944609cf7a1c5127d0ca56djsollen@google.com
30945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    /**
3154f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     * Sets the directory within which to store alphaMasks (images that
3254f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     * are transparent for each pixel that differs between baseline and test).
3354f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *
3454f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     * If the directory does not exist yet, it will be created.
3554f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     */
3654f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger    void setAlphaMaskDir(const SkString& directory);
3754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger
3854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger    /**
3954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     * Sets the directory within which to store rgbDiffs (images showing the
4054f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     * per-channel difference between baseline and test at each pixel).
4154f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *
4254f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     * If the directory does not exist yet, it will be created.
4354f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     */
4454f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger    void setRgbDiffDir(const SkString& directory);
4554f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger
4654f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger    /**
4754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     * Sets the directory within which to store whiteDiffs (images showing white
4854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     * for each pixel that differs between baseline and test).
4954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *
5054f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     * If the directory does not exist yet, it will be created.
51513a7bffd344a2bba6e014ec08838ea0bbb8aa68djsollen@google.com     */
5254f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger    void setWhiteDiffDir(const SkString& directory);
53513a7bffd344a2bba6e014ec08838ea0bbb8aa68djsollen@google.com
54513a7bffd344a2bba6e014ec08838ea0bbb8aa68djsollen@google.com    /**
55945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * Sets the differs to be used in each diff. Already started diffs will not retroactively use
56945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * these.
57945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * @param differs An array of differs to use. The array is copied, but not the differs
58945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *                themselves.
59945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     */
60945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    void setDiffers(const SkTDArray<SkImageDiffer*>& differs);
61945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
62945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    /**
63945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * Compares two directories of images with the given differ
64945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * @param baselinePath The baseline directory's path
65945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * @param testPath     The test directory's path
66945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     */
67945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    void diffDirectories(const char baselinePath[], const char testPath[]);
68945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
69945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    /**
70945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * Compares two sets of images identified by glob style patterns with the given differ
71945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * @param baselinePattern A pattern for baseline files
72945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * @param testPattern     A pattern for test files that matches each file of the baseline file
73945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     */
74945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    void diffPatterns(const char baselinePattern[], const char testPattern[]);
75945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
76945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    /**
77945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * Compares the images at the given paths
78945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * @param baselinePath The baseline file path
79945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * @param testPath     The matching test file path
80945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     */
81945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    void addDiff(const char* baselinePath, const char* testPath);
82945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
83945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    /**
84945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * Output the records of each diff in JSON.
85945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *
86945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * The format of the JSON document is one top level array named "records".
87efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     * Each record in the array is an object with the following values:
88efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *    "commonName"     : string containing the common prefix of the baselinePath
89efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *                       and testPath filenames
90efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *    "baselinePath"   : string containing the path to the baseline image
91efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *    "testPath"       : string containing the path to the test image
92efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *    "differencePath" : (optional) string containing the path to an alpha
93efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *                       mask of the pixel difference between the baseline
94efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *                       and test images
9554f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *                       TODO(epoger): consider renaming this "alphaMaskPath"
9654f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *                       to distinguish from other difference types?
9754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *    "rgbDiffPath"    : (optional) string containing the path to a bitmap
9854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *                       showing per-channel differences between the
9954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *                       baseline and test images at each pixel
10054f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *    "whiteDiffPath"  : (optional) string containing the path to a bitmap
10154f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *                       showing every pixel that differs between the
10254f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger     *                       baseline and test images as white
103efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *
104945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * They also have an array named "diffs" with each element being one diff record for the two
105945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * images indicated in the above field.
106945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * A diff record includes:
107945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *    "differName"       : string name of the diff metric used
108945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *    "result"           : numerical result of the diff
109945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *
110945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * Here is an example:
111945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *
112945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * {
113945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *     "records": [
114945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *         {
115efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *             "commonName": "queue.png",
116efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *             "baselinePath": "/a/queue.png",
117efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com     *             "testPath": "/b/queue.png",
118945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *             "diffs": [
119945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *                 {
120945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *                     "differName": "different_pixels",
121945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *                     "result": 1,
122945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *                 }
123945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *             ]
124945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *         }
125945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *     ]
126945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     * }
127945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     *
128a95959c3fb4c502b45bc78f15b65cda1f21620e6zachr@google.com     * @param stream   The stream to output the diff to
129a95959c3fb4c502b45bc78f15b65cda1f21620e6zachr@google.com     * @param useJSONP True to adding padding to the JSON output to make it cross-site requestable.
130945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com     */
131a95959c3fb4c502b45bc78f15b65cda1f21620e6zachr@google.com    void outputRecords(SkWStream& stream, bool useJSONP);
132945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
133c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com    /**
134c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com     * Output the records score in csv format.
135c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com     */
136c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com    void outputCsv(SkWStream& stream);
137c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com
138c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com
139945708ad9494322e2bc26776ccb741776205b4b8zachr@google.comprivate:
140945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    struct DiffData {
141945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com        const char* fDiffName;
142efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com        SkImageDiffer::Result fResult;
143945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    };
144945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
145945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    struct DiffRecord {
14654f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        // TODO(djsollen): Some of these fields are required, while others are optional
14754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        // (e.g., fRgbDiffPath is only filled in if SkDifferentPixelsMetric
14854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        // was run).  Figure out a way to note that.  See http://skbug.com/2712
14954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        // ('allow skpdiff to report different sets of result fields for
15054f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        // different comparison algorithms')
151513a7bffd344a2bba6e014ec08838ea0bbb8aa68djsollen@google.com        SkString           fCommonName;
15254f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        SkString           fAlphaMaskPath;
15354f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        SkString           fRgbDiffPath;
15454f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        SkString           fWhiteDiffPath;
155945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com        SkString           fBaselinePath;
156945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com        SkString               fTestPath;
15754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        SkISize                    fSize;
15854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        int                  fMaxRedDiff;
15954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        int                fMaxGreenDiff;
16054f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger        int                 fMaxBlueDiff;
161945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com        SkTArray<DiffData>        fDiffs;
162945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    };
163945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
164efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com    // Used to protect access to fRecords and ensure only one thread is
165efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com    // adding new entries at a time.
166efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com    SkMutex fRecordMutex;
167efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com
168945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    // We use linked list for the records so that their pointers remain stable. A resizable array
169945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    // might change its pointers, which would make it harder for async diffs to record their
170945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    // results.
171efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com    SkTLList<DiffRecord> fRecords;
172945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
173945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    SkImageDiffer** fDiffers;
174945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com    int fDifferCount;
175cbbf1ca304d35e3acd944609cf7a1c5127d0ca56djsollen@google.com    int fThreadCount;
176513a7bffd344a2bba6e014ec08838ea0bbb8aa68djsollen@google.com
17754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger    SkString fAlphaMaskDir;
17854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger    SkString fRgbDiffDir;
17954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger    SkString fWhiteDiffDir;
180945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com};
181945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com
182945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com#endif
183