Index: include/core/SkChecksum.h |
diff --git a/include/core/SkChecksum.h b/include/core/SkChecksum.h |
index 287109fef9d60386dc307a77ff72bd4276c42f45..bf3228f91db8722337e9b06db0fb23fb491d4e37 100644 |
--- a/include/core/SkChecksum.h |
+++ b/include/core/SkChecksum.h |
@@ -36,6 +36,42 @@ private: |
} |
public: |
+ |
+ /** |
+ * Calculate 32-bit Murmur hash (murmur3). |
+ * This should take 2-3x longer than SkChecksum::Compute, but is a considerably better hash. |
+ * See en.wikipedia.org/wiki/MurmurHash. |
+ * |
+ * @param data Memory address of the data block to be processed. Must be 32-bit aligned. |
+ * @param size Size of the data block in bytes. Must be a multiple of 4. |
+ * @param seed Initial hash seed. (optional) |
+ * @return hash result |
+ */ |
+ static uint32_t Murmur3(const uint32_t* data, size_t bytes, uint32_t seed=0) { |
+ SkASSERT(SkIsAlign4(bytes)); |
+ const size_t words = bytes/4; |
+ |
+ uint32_t hash = seed; |
+ for (size_t i = 0; i < words; i++) { |
+ uint32_t k = data[i]; |
+ k *= 0xcc9e2d51; |
+ k = (k << 15) | (k >> 17); |
+ k *= 0x1b873593; |
+ |
+ hash ^= k; |
+ hash = (hash << 13) | (hash >> 19); |
+ hash *= 5; |
+ hash += 0xe6546b64; |
+ } |
+ hash ^= bytes; |
+ hash ^= hash >> 16; |
+ hash *= 0x85ebca6b; |
+ hash ^= hash >> 13; |
+ hash *= 0xc2b2ae35; |
+ hash ^= hash >> 16; |
+ return hash; |
+ } |
+ |
/** |
* Compute a 32-bit checksum for a given data block |
* |