]> git.proxmox.com Git - ceph.git/blob - ceph/src/isa-l/igzip/igzip_base.c
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / isa-l / igzip / igzip_base.c
1 #include <stdint.h>
2 #include "igzip_lib.h"
3 #include "huffman.h"
4 #include "huff_codes.h"
5 #include "bitbuf2.h"
6
7 extern const struct isal_hufftables hufftables_default;
8
9 static inline void update_state(struct isal_zstream *stream, uint8_t * start_in,
10 uint8_t * next_in, uint8_t * end_in)
11 {
12 struct isal_zstate *state = &stream->internal_state;
13 uint32_t bytes_written;
14
15 if (next_in - start_in > 0)
16 state->has_hist = IGZIP_HIST;
17
18 stream->next_in = next_in;
19 stream->total_in += next_in - start_in;
20 stream->avail_in = end_in - next_in;
21
22 bytes_written = buffer_used(&state->bitbuf);
23 stream->total_out += bytes_written;
24 stream->next_out += bytes_written;
25 stream->avail_out -= bytes_written;
26
27 }
28
29 void isal_deflate_body_base(struct isal_zstream *stream)
30 {
31 uint32_t literal, hash;
32 uint8_t *start_in, *next_in, *end_in, *end, *next_hash;
33 uint16_t match_length;
34 uint32_t dist;
35 uint64_t code, code_len, code2, code_len2;
36 struct isal_zstate *state = &stream->internal_state;
37 uint16_t *last_seen = state->head;
38 uint8_t *file_start = (uint8_t *) ((uintptr_t) stream->next_in - stream->total_in);
39 uint32_t hist_size = state->dist_mask;
40 uint32_t hash_mask = state->hash_mask;
41
42 if (stream->avail_in == 0) {
43 if (stream->end_of_stream || stream->flush != NO_FLUSH)
44 state->state = ZSTATE_FLUSH_READ_BUFFER;
45 return;
46 }
47
48 set_buf(&state->bitbuf, stream->next_out, stream->avail_out);
49
50 start_in = stream->next_in;
51 end_in = start_in + stream->avail_in;
52 next_in = start_in;
53
54 while (next_in + ISAL_LOOK_AHEAD < end_in) {
55
56 if (is_full(&state->bitbuf)) {
57 update_state(stream, start_in, next_in, end_in);
58 return;
59 }
60
61 literal = load_u32(next_in);
62 hash = compute_hash(literal) & hash_mask;
63 dist = (next_in - file_start - last_seen[hash]) & 0xFFFF;
64 last_seen[hash] = (uint64_t) (next_in - file_start);
65
66 /* The -1 are to handle the case when dist = 0 */
67 if (dist - 1 < hist_size) {
68 assert(dist != 0);
69
70 match_length = compare258(next_in - dist, next_in, 258);
71
72 if (match_length >= SHORTEST_MATCH) {
73 next_hash = next_in;
74 #ifdef ISAL_LIMIT_HASH_UPDATE
75 end = next_hash + 3;
76 #else
77 end = next_hash + match_length;
78 #endif
79 next_hash++;
80
81 for (; next_hash < end; next_hash++) {
82 literal = load_u32(next_hash);
83 hash = compute_hash(literal) & hash_mask;
84 last_seen[hash] = (uint64_t) (next_hash - file_start);
85 }
86
87 get_len_code(stream->hufftables, match_length, &code,
88 &code_len);
89 get_dist_code(stream->hufftables, dist, &code2, &code_len2);
90
91 code |= code2 << code_len;
92 code_len += code_len2;
93
94 write_bits(&state->bitbuf, code, code_len);
95
96 next_in += match_length;
97
98 continue;
99 }
100 }
101
102 get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len);
103 write_bits(&state->bitbuf, code, code_len);
104 next_in++;
105 }
106
107 update_state(stream, start_in, next_in, end_in);
108
109 assert(stream->avail_in <= ISAL_LOOK_AHEAD);
110 if (stream->end_of_stream || stream->flush != NO_FLUSH)
111 state->state = ZSTATE_FLUSH_READ_BUFFER;
112
113 return;
114
115 }
116
117 void isal_deflate_finish_base(struct isal_zstream *stream)
118 {
119 uint32_t literal = 0, hash;
120 uint8_t *start_in, *next_in, *end_in, *end, *next_hash;
121 uint16_t match_length;
122 uint32_t dist;
123 uint64_t code, code_len, code2, code_len2;
124 struct isal_zstate *state = &stream->internal_state;
125 uint16_t *last_seen = state->head;
126 uint8_t *file_start = (uint8_t *) ((uintptr_t) stream->next_in - stream->total_in);
127 uint32_t hist_size = state->dist_mask;
128 uint32_t hash_mask = state->hash_mask;
129
130 set_buf(&state->bitbuf, stream->next_out, stream->avail_out);
131
132 start_in = stream->next_in;
133 end_in = start_in + stream->avail_in;
134 next_in = start_in;
135
136 if (stream->avail_in != 0) {
137 while (next_in + 3 < end_in) {
138 if (is_full(&state->bitbuf)) {
139 update_state(stream, start_in, next_in, end_in);
140 return;
141 }
142
143 literal = load_u32(next_in);
144 hash = compute_hash(literal) & hash_mask;
145 dist = (next_in - file_start - last_seen[hash]) & 0xFFFF;
146 last_seen[hash] = (uint64_t) (next_in - file_start);
147
148 if (dist - 1 < hist_size) { /* The -1 are to handle the case when dist = 0 */
149 match_length =
150 compare258(next_in - dist, next_in, end_in - next_in);
151
152 if (match_length >= SHORTEST_MATCH) {
153 next_hash = next_in;
154 #ifdef ISAL_LIMIT_HASH_UPDATE
155 end = next_hash + 3;
156 #else
157 end = next_hash + match_length;
158 #endif
159 next_hash++;
160
161 for (; next_hash < end - 3; next_hash++) {
162 literal = load_u32(next_hash);
163 hash = compute_hash(literal) & hash_mask;
164 last_seen[hash] =
165 (uint64_t) (next_hash - file_start);
166 }
167
168 get_len_code(stream->hufftables, match_length, &code,
169 &code_len);
170 get_dist_code(stream->hufftables, dist, &code2,
171 &code_len2);
172
173 code |= code2 << code_len;
174 code_len += code_len2;
175
176 write_bits(&state->bitbuf, code, code_len);
177
178 next_in += match_length;
179
180 continue;
181 }
182 }
183
184 get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len);
185 write_bits(&state->bitbuf, code, code_len);
186 next_in++;
187
188 }
189
190 while (next_in < end_in) {
191 if (is_full(&state->bitbuf)) {
192 update_state(stream, start_in, next_in, end_in);
193 return;
194 }
195
196 literal = *next_in;
197 get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len);
198 write_bits(&state->bitbuf, code, code_len);
199 next_in++;
200
201 }
202 }
203
204 if (!is_full(&state->bitbuf)) {
205 get_lit_code(stream->hufftables, 256, &code, &code_len);
206 write_bits(&state->bitbuf, code, code_len);
207 state->has_eob = 1;
208
209 if (stream->end_of_stream == 1)
210 state->state = ZSTATE_TRL;
211 else
212 state->state = ZSTATE_SYNC_FLUSH;
213 }
214
215 update_state(stream, start_in, next_in, end_in);
216
217 return;
218 }
219
220 void isal_deflate_hash_base(uint16_t * hash_table, uint32_t hash_mask,
221 uint32_t current_index, uint8_t * dict, uint32_t dict_len)
222 {
223 uint8_t *next_in = dict;
224 uint8_t *end_in = dict + dict_len - SHORTEST_MATCH;
225 uint32_t literal;
226 uint32_t hash;
227 uint16_t index = current_index - dict_len;
228
229 while (next_in <= end_in) {
230 literal = load_u32(next_in);
231 hash = compute_hash(literal) & hash_mask;
232 hash_table[hash] = index;
233 index++;
234 next_in++;
235 }
236 }