4 #include "huff_codes.h"
7 extern const struct isal_hufftables hufftables_default
;
9 static inline void update_state(struct isal_zstream
*stream
, uint8_t * start_in
,
10 uint8_t * next_in
, uint8_t * end_in
)
12 struct isal_zstate
*state
= &stream
->internal_state
;
13 uint32_t bytes_written
;
15 if (next_in
- start_in
> 0)
16 state
->has_hist
= IGZIP_HIST
;
18 stream
->next_in
= next_in
;
19 stream
->total_in
+= next_in
- start_in
;
20 stream
->avail_in
= end_in
- next_in
;
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
;
29 void isal_deflate_body_base(struct isal_zstream
*stream
)
31 uint32_t literal
, hash
;
32 uint8_t *start_in
, *next_in
, *end_in
, *end
, *next_hash
;
33 uint16_t match_length
;
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
;
42 if (stream
->avail_in
== 0) {
43 if (stream
->end_of_stream
|| stream
->flush
!= NO_FLUSH
)
44 state
->state
= ZSTATE_FLUSH_READ_BUFFER
;
48 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
50 start_in
= stream
->next_in
;
51 end_in
= start_in
+ stream
->avail_in
;
54 while (next_in
+ ISAL_LOOK_AHEAD
< end_in
) {
56 if (is_full(&state
->bitbuf
)) {
57 update_state(stream
, start_in
, next_in
, end_in
);
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
);
66 /* The -1 are to handle the case when dist = 0 */
67 if (dist
- 1 < hist_size
) {
70 match_length
= compare258(next_in
- dist
, next_in
, 258);
72 if (match_length
>= SHORTEST_MATCH
) {
74 #ifdef ISAL_LIMIT_HASH_UPDATE
77 end
= next_hash
+ match_length
;
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
);
87 get_len_code(stream
->hufftables
, match_length
, &code
,
89 get_dist_code(stream
->hufftables
, dist
, &code2
, &code_len2
);
91 code
|= code2
<< code_len
;
92 code_len
+= code_len2
;
94 write_bits(&state
->bitbuf
, code
, code_len
);
96 next_in
+= match_length
;
102 get_lit_code(stream
->hufftables
, literal
& 0xFF, &code
, &code_len
);
103 write_bits(&state
->bitbuf
, code
, code_len
);
107 update_state(stream
, start_in
, next_in
, end_in
);
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
;
117 void isal_deflate_finish_base(struct isal_zstream
*stream
)
119 uint32_t literal
= 0, hash
;
120 uint8_t *start_in
, *next_in
, *end_in
, *end
, *next_hash
;
121 uint16_t match_length
;
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
;
130 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
132 start_in
= stream
->next_in
;
133 end_in
= start_in
+ stream
->avail_in
;
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
);
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
);
148 if (dist
- 1 < hist_size
) { /* The -1 are to handle the case when dist = 0 */
150 compare258(next_in
- dist
, next_in
, end_in
- next_in
);
152 if (match_length
>= SHORTEST_MATCH
) {
154 #ifdef ISAL_LIMIT_HASH_UPDATE
157 end
= next_hash
+ match_length
;
161 for (; next_hash
< end
- 3; next_hash
++) {
162 literal
= load_u32(next_hash
);
163 hash
= compute_hash(literal
) & hash_mask
;
165 (uint64_t) (next_hash
- file_start
);
168 get_len_code(stream
->hufftables
, match_length
, &code
,
170 get_dist_code(stream
->hufftables
, dist
, &code2
,
173 code
|= code2
<< code_len
;
174 code_len
+= code_len2
;
176 write_bits(&state
->bitbuf
, code
, code_len
);
178 next_in
+= match_length
;
184 get_lit_code(stream
->hufftables
, literal
& 0xFF, &code
, &code_len
);
185 write_bits(&state
->bitbuf
, code
, code_len
);
190 while (next_in
< end_in
) {
191 if (is_full(&state
->bitbuf
)) {
192 update_state(stream
, start_in
, next_in
, end_in
);
197 get_lit_code(stream
->hufftables
, literal
& 0xFF, &code
, &code_len
);
198 write_bits(&state
->bitbuf
, code
, code_len
);
204 if (!is_full(&state
->bitbuf
)) {
205 get_lit_code(stream
->hufftables
, 256, &code
, &code_len
);
206 write_bits(&state
->bitbuf
, code
, code_len
);
209 if (stream
->end_of_stream
== 1)
210 state
->state
= ZSTATE_TRL
;
212 state
->state
= ZSTATE_SYNC_FLUSH
;
215 update_state(stream
, start_in
, next_in
, end_in
);
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
)
223 uint8_t *next_in
= dict
;
224 uint8_t *end_in
= dict
+ dict_len
- SHORTEST_MATCH
;
227 uint16_t index
= current_index
- dict_len
;
229 while (next_in
<= end_in
) {
230 literal
= load_u32(next_in
);
231 hash
= compute_hash(literal
) & hash_mask
;
232 hash_table
[hash
] = index
;