Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Unified Diff: gm/gm_expectations.cpp

Issue 14284018: GM: specify that currently used checksums are CityHashes of SkBitmaps (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: fix_mac_trybot Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gm/gm_expectations.h ('k') | gm/gmmain.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gm/gm_expectations.cpp
===================================================================
--- gm/gm_expectations.cpp (revision 0)
+++ gm/gm_expectations.cpp (revision 0)
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm_expectations.h"
+#include "SkBitmapHasher.h"
+#include "SkImageDecoder.h"
+
+#define DEBUGFAIL_SEE_STDERR SkDEBUGFAIL("see stderr for message")
+
+const static char kJsonKey_ActualResults[] = "actual-results";
+const static char kJsonKey_ActualResults_Failed[] = "failed";
+const static char kJsonKey_ActualResults_FailureIgnored[]= "failure-ignored";
+const static char kJsonKey_ActualResults_NoComparison[] = "no-comparison";
+const static char kJsonKey_ActualResults_Succeeded[] = "succeeded";
+const static char kJsonKey_ActualResults_AnyStatus_BitmapCityhash[] = "bitmap-cityhash";
+
+const static char kJsonKey_ExpectedResults[] = "expected-results";
+const static char kJsonKey_ExpectedResults_AllowedBitmapCityhashes[] = "allowed-bitmap-cityhashes";
+const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-failure";
+
+namespace skiagm {
+
+ // TODO(epoger): This currently assumes that the result SkHashDigest was
+ // generated as a CityHash of an SkBitmap. We'll need to allow for other
+ // hash types to cover non-bitmaps, MD5 instead of CityHash, etc.
+ Json::Value ActualResultAsJsonValue(const SkHashDigest& result) {
+ Json::Value jsonValue;
+ jsonValue[kJsonKey_ActualResults_AnyStatus_BitmapCityhash] = asJsonValue(result);
+ return jsonValue;
+ }
+
+ Json::Value CreateJsonTree(Json::Value expectedResults,
+ Json::Value actualResultsFailed,
+ Json::Value actualResultsFailureIgnored,
+ Json::Value actualResultsNoComparison,
+ Json::Value actualResultsSucceeded) {
+ Json::Value actualResults;
+ actualResults[kJsonKey_ActualResults_Failed] = actualResultsFailed;
+ actualResults[kJsonKey_ActualResults_FailureIgnored] = actualResultsFailureIgnored;
+ actualResults[kJsonKey_ActualResults_NoComparison] = actualResultsNoComparison;
+ actualResults[kJsonKey_ActualResults_Succeeded] = actualResultsSucceeded;
+ Json::Value root;
+ root[kJsonKey_ActualResults] = actualResults;
+ root[kJsonKey_ExpectedResults] = expectedResults;
+ return root;
+ }
+
+
+ // Expectations class...
+
+ Expectations::Expectations(bool ignoreFailure) {
+ fIgnoreFailure = ignoreFailure;
+ }
+
+ Expectations::Expectations(const SkBitmap& bitmap, bool ignoreFailure) {
+ fBitmap = bitmap;
+ fIgnoreFailure = ignoreFailure;
+ SkHashDigest digest;
+ // TODO(epoger): Better handling for error returned by ComputeDigest()?
+ // For now, we just report a digest of 0 in error cases, like before.
+ if (!SkBitmapHasher::ComputeDigest(bitmap, &digest)) {
+ digest = 0;
+ }
+ fAllowedBitmapCityhashes.push_back() = digest;
+ }
+
+ Expectations::Expectations(Json::Value jsonElement) {
+ if (jsonElement.empty()) {
+ fIgnoreFailure = kDefaultIgnoreFailure;
+ } else {
+ Json::Value ignoreFailure = jsonElement[kJsonKey_ExpectedResults_IgnoreFailure];
+ if (ignoreFailure.isNull()) {
+ fIgnoreFailure = kDefaultIgnoreFailure;
+ } else if (!ignoreFailure.isBool()) {
+ gm_fprintf(stderr, "found non-boolean json value"
+ " for key '%s' in element '%s'\n",
+ kJsonKey_ExpectedResults_IgnoreFailure,
+ jsonElement.toStyledString().c_str());
+ DEBUGFAIL_SEE_STDERR;
+ fIgnoreFailure = kDefaultIgnoreFailure;
+ } else {
+ fIgnoreFailure = ignoreFailure.asBool();
+ }
+
+ Json::Value allowedChecksums =
+ jsonElement[kJsonKey_ExpectedResults_AllowedBitmapCityhashes];
+ if (allowedChecksums.isNull()) {
+ // ok, we'll just assume there aren't any expected checksums to compare against
+ } else if (!allowedChecksums.isArray()) {
+ gm_fprintf(stderr, "found non-array json value"
+ " for key '%s' in element '%s'\n",
+ kJsonKey_ExpectedResults_AllowedBitmapCityhashes,
+ jsonElement.toStyledString().c_str());
+ DEBUGFAIL_SEE_STDERR;
+ } else {
+ for (Json::ArrayIndex i=0; i<allowedChecksums.size(); i++) {
+ Json::Value checksumElement = allowedChecksums[i];
+ if (!checksumElement.isIntegral()) {
+ gm_fprintf(stderr, "found non-integer checksum"
+ " in json element '%s'\n",
+ jsonElement.toStyledString().c_str());
+ DEBUGFAIL_SEE_STDERR;
+ } else {
+ fAllowedBitmapCityhashes.push_back() = asChecksum(checksumElement);
+ }
+ }
+ }
+ }
+ }
+
+ bool Expectations::match(Checksum actualChecksum) const {
+ for (int i=0; i < this->fAllowedBitmapCityhashes.count(); i++) {
+ Checksum allowedChecksum = this->fAllowedBitmapCityhashes[i];
+ if (allowedChecksum == actualChecksum) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ Json::Value Expectations::asJsonValue() const {
+ Json::Value allowedChecksumArray;
+ if (!this->fAllowedBitmapCityhashes.empty()) {
+ for (int i=0; i < this->fAllowedBitmapCityhashes.count(); i++) {
+ Checksum allowedChecksum = this->fAllowedBitmapCityhashes[i];
+ allowedChecksumArray.append(Json::UInt64(allowedChecksum));
+ }
+ }
+
+ Json::Value jsonValue;
+ jsonValue[kJsonKey_ExpectedResults_AllowedBitmapCityhashes] = allowedChecksumArray;
+ jsonValue[kJsonKey_ExpectedResults_IgnoreFailure] = this->ignoreFailure();
+ return jsonValue;
+ }
+
+
+ // IndividualImageExpectationsSource class...
+
+ Expectations IndividualImageExpectationsSource::get(const char *testName) {
+ SkString path = make_filename(fRootDir.c_str(), "", testName,
+ "png");
+ SkBitmap referenceBitmap;
+ bool decodedReferenceBitmap =
+ SkImageDecoder::DecodeFile(path.c_str(), &referenceBitmap,
+ SkBitmap::kARGB_8888_Config,
+ SkImageDecoder::kDecodePixels_Mode,
+ NULL);
+ if (decodedReferenceBitmap) {
+ return Expectations(referenceBitmap);
+ } else {
+ return Expectations();
+ }
+ }
+
+
+ // JsonExpectationsSource class...
+
+ JsonExpectationsSource::JsonExpectationsSource(const char *jsonPath) {
+ parse(jsonPath, &fJsonRoot);
+ fJsonExpectedResults = fJsonRoot[kJsonKey_ExpectedResults];
+ }
+
+ Expectations JsonExpectationsSource::get(const char *testName) {
+ return Expectations(fJsonExpectedResults[testName]);
+ }
+
+ /*static*/ SkData* JsonExpectationsSource::readIntoSkData(SkStream &stream, size_t maxBytes) {
+ if (0 == maxBytes) {
+ return SkData::NewEmpty();
+ }
+ char* bufStart = reinterpret_cast<char *>(sk_malloc_throw(maxBytes));
+ char* bufPtr = bufStart;
+ size_t bytesRemaining = maxBytes;
+ while (bytesRemaining > 0) {
+ size_t bytesReadThisTime = stream.read(bufPtr, bytesRemaining);
+ if (0 == bytesReadThisTime) {
+ break;
+ }
+ bytesRemaining -= bytesReadThisTime;
+ bufPtr += bytesReadThisTime;
+ }
+ return SkData::NewFromMalloc(bufStart, maxBytes - bytesRemaining);
+ }
+
+ /*static*/ bool JsonExpectationsSource::parse(const char *jsonPath, Json::Value *jsonRoot) {
+ SkFILEStream inFile(jsonPath);
+ if (!inFile.isValid()) {
+ gm_fprintf(stderr, "unable to read JSON file %s\n", jsonPath);
+ DEBUGFAIL_SEE_STDERR;
+ return false;
+ }
+
+ SkAutoDataUnref dataRef(readFileIntoSkData(inFile));
+ if (NULL == dataRef.get()) {
+ gm_fprintf(stderr, "error reading JSON file %s\n", jsonPath);
+ DEBUGFAIL_SEE_STDERR;
+ return false;
+ }
+
+ const char *bytes = reinterpret_cast<const char *>(dataRef.get()->data());
+ size_t size = dataRef.get()->size();
+ Json::Reader reader;
+ if (!reader.parse(bytes, bytes+size, *jsonRoot)) {
+ gm_fprintf(stderr, "error parsing JSON file %s\n", jsonPath);
+ DEBUGFAIL_SEE_STDERR;
+ return false;
+ }
+ return true;
+ }
+
+}
« no previous file with comments | « gm/gm_expectations.h ('k') | gm/gmmain.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698