1 #ifndef INSERT_STRING_H_
2 #define INSERT_STRING_H_
3
4 /* insert_string.h -- Private insert_string functions shared with more than
5 * one insert string implementation
6 *
7 * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
8 *
9 * Copyright (C) 2013 Intel Corporation. All rights reserved.
10 * Authors:
11 * Wajdi Feghali <wajdi.k.feghali@intel.com>
12 * Jim Guilford <james.guilford@intel.com>
13 * Vinodh Gopal <vinodh.gopal@intel.com>
14 * Erdinc Ozturk <erdinc.ozturk@intel.com>
15 * Jim Kukunas <james.t.kukunas@linux.intel.com>
16 *
17 * Portions are Copyright (C) 2016 12Sided Technology, LLC.
18 * Author:
19 * Phil Vachon <pvachon@12sidedtech.com>
20 *
21 * For conditions of distribution and use, see copyright notice in zlib.h
22 *
23 */
24
25 #ifndef HASH_CALC_OFFSET
26 # define HASH_CALC_OFFSET 0
27 #endif
28 #ifndef HASH_CALC_MASK
29 # define HASH_CALC_MASK HASH_MASK
30 #endif
31 #ifndef HASH_CALC_READ
32 # if BYTE_ORDER == LITTLE_ENDIAN
33 # define HASH_CALC_READ \
34 zmemcpy_4(&val, strstart);
35 # else
36 # define HASH_CALC_READ \
37 val = ((uint32_t)(strstart[0])); \
38 val |= ((uint32_t)(strstart[1]) << 8); \
39 val |= ((uint32_t)(strstart[2]) << 16); \
40 val |= ((uint32_t)(strstart[3]) << 24);
41 # endif
42 #endif
43
44 /* ===========================================================================
45 * Update a hash value with the given input byte
46 * IN assertion: all calls to to UPDATE_HASH are made with consecutive
47 * input characters, so that a running hash key can be computed from the
48 * previous key instead of complete recalculation each time.
49 */
UPDATE_HASH(deflate_state * const s,uint32_t h,uint32_t val)50 Z_INTERNAL uint32_t UPDATE_HASH(deflate_state *const s, uint32_t h, uint32_t val) {
51 (void)s;
52 HASH_CALC(s, h, val);
53 return h & HASH_CALC_MASK;
54 }
55
56 /* ===========================================================================
57 * Quick insert string str in the dictionary and set match_head to the previous head
58 * of the hash chain (the most recent string with same hash key). Return
59 * the previous length of the hash chain.
60 */
QUICK_INSERT_STRING(deflate_state * const s,uint32_t str)61 Z_INTERNAL Pos QUICK_INSERT_STRING(deflate_state *const s, uint32_t str) {
62 Pos head;
63 uint8_t *strstart = s->window + str + HASH_CALC_OFFSET;
64 uint32_t val, hm;
65
66 HASH_CALC_VAR_INIT;
67 HASH_CALC_READ;
68 HASH_CALC(s, HASH_CALC_VAR, val);
69 HASH_CALC_VAR &= HASH_CALC_MASK;
70 hm = HASH_CALC_VAR;
71
72 head = s->head[hm];
73 if (LIKELY(head != str)) {
74 s->prev[str & s->w_mask] = head;
75 s->head[hm] = (Pos)str;
76 }
77 return head;
78 }
79
80 /* ===========================================================================
81 * Insert string str in the dictionary and set match_head to the previous head
82 * of the hash chain (the most recent string with same hash key). Return
83 * the previous length of the hash chain.
84 * IN assertion: all calls to to INSERT_STRING are made with consecutive
85 * input characters and the first STD_MIN_MATCH bytes of str are valid
86 * (except for the last STD_MIN_MATCH-1 bytes of the input file).
87 */
INSERT_STRING(deflate_state * const s,uint32_t str,uint32_t count)88 Z_INTERNAL void INSERT_STRING(deflate_state *const s, uint32_t str, uint32_t count) {
89 uint8_t *strstart = s->window + str + HASH_CALC_OFFSET;
90 uint8_t *strend = strstart + count;
91
92 for (Pos idx = (Pos)str; strstart < strend; idx++, strstart++) {
93 uint32_t val, hm;
94
95 HASH_CALC_VAR_INIT;
96 HASH_CALC_READ;
97 HASH_CALC(s, HASH_CALC_VAR, val);
98 HASH_CALC_VAR &= HASH_CALC_MASK;
99 hm = HASH_CALC_VAR;
100
101 Pos head = s->head[hm];
102 if (LIKELY(head != idx)) {
103 s->prev[idx & s->w_mask] = head;
104 s->head[hm] = idx;
105 }
106 }
107 }
108 #endif
109