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 /** 5521b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * Modify the pattern used to generate commonName (= the 5621b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * basename of rgb/white diff files). 5721b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * 5821b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * - true: basename is a combination of the input file names. 5921b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * - false: basename is the common prefix of the input file names. 6021b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * 6121b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * For example, for: 6221b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * baselinePath=/tmp/dir/image-before.png 6321b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * testPath=/tmp/dir/image-after.png 6421b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * 6521b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * If setLongNames(true), commonName would be: 6621b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * image-before-png-vs-image-after-png.png 6721b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * 6821b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * If setLongNames(false), commonName would be: 6921b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * image-.png 7021b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana */ 7121b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana void setLongNames(const bool useLongNames); 7221b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana 7321b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana /** 74945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * Sets the differs to be used in each diff. Already started diffs will not retroactively use 75945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * these. 76945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * @param differs An array of differs to use. The array is copied, but not the differs 77945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * themselves. 78945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com */ 79945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com void setDiffers(const SkTDArray<SkImageDiffer*>& differs); 80945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com 81945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com /** 82945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * Compares two directories of images with the given differ 83945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * @param baselinePath The baseline directory's path 84945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * @param testPath The test directory's path 85945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com */ 86945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com void diffDirectories(const char baselinePath[], const char testPath[]); 87945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com 88945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com /** 89945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * Compares two sets of images identified by glob style patterns with the given differ 90945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * @param baselinePattern A pattern for baseline files 91945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * @param testPattern A pattern for test files that matches each file of the baseline file 92945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com */ 93945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com void diffPatterns(const char baselinePattern[], const char testPattern[]); 94945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com 95945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com /** 96945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * Compares the images at the given paths 97945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * @param baselinePath The baseline file path 98945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * @param testPath The matching test file path 99945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com */ 100945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com void addDiff(const char* baselinePath, const char* testPath); 101945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com 102945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com /** 103945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * Output the records of each diff in JSON. 104945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * 105945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * The format of the JSON document is one top level array named "records". 106efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * Each record in the array is an object with the following values: 10721b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * "commonName" : string containing the output filename (basename) 10821b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * depending on the value of 'longNames'. 10921b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana * (see 'setLongNames' for an explanation and example). 110efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * "baselinePath" : string containing the path to the baseline image 111efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * "testPath" : string containing the path to the test image 112efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * "differencePath" : (optional) string containing the path to an alpha 113efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * mask of the pixel difference between the baseline 114efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * and test images 11554f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger * TODO(epoger): consider renaming this "alphaMaskPath" 11654f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger * to distinguish from other difference types? 11754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger * "rgbDiffPath" : (optional) string containing the path to a bitmap 11854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger * showing per-channel differences between the 11954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger * baseline and test images at each pixel 12054f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger * "whiteDiffPath" : (optional) string containing the path to a bitmap 12154f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger * showing every pixel that differs between the 12254f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger * baseline and test images as white 123efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * 124945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * They also have an array named "diffs" with each element being one diff record for the two 125945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * images indicated in the above field. 126945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * A diff record includes: 127945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * "differName" : string name of the diff metric used 128945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * "result" : numerical result of the diff 129945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * 130945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * Here is an example: 131945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * 132945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * { 133945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * "records": [ 134945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * { 135efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * "commonName": "queue.png", 136efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * "baselinePath": "/a/queue.png", 137efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com * "testPath": "/b/queue.png", 138945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * "diffs": [ 139945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * { 140945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * "differName": "different_pixels", 141945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * "result": 1, 142945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * } 143945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * ] 144945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * } 145945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * ] 146945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * } 147945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com * 148a95959c3fb4c502b45bc78f15b65cda1f21620e6zachr@google.com * @param stream The stream to output the diff to 149a95959c3fb4c502b45bc78f15b65cda1f21620e6zachr@google.com * @param useJSONP True to adding padding to the JSON output to make it cross-site requestable. 150945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com */ 151a95959c3fb4c502b45bc78f15b65cda1f21620e6zachr@google.com void outputRecords(SkWStream& stream, bool useJSONP); 152945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com 153c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com /** 154c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com * Output the records score in csv format. 155c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com */ 156c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com void outputCsv(SkWStream& stream); 157c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com 158c93c8ac625a89c14f392d46620abaf6edfabe02eedisonn@google.com 159945708ad9494322e2bc26776ccb741776205b4b8zachr@google.comprivate: 160945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com struct DiffData { 161945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com const char* fDiffName; 162efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com SkImageDiffer::Result fResult; 163945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com }; 164945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com 165945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com struct DiffRecord { 16654f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger // TODO(djsollen): Some of these fields are required, while others are optional 16754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger // (e.g., fRgbDiffPath is only filled in if SkDifferentPixelsMetric 16854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger // was run). Figure out a way to note that. See http://skbug.com/2712 16954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger // ('allow skpdiff to report different sets of result fields for 17054f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger // different comparison algorithms') 171513a7bffd344a2bba6e014ec08838ea0bbb8aa68djsollen@google.com SkString fCommonName; 17254f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger SkString fAlphaMaskPath; 17354f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger SkString fRgbDiffPath; 17454f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger SkString fWhiteDiffPath; 175945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com SkString fBaselinePath; 176945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com SkString fTestPath; 17754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger SkISize fSize; 17854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger int fMaxRedDiff; 17954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger int fMaxGreenDiff; 18054f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger int fMaxBlueDiff; 181945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com SkTArray<DiffData> fDiffs; 182945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com }; 183945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com 184efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com // Used to protect access to fRecords and ensure only one thread is 185efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com // adding new entries at a time. 186efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com SkMutex fRecordMutex; 187efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com 188945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com // We use linked list for the records so that their pointers remain stable. A resizable array 189945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com // might change its pointers, which would make it harder for async diffs to record their 190945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com // results. 191efc51b79a22348e3c2596e872609a7a4b018e531djsollen@google.com SkTLList<DiffRecord> fRecords; 192945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com 193945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com SkImageDiffer** fDiffers; 194945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com int fDifferCount; 195cbbf1ca304d35e3acd944609cf7a1c5127d0ca56djsollen@google.com int fThreadCount; 196513a7bffd344a2bba6e014ec08838ea0bbb8aa68djsollen@google.com 19754f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger SkString fAlphaMaskDir; 19854f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger SkString fRgbDiffDir; 19954f1ad8bb5bdd2ac2ea7981427abeb193383d449epoger SkString fWhiteDiffDir; 20021b342d19c71fa5abe7e4aa5cfb518fd04cb9d67stephana bool longNames; 201945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com}; 202945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com 203945708ad9494322e2bc26776ccb741776205b4b8zachr@google.com#endif 204