"Fossies" - the Fresh Open Source Software Archive 
Member "pigz-2.8/zopfli/src/zopfli/hash.c" (28 Dec 2017, 3958 Bytes) of package /linux/privat/pigz-2.8.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "hash.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
2.4_vs_2.5.
1 /*
2 Copyright 2011 Google Inc. All Rights Reserved.
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 Author: lode.vandevenne@gmail.com (Lode Vandevenne)
17 Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
18 */
19
20 #include "hash.h"
21
22 #include <assert.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #define HASH_SHIFT 5
27 #define HASH_MASK 32767
28
29 void ZopfliAllocHash(size_t window_size, ZopfliHash* h) {
30 h->head = (int*)malloc(sizeof(*h->head) * 65536);
31 h->prev = (unsigned short*)malloc(sizeof(*h->prev) * window_size);
32 h->hashval = (int*)malloc(sizeof(*h->hashval) * window_size);
33
34 #ifdef ZOPFLI_HASH_SAME
35 h->same = (unsigned short*)malloc(sizeof(*h->same) * window_size);
36 #endif
37
38 #ifdef ZOPFLI_HASH_SAME_HASH
39 h->head2 = (int*)malloc(sizeof(*h->head2) * 65536);
40 h->prev2 = (unsigned short*)malloc(sizeof(*h->prev2) * window_size);
41 h->hashval2 = (int*)malloc(sizeof(*h->hashval2) * window_size);
42 #endif
43 }
44
45 void ZopfliResetHash(size_t window_size, ZopfliHash* h) {
46 size_t i;
47
48 h->val = 0;
49 for (i = 0; i < 65536; i++) {
50 h->head[i] = -1; /* -1 indicates no head so far. */
51 }
52 for (i = 0; i < window_size; i++) {
53 h->prev[i] = i; /* If prev[j] == j, then prev[j] is uninitialized. */
54 h->hashval[i] = -1;
55 }
56
57 #ifdef ZOPFLI_HASH_SAME
58 for (i = 0; i < window_size; i++) {
59 h->same[i] = 0;
60 }
61 #endif
62
63 #ifdef ZOPFLI_HASH_SAME_HASH
64 h->val2 = 0;
65 for (i = 0; i < 65536; i++) {
66 h->head2[i] = -1;
67 }
68 for (i = 0; i < window_size; i++) {
69 h->prev2[i] = i;
70 h->hashval2[i] = -1;
71 }
72 #endif
73 }
74
75 void ZopfliCleanHash(ZopfliHash* h) {
76 free(h->head);
77 free(h->prev);
78 free(h->hashval);
79
80 #ifdef ZOPFLI_HASH_SAME_HASH
81 free(h->head2);
82 free(h->prev2);
83 free(h->hashval2);
84 #endif
85
86 #ifdef ZOPFLI_HASH_SAME
87 free(h->same);
88 #endif
89 }
90
91 /*
92 Update the sliding hash value with the given byte. All calls to this function
93 must be made on consecutive input characters. Since the hash value exists out
94 of multiple input bytes, a few warmups with this function are needed initially.
95 */
96 static void UpdateHashValue(ZopfliHash* h, unsigned char c) {
97 h->val = (((h->val) << HASH_SHIFT) ^ (c)) & HASH_MASK;
98 }
99
100 void ZopfliUpdateHash(const unsigned char* array, size_t pos, size_t end,
101 ZopfliHash* h) {
102 unsigned short hpos = pos & ZOPFLI_WINDOW_MASK;
103 #ifdef ZOPFLI_HASH_SAME
104 size_t amount = 0;
105 #endif
106
107 UpdateHashValue(h, pos + ZOPFLI_MIN_MATCH <= end ?
108 array[pos + ZOPFLI_MIN_MATCH - 1] : 0);
109 h->hashval[hpos] = h->val;
110 if (h->head[h->val] != -1 && h->hashval[h->head[h->val]] == h->val) {
111 h->prev[hpos] = h->head[h->val];
112 }
113 else h->prev[hpos] = hpos;
114 h->head[h->val] = hpos;
115
116 #ifdef ZOPFLI_HASH_SAME
117 /* Update "same". */
118 if (h->same[(pos - 1) & ZOPFLI_WINDOW_MASK] > 1) {
119 amount = h->same[(pos - 1) & ZOPFLI_WINDOW_MASK] - 1;
120 }
121 while (pos + amount + 1 < end &&
122 array[pos] == array[pos + amount + 1] && amount < (unsigned short)(-1)) {
123 amount++;
124 }
125 h->same[hpos] = amount;
126 #endif
127
128 #ifdef ZOPFLI_HASH_SAME_HASH
129 h->val2 = ((h->same[hpos] - ZOPFLI_MIN_MATCH) & 255) ^ h->val;
130 h->hashval2[hpos] = h->val2;
131 if (h->head2[h->val2] != -1 && h->hashval2[h->head2[h->val2]] == h->val2) {
132 h->prev2[hpos] = h->head2[h->val2];
133 }
134 else h->prev2[hpos] = hpos;
135 h->head2[h->val2] = hpos;
136 #endif
137 }
138
139 void ZopfliWarmupHash(const unsigned char* array, size_t pos, size_t end,
140 ZopfliHash* h) {
141 UpdateHashValue(h, array[pos + 0]);
142 if (pos + 1 < end) UpdateHashValue(h, array[pos + 1]);
143 }