gfx/skia/trunk/src/utils/SkBitmapHasher.cpp

changeset 0
6474c204b198
     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(&copyBitmap, kPMColor_SkColorType)) {
    1.64 +        return false;
    1.65 +    }
    1.66 +    return ComputeDigestInternal(copyBitmap, result);
    1.67 +}

mercurial