Index: src/utils/SkBitmapHasher.cpp |
=================================================================== |
--- src/utils/SkBitmapHasher.cpp (revision 8826) |
+++ src/utils/SkBitmapHasher.cpp (working copy) |
@@ -11,20 +11,50 @@ |
#include "SkBitmapTransformer.h" |
#include "SkCityHash.h" |
#include "SkEndian.h" |
+#include "SkMD5.h" |
/** |
- * Write an integer value into a bytebuffer in little-endian order. |
+ * Write an int32_t value into a bytebuffer in little-endian order. |
*/ |
-static void write_int_to_buffer(int val, char* buf) { |
- val = SkEndian_SwapLE32(val); |
+static void write_int32_to_buffer(int32_t val, char* buf) { |
for (int byte=0; byte<4; byte++) { |
*buf++ = (char)(val & 0xff); |
val = val >> 8; |
} |
} |
+#ifdef BITMAP_HASH_TYPE_SkHashDigest |
/*static*/ bool SkBitmapHasher::ComputeDigestInternal( |
- const SkBitmap& bitmap, const SkBitmapTransformer& transformer, SkHashDigest *result) { |
+ const SkBitmap& bitmap, const SkBitmapTransformer& transformer, BITMAP_HASH_TYPE *result) { |
+ SkMD5 hasher; |
+ |
+ // Start with x/y dimensions. |
+ uint8_t dimensions[8]; |
+ char *bufPtr = reinterpret_cast<char *>(dimensions); |
+ write_int32_to_buffer(bitmap.width(), bufPtr); |
+ write_int32_to_buffer(bitmap.height(), bufPtr + 4); |
+ hasher.update(dimensions, sizeof(dimensions)); |
+ |
+ // Add all the pixel data, one transformed row at a time. |
+ size_t rowBufferSize = transformer.bytesNeededPerRow(); |
+ SkAutoMalloc bufferManager(rowBufferSize); |
+ char *buffer = static_cast<char *>(bufferManager.get()); |
+ for (int row = 0; row < transformer.numRows(); row++) { |
+ if (!transformer.copyRowToPixelBuffer(row, buffer, rowBufferSize)) { |
+ return false; |
+ } |
+ hasher.update(reinterpret_cast<const uint8_t*>(buffer), rowBufferSize); |
+ } |
+ |
+ SkMD5::Digest digest; |
+ hasher.finish(digest); |
+ // EPOGER: instead of creating the extra copy on the stack and running copyFrom, use malloc and then just make the SkHashDigest hold a reference to it? |
+ result->copyFrom(&digest, sizeof(digest)); |
+ return true; |
+} |
+#else |
+/*static*/ bool SkBitmapHasher::ComputeDigestInternal( |
+ const SkBitmap& bitmap, const SkBitmapTransformer& transformer, BITMAP_HASH_TYPE *result) { |
size_t pixelBufferSize = transformer.bytesNeededTotal(); |
size_t totalBufferSize = pixelBufferSize + 8; // leave room for x/y dimensions |
@@ -32,9 +62,9 @@ |
char *bufferStart = static_cast<char *>(bufferManager.get()); |
char *bufPtr = bufferStart; |
// start with the x/y dimensions |
- write_int_to_buffer(bitmap.width(), bufPtr); |
+ write_int32_to_buffer(bitmap.width(), bufPtr); |
bufPtr += 4; |
- write_int_to_buffer(bitmap.height(), bufPtr); |
+ write_int32_to_buffer(bitmap.height(), bufPtr); |
bufPtr += 4; |
// add all the pixel data |
@@ -44,8 +74,9 @@ |
*result = SkCityHash::Compute64(bufferStart, totalBufferSize); |
return true; |
} |
+#endif |
-/*static*/ bool SkBitmapHasher::ComputeDigest(const SkBitmap& bitmap, SkHashDigest *result) { |
+/*static*/ bool SkBitmapHasher::ComputeDigest(const SkBitmap& bitmap, BITMAP_HASH_TYPE *result) { |
const SkBitmapTransformer::PixelFormat kPixelFormat = |
SkBitmapTransformer::kARGB_8888_Premul_PixelFormat; |