1 1.1 tls /* 2 1.1 tls Copyright 2011 Google Inc. All Rights Reserved. 3 1.1 tls 4 1.1 tls Licensed under the Apache License, Version 2.0 (the "License"); 5 1.1 tls you may not use this file except in compliance with the License. 6 1.1 tls You may obtain a copy of the License at 7 1.1 tls 8 1.1 tls http://www.apache.org/licenses/LICENSE-2.0 9 1.1 tls 10 1.1 tls Unless required by applicable law or agreed to in writing, software 11 1.1 tls distributed under the License is distributed on an "AS IS" BASIS, 12 1.1 tls WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 1.1 tls See the License for the specific language governing permissions and 14 1.1 tls limitations under the License. 15 1.1 tls 16 1.1 tls Author: lode.vandevenne (at) gmail.com (Lode Vandevenne) 17 1.1 tls Author: jyrki.alakuijala (at) gmail.com (Jyrki Alakuijala) 18 1.1 tls */ 19 1.1 tls 20 1.1 tls #include "hash.h" 21 1.1 tls 22 1.1 tls #include <assert.h> 23 1.1 tls #include <stdio.h> 24 1.1 tls #include <stdlib.h> 25 1.1 tls 26 1.1 tls #define HASH_SHIFT 5 27 1.1 tls #define HASH_MASK 32767 28 1.1 tls 29 1.1 tls void ZopfliInitHash(size_t window_size, ZopfliHash* h) { 30 1.1 tls size_t i; 31 1.1 tls 32 1.1 tls h->val = 0; 33 1.1 tls h->head = (int*)malloc(sizeof(*h->head) * 65536); 34 1.1 tls h->prev = (unsigned short*)malloc(sizeof(*h->prev) * window_size); 35 1.1 tls h->hashval = (int*)malloc(sizeof(*h->hashval) * window_size); 36 1.1 tls for (i = 0; i < 65536; i++) { 37 1.1 tls h->head[i] = -1; /* -1 indicates no head so far. */ 38 1.1 tls } 39 1.1 tls for (i = 0; i < window_size; i++) { 40 1.1 tls h->prev[i] = i; /* If prev[j] == j, then prev[j] is uninitialized. */ 41 1.1 tls h->hashval[i] = -1; 42 1.1 tls } 43 1.1 tls 44 1.1 tls #ifdef ZOPFLI_HASH_SAME 45 1.1 tls h->same = (unsigned short*)malloc(sizeof(*h->same) * window_size); 46 1.1 tls for (i = 0; i < window_size; i++) { 47 1.1 tls h->same[i] = 0; 48 1.1 tls } 49 1.1 tls #endif 50 1.1 tls 51 1.1 tls #ifdef ZOPFLI_HASH_SAME_HASH 52 1.1 tls h->val2 = 0; 53 1.1 tls h->head2 = (int*)malloc(sizeof(*h->head2) * 65536); 54 1.1 tls h->prev2 = (unsigned short*)malloc(sizeof(*h->prev2) * window_size); 55 1.1 tls h->hashval2 = (int*)malloc(sizeof(*h->hashval2) * window_size); 56 1.1 tls for (i = 0; i < 65536; i++) { 57 1.1 tls h->head2[i] = -1; 58 1.1 tls } 59 1.1 tls for (i = 0; i < window_size; i++) { 60 1.1 tls h->prev2[i] = i; 61 1.1 tls h->hashval2[i] = -1; 62 1.1 tls } 63 1.1 tls #endif 64 1.1 tls } 65 1.1 tls 66 1.1 tls void ZopfliCleanHash(ZopfliHash* h) { 67 1.1 tls free(h->head); 68 1.1 tls free(h->prev); 69 1.1 tls free(h->hashval); 70 1.1 tls 71 1.1 tls #ifdef ZOPFLI_HASH_SAME_HASH 72 1.1 tls free(h->head2); 73 1.1 tls free(h->prev2); 74 1.1 tls free(h->hashval2); 75 1.1 tls #endif 76 1.1 tls 77 1.1 tls #ifdef ZOPFLI_HASH_SAME 78 1.1 tls free(h->same); 79 1.1 tls #endif 80 1.1 tls } 81 1.1 tls 82 1.1 tls /* 83 1.1 tls Update the sliding hash value with the given byte. All calls to this function 84 1.1 tls must be made on consecutive input characters. Since the hash value exists out 85 1.1 tls of multiple input bytes, a few warmups with this function are needed initially. 86 1.1 tls */ 87 1.1 tls static void UpdateHashValue(ZopfliHash* h, unsigned char c) { 88 1.1 tls h->val = (((h->val) << HASH_SHIFT) ^ (c)) & HASH_MASK; 89 1.1 tls } 90 1.1 tls 91 1.1 tls void ZopfliUpdateHash(const unsigned char* array, size_t pos, size_t end, 92 1.1 tls ZopfliHash* h) { 93 1.1 tls unsigned short hpos = pos & ZOPFLI_WINDOW_MASK; 94 1.1 tls #ifdef ZOPFLI_HASH_SAME 95 1.1 tls size_t amount = 0; 96 1.1 tls #endif 97 1.1 tls 98 1.1 tls UpdateHashValue(h, pos + ZOPFLI_MIN_MATCH <= end ? 99 1.1 tls array[pos + ZOPFLI_MIN_MATCH - 1] : 0); 100 1.1 tls h->hashval[hpos] = h->val; 101 1.1 tls if (h->head[h->val] != -1 && h->hashval[h->head[h->val]] == h->val) { 102 1.1 tls h->prev[hpos] = h->head[h->val]; 103 1.1 tls } 104 1.1 tls else h->prev[hpos] = hpos; 105 1.1 tls h->head[h->val] = hpos; 106 1.1 tls 107 1.1 tls #ifdef ZOPFLI_HASH_SAME 108 1.1 tls /* Update "same". */ 109 1.1 tls if (h->same[(pos - 1) & ZOPFLI_WINDOW_MASK] > 1) { 110 1.1 tls amount = h->same[(pos - 1) & ZOPFLI_WINDOW_MASK] - 1; 111 1.1 tls } 112 1.1 tls while (pos + amount + 1 < end && 113 1.1 tls array[pos] == array[pos + amount + 1] && amount < (unsigned short)(-1)) { 114 1.1 tls amount++; 115 1.1 tls } 116 1.1 tls h->same[hpos] = amount; 117 1.1 tls #endif 118 1.1 tls 119 1.1 tls #ifdef ZOPFLI_HASH_SAME_HASH 120 1.1 tls h->val2 = ((h->same[hpos] - ZOPFLI_MIN_MATCH) & 255) ^ h->val; 121 1.1 tls h->hashval2[hpos] = h->val2; 122 1.1 tls if (h->head2[h->val2] != -1 && h->hashval2[h->head2[h->val2]] == h->val2) { 123 1.1 tls h->prev2[hpos] = h->head2[h->val2]; 124 1.1 tls } 125 1.1 tls else h->prev2[hpos] = hpos; 126 1.1 tls h->head2[h->val2] = hpos; 127 1.1 tls #endif 128 1.1 tls } 129 1.1 tls 130 1.1 tls void ZopfliWarmupHash(const unsigned char* array, size_t pos, size_t end, 131 1.1 tls ZopfliHash* h) { 132 1.1 tls (void)end; 133 1.1 tls UpdateHashValue(h, array[pos + 0]); 134 1.1 tls UpdateHashValue(h, array[pos + 1]); 135 1.1 tls } 136