]> git.proxmox.com Git - ceph.git/blob - ceph/src/isa-l/igzip/igzip_stateless_base.c
63fa578665b7f13570eaaa0ff78df26dbe1ca6e7
[ceph.git] / ceph / src / isa-l / igzip / igzip_stateless_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 static inline void update_state(struct isal_zstream *stream, struct isal_zstate *state,
8 uint8_t * end_in, uint8_t * start_in)
9 {
10 uint32_t count;
11 stream->avail_in = end_in - stream->next_in;
12 stream->total_in += stream->next_in - start_in;
13 count = buffer_used(&state->bitbuf);
14 stream->next_out = buffer_ptr(&state->bitbuf);
15 stream->avail_out -= count;
16 stream->total_out += count;
17
18 }
19
20 void isal_deflate_body_stateless_base(struct isal_zstream *stream)
21 {
22 uint32_t literal = 0, hash;
23 uint8_t *start_in, *end_in, *end, *next_hash;
24 uint16_t match_length;
25 uint32_t dist;
26 uint64_t code, code_len, code2, code_len2, i;
27 struct isal_zstate *state = &stream->internal_state;
28 uint16_t *last_seen = state->head;
29
30 if (stream->avail_in == 0)
31 return;
32
33 set_buf(&state->bitbuf, stream->next_out, stream->avail_out);
34 start_in = stream->next_in;
35 end_in = stream->next_in + stream->avail_in;
36
37 while (stream->next_in < end_in - 3) {
38 if (is_full(&state->bitbuf)) {
39 update_state(stream, state, end_in, start_in);
40 return;
41 }
42
43 literal = *(uint32_t *) stream->next_in;
44 hash = compute_hash(literal) & HASH_MASK;
45 dist = (uint64_t) (stream->next_in - last_seen[hash]) & 0xFFFF;
46 last_seen[hash] = (uint64_t) stream->next_in;
47
48 if (dist - 1 < IGZIP_D - 1 && stream->next_in - dist >= start_in) { /* The -1 are to handle the case when dist = 0 */
49 match_length =
50 compare258(stream->next_in - dist, stream->next_in,
51 end_in - stream->next_in);
52
53 if (match_length >= SHORTEST_MATCH) {
54 next_hash = stream->next_in;
55 #ifdef LIMIT_HASH_UPDATE
56 end = next_hash + 3;
57 #else
58 end = next_hash + match_length;
59 #endif
60 if (end > end_in - 3)
61 end = end_in - 3;
62 next_hash++;
63 for (; next_hash < end; next_hash++) {
64 literal = *(uint32_t *) next_hash;
65 hash = compute_hash(literal) & HASH_MASK;
66 last_seen[hash] = (uint64_t) next_hash;
67 }
68
69 get_len_code(stream->hufftables, match_length, &code,
70 &code_len);
71 get_dist_code(stream->hufftables, dist, &code2, &code_len2);
72
73 code |= code2 << code_len;
74 code_len += code_len2;
75
76 write_bits(&state->bitbuf, code, code_len);
77
78 stream->next_in += match_length;
79
80 continue;
81 }
82 }
83
84 get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len);
85 write_bits(&state->bitbuf, code, code_len);
86 stream->next_in++;
87 }
88
89 if (is_full(&state->bitbuf)) {
90 update_state(stream, state, end_in, start_in);
91 return;
92 }
93
94 literal = *(uint32_t *) (end_in - 4);
95
96 for (i = 4; i > end_in - stream->next_in; i--)
97 literal = literal >> 8;
98
99 hash = compute_hash(literal) & HASH_MASK;
100 dist = (uint64_t) (stream->next_in - last_seen[hash]) & 0xFFFF;
101
102 if (dist - 1 < IGZIP_D - 1 && stream->next_in - dist >= start_in) {
103 match_length =
104 compare258(stream->next_in - dist, stream->next_in,
105 end_in - stream->next_in);
106 if (match_length >= SHORTEST_MATCH) {
107 get_len_code(stream->hufftables, match_length, &code, &code_len);
108 get_dist_code(stream->hufftables, dist, &code2, &code_len2);
109 code |= code2 << code_len;
110 code_len += code_len2;
111 write_bits(&state->bitbuf, code, code_len);
112 stream->next_in += 3;
113
114 if (is_full(&state->bitbuf)) {
115 update_state(stream, state, end_in, start_in);
116 return;
117 }
118
119 get_lit_code(stream->hufftables, 256, &code, &code_len);
120 write_bits(&state->bitbuf, code, code_len);
121
122 if (is_full(&state->bitbuf)) {
123 update_state(stream, state, end_in, start_in);
124 return;
125 }
126
127 state->has_eob = 1;
128 update_state(stream, state, end_in, start_in);
129 return;
130 }
131 }
132
133 while (stream->next_in < end_in) {
134 get_lit_code(stream->hufftables, literal & 0xFF, &code, &code_len);
135 write_bits(&state->bitbuf, code, code_len);
136 stream->next_in++;
137
138 if (is_full(&state->bitbuf)) {
139 update_state(stream, state, end_in, start_in);
140 return;
141 }
142 literal >>= 8;
143 }
144
145 get_lit_code(stream->hufftables, 256, &code, &code_len);
146 write_bits(&state->bitbuf, code, code_len);
147
148 state->has_eob = 1;
149 update_state(stream, state, end_in, start_in);
150 return;
151 }