aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils
diff options
context:
space:
mode:
authorGravatar epoger@google.com <epoger@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-03 17:35:39 +0000
committerGravatar epoger@google.com <epoger@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-05-03 17:35:39 +0000
commitb4ca46d748364236e82fdaccc08022dd89e29d40 (patch)
tree1bb565bddd409b6e82e6dd5af39f39f80788438c /src/utils
parent25720b4d7e6f86043997c040315f2874aa2c8c9a (diff)
SkBitmapHasher: use 64-bit-truncated MD5 instead of 64-bit CityHash
BUG=https://code.google.com/p/skia/issues/detail?id=1257 (if we change our mind within the next few days, we can toggle the BITMAPHASHER_USES_TRUNCATED_MD5 #ifdef ; at some point, we'll remove that option so we can delete our CityHash implementation entirely) R=bungeman@google.com Review URL: https://codereview.chromium.org/14054012 git-svn-id: http://skia.googlecode.com/svn/trunk@8992 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/SkBitmapHasher.cpp32
-rw-r--r--src/utils/SkBitmapHasher.h2
2 files changed, 29 insertions, 5 deletions
diff --git a/src/utils/SkBitmapHasher.cpp b/src/utils/SkBitmapHasher.cpp
index e8352e59b9..82cbe9fa7e 100644
--- a/src/utils/SkBitmapHasher.cpp
+++ b/src/utils/SkBitmapHasher.cpp
@@ -7,15 +7,20 @@
#include "SkBitmap.h"
#include "SkBitmapHasher.h"
-#include "SkCityHash.h"
#include "SkEndian.h"
#include "SkImageEncoder.h"
+
+#ifdef BITMAPHASHER_USES_TRUNCATED_MD5
+#include "SkMD5.h"
+#else
+#include "SkCityHash.h"
#include "SkStream.h"
+#endif
/**
- * Write an integer value to a stream in little-endian order.
+ * Write an int32 value to a stream in little-endian order.
*/
-static void write_int_to_buffer(uint32_t val, SkWStream* out) {
+static void write_int32_to_buffer(uint32_t val, SkWStream* out) {
val = SkEndian_SwapLE32(val);
for (size_t byte = 0; byte < 4; ++byte) {
out->write8((uint8_t)(val & 0xff));
@@ -23,18 +28,29 @@ static void write_int_to_buffer(uint32_t val, SkWStream* out) {
}
}
+/**
+ * Return the first 8 bytes of a bytearray, encoded as a little-endian uint64.
+ */
+static inline uint64_t first_8_bytes_as_uint64(const uint8_t *bytearray) {
+ return SkEndian_SwapLE64(*(reinterpret_cast<const uint64_t *>(bytearray)));
+}
+
/*static*/ bool SkBitmapHasher::ComputeDigestInternal(const SkBitmap& bitmap,
SkHashDigest *result) {
+#ifdef BITMAPHASHER_USES_TRUNCATED_MD5
+ SkMD5 out;
+#else
size_t pixelBufferSize = bitmap.width() * bitmap.height() * 4;
size_t totalBufferSize = pixelBufferSize + 2 * sizeof(uint32_t);
SkAutoMalloc bufferManager(totalBufferSize);
char *bufferStart = static_cast<char *>(bufferManager.get());
SkMemoryWStream out(bufferStart, totalBufferSize);
+#endif
// start with the x/y dimensions
- write_int_to_buffer(SkToU32(bitmap.width()), &out);
- write_int_to_buffer(SkToU32(bitmap.height()), &out);
+ write_int32_to_buffer(SkToU32(bitmap.width()), &out);
+ write_int32_to_buffer(SkToU32(bitmap.height()), &out);
// add all the pixel data
SkAutoTDelete<SkImageEncoder> enc(CreateARGBImageEncoder());
@@ -42,7 +58,13 @@ static void write_int_to_buffer(uint32_t val, SkWStream* out) {
return false;
}
+#ifdef BITMAPHASHER_USES_TRUNCATED_MD5
+ SkMD5::Digest digest;
+ out.finish(digest);
+ *result = first_8_bytes_as_uint64(digest.data);
+#else
*result = SkCityHash::Compute64(bufferStart, totalBufferSize);
+#endif
return true;
}
diff --git a/src/utils/SkBitmapHasher.h b/src/utils/SkBitmapHasher.h
index 165da3dcc8..c99421a8d6 100644
--- a/src/utils/SkBitmapHasher.h
+++ b/src/utils/SkBitmapHasher.h
@@ -11,6 +11,8 @@
#include "SkBitmap.h"
+#define BITMAPHASHER_USES_TRUNCATED_MD5
+
// TODO(epoger): Soon, SkHashDigest will become a real class of its own,
// and callers won't be able to assume it converts to/from a uint64_t.
typedef uint64_t SkHashDigest;