blob: ab88cbc01a688821cd6b54a9bb1c8c936b7ee6fc [file] [log] [blame]
junov@chromium.orgef760602012-06-27 20:03:16 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkChecksum_DEFINED
9#define SkChecksum_DEFINED
10
11#include "SkTypes.h"
12
13#if !defined(SK_PREFER_32BIT_CHECKSUM)
14#define SK_PREFER_32BIT_CHECKSUM 0
15#endif
16
17enum {
18 ChecksumRotateBits = 17
19};
20
21#define SkCHECKSUM_MASH(CHECKSUM, NEW_CHUNK) \
22 CHECKSUM = (((CHECKSUM) >> (sizeof(CHECKSUM)*8 - ChecksumRotateBits)) + \
23 ((CHECKSUM) << ChecksumRotateBits)) ^ (NEW_CHUNK);
24
25
26/**
27 * Compute a 64-bit checksum for a given data block
28 *
29 * @param data Memory address of the data block to be processed. Must be
30 * 32-bit aligned
31 * @param size Size of the data block in bytes. Must be a multiple of 8.
32 * @return checksum result
33 */
34inline uint64_t SkComputeChecksum64(const uint64_t* ptr, size_t size) {
35 SkASSERT(SkIsAlign8(size));
36 // Strict 8-byte alignment is not required on ptr. On current
37 // CPUs there is no measurable performance difference between 32-bit
38 // and 64-bit aligned access to uint64_t data
39 SkASSERT(SkIsAlign4((intptr_t)ptr));
40
41 const uint64_t* stop = ptr + (size >> 3);
42 uint64_t result = 0;
43 while (ptr < stop) {
44 SkCHECKSUM_MASH(result, *ptr);
45 ptr++;
46 }
47 return result;
48}
49
50/**
51 * Compute a 32-bit checksum for a given data block
52 *
53 * @param data Memory address of the data block to be processed. Must be
54 * 32-bit aligned.
55 * @param size Size of the data block in bytes. Must be a multiple of 4.
56 * @return checksum result
57 */
58inline uint32_t SkComputeChecksum32(const uint32_t* ptr, size_t size) {
59 SkASSERT(SkIsAlign4(size));
60 SkASSERT(SkIsAlign4((intptr_t)ptr));
61
62 const uint32_t* stop = ptr + (size >> 2);
63 uint32_t result = 0;
64 while (ptr < stop) {
65 SkCHECKSUM_MASH(result, *ptr);
66 ptr++;
67 }
68 return result;
69}
robertphillips@google.comfffc8d02012-06-28 00:29:23 +000070#endif
71