1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/utils/SkBitmapHasher.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,64 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkBitmap.h" 1.12 +#include "SkBitmapHasher.h" 1.13 +#include "SkEndian.h" 1.14 +#include "SkImageEncoder.h" 1.15 + 1.16 +#include "SkMD5.h" 1.17 + 1.18 +/** 1.19 + * Write an int32 value to a stream in little-endian order. 1.20 + */ 1.21 +static void write_int32_to_buffer(uint32_t val, SkWStream* out) { 1.22 + val = SkEndian_SwapLE32(val); 1.23 + for (size_t byte = 0; byte < 4; ++byte) { 1.24 + out->write8((uint8_t)(val & 0xff)); 1.25 + val = val >> 8; 1.26 + } 1.27 +} 1.28 + 1.29 +/** 1.30 + * Return the first 8 bytes of a bytearray, encoded as a little-endian uint64. 1.31 + */ 1.32 +static inline uint64_t first_8_bytes_as_uint64(const uint8_t *bytearray) { 1.33 + return SkEndian_SwapLE64(*(reinterpret_cast<const uint64_t *>(bytearray))); 1.34 +} 1.35 + 1.36 +/*static*/ bool SkBitmapHasher::ComputeDigestInternal(const SkBitmap& bitmap, uint64_t *result) { 1.37 + SkMD5 out; 1.38 + 1.39 + // start with the x/y dimensions 1.40 + write_int32_to_buffer(SkToU32(bitmap.width()), &out); 1.41 + write_int32_to_buffer(SkToU32(bitmap.height()), &out); 1.42 + 1.43 + // add all the pixel data 1.44 + SkAutoTDelete<SkImageEncoder> enc(CreateARGBImageEncoder()); 1.45 + if (!enc->encodeStream(&out, bitmap, SkImageEncoder::kDefaultQuality)) { 1.46 + return false; 1.47 + } 1.48 + 1.49 + SkMD5::Digest digest; 1.50 + out.finish(digest); 1.51 + *result = first_8_bytes_as_uint64(digest.data); 1.52 + return true; 1.53 +} 1.54 + 1.55 +/*static*/ bool SkBitmapHasher::ComputeDigest(const SkBitmap& bitmap, uint64_t *result) { 1.56 + if (ComputeDigestInternal(bitmap, result)) { 1.57 + return true; 1.58 + } 1.59 + 1.60 + // Hmm, that didn't work. Maybe if we create a new 1.61 + // kARGB_8888_Config version of the bitmap it will work better? 1.62 + SkBitmap copyBitmap; 1.63 + if (!bitmap.copyTo(©Bitmap, kPMColor_SkColorType)) { 1.64 + return false; 1.65 + } 1.66 + return ComputeDigestInternal(copyBitmap, result); 1.67 +}