Fix T63775: Toolbar icons ignore BLENDER_SYSTEM_DATAFILES
[blender.git] / intern / cycles / util / util_murmurhash.cpp
1 /*
2  * Copyright 2018 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /* This is taken from alShaders/Cryptomatte/MurmurHash3.h:
18  *
19  * MurmurHash3 was written by Austin Appleby, and is placed in the public
20  * domain. The author hereby disclaims copyright to this source code.
21  */
22
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "util/util_algorithm.h"
27 #include "util/util_murmurhash.h"
28
29 #if defined(_MSC_VER)
30 #  define ROTL32(x, y) _rotl(x, y)
31 #  define ROTL64(x, y) _rotl64(x, y)
32 #  define BIG_CONSTANT(x) (x)
33 #else
34 ccl_device_inline uint32_t rotl32(uint32_t x, int8_t r)
35 {
36   return (x << r) | (x >> (32 - r));
37 }
38 #  define ROTL32(x, y) rotl32(x, y)
39 #  define BIG_CONSTANT(x) (x##LLU)
40 #endif
41
42 CCL_NAMESPACE_BEGIN
43
44 /* Block read - if your platform needs to do endian-swapping or can only
45  * handle aligned reads, do the conversion here. */
46 ccl_device_inline uint32_t mm_hash_getblock32(const uint32_t *p, int i)
47 {
48   return p[i];
49 }
50
51 /* Finalization mix - force all bits of a hash block to avalanche */
52 ccl_device_inline uint32_t mm_hash_fmix32(uint32_t h)
53 {
54   h ^= h >> 16;
55   h *= 0x85ebca6b;
56   h ^= h >> 13;
57   h *= 0xc2b2ae35;
58   h ^= h >> 16;
59   return h;
60 }
61
62 uint32_t util_murmur_hash3(const void *key, int len, uint32_t seed)
63 {
64   const uint8_t *data = (const uint8_t *)key;
65   const int nblocks = len / 4;
66
67   uint32_t h1 = seed;
68
69   const uint32_t c1 = 0xcc9e2d51;
70   const uint32_t c2 = 0x1b873593;
71
72   const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4);
73
74   for (int i = -nblocks; i; i++) {
75     uint32_t k1 = mm_hash_getblock32(blocks, i);
76
77     k1 *= c1;
78     k1 = ROTL32(k1, 15);
79     k1 *= c2;
80
81     h1 ^= k1;
82     h1 = ROTL32(h1, 13);
83     h1 = h1 * 5 + 0xe6546b64;
84   }
85
86   const uint8_t *tail = (const uint8_t *)(data + nblocks * 4);
87
88   uint32_t k1 = 0;
89
90   switch (len & 3) {
91     case 3:
92       k1 ^= tail[2] << 16;
93       ATTR_FALLTHROUGH;
94     case 2:
95       k1 ^= tail[1] << 8;
96       ATTR_FALLTHROUGH;
97     case 1:
98       k1 ^= tail[0];
99       k1 *= c1;
100       k1 = ROTL32(k1, 15);
101       k1 *= c2;
102       h1 ^= k1;
103   }
104
105   h1 ^= len;
106   h1 = mm_hash_fmix32(h1);
107   return h1;
108 }
109
110 /* This is taken from the cryptomatte specification 1.0 */
111 float util_hash_to_float(uint32_t hash)
112 {
113   uint32_t mantissa = hash & ((1 << 23) - 1);
114   uint32_t exponent = (hash >> 23) & ((1 << 8) - 1);
115   exponent = max(exponent, (uint32_t)1);
116   exponent = min(exponent, (uint32_t)254);
117   exponent = exponent << 23;
118   uint32_t sign = (hash >> 31);
119   sign = sign << 31;
120   uint32_t float_bits = sign | exponent | mantissa;
121   float f;
122   memcpy(&f, &float_bits, sizeof(uint32_t));
123   return f;
124 }
125
126 CCL_NAMESPACE_END