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 stream
->next_in
= next_in
;
16 stream
->total_in
+= next_in
- start_in
;
17 stream
->avail_in
= end_in
- next_in
;
19 bytes_written
= buffer_used(&state
->bitbuf
);
20 stream
->total_out
+= bytes_written
;
21 stream
->next_out
+= bytes_written
;
22 stream
->avail_out
-= bytes_written
;
26 void isal_deflate_body_base(struct isal_zstream
*stream
)
28 uint32_t literal
, hash
;
29 uint8_t *start_in
, *next_in
, *end_in
, *end
, *next_hash
;
30 uint16_t match_length
;
32 uint64_t code
, code_len
, code2
, code_len2
;
33 struct isal_zstate
*state
= &stream
->internal_state
;
34 uint16_t *last_seen
= state
->head
;
36 if (stream
->avail_in
== 0) {
37 if (stream
->end_of_stream
|| stream
->flush
!= NO_FLUSH
)
38 state
->state
= ZSTATE_FLUSH_READ_BUFFER
;
42 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
44 start_in
= stream
->next_in
;
45 end_in
= start_in
+ stream
->avail_in
;
48 while (next_in
+ ISAL_LOOK_AHEAD
< end_in
) {
50 if (is_full(&state
->bitbuf
)) {
51 update_state(stream
, start_in
, next_in
, end_in
);
55 literal
= *(uint32_t *) next_in
;
56 hash
= compute_hash(literal
) & HASH_MASK
;
57 dist
= (next_in
- state
->file_start
- last_seen
[hash
]) & 0xFFFF;
58 last_seen
[hash
] = (uint64_t) (next_in
- state
->file_start
);
60 /* The -1 are to handle the case when dist = 0 */
61 if (dist
- 1 < IGZIP_HIST_SIZE
- 1) {
64 match_length
= compare258(next_in
- dist
, next_in
, 258);
66 if (match_length
>= SHORTEST_MATCH
) {
68 #ifdef ISAL_LIMIT_HASH_UPDATE
71 end
= next_hash
+ match_length
;
75 for (; next_hash
< end
; next_hash
++) {
76 literal
= *(uint32_t *) next_hash
;
77 hash
= compute_hash(literal
) & HASH_MASK
;
79 (uint64_t) (next_hash
- state
->file_start
);
82 get_len_code(stream
->hufftables
, match_length
, &code
,
84 get_dist_code(stream
->hufftables
, dist
, &code2
, &code_len2
);
86 code
|= code2
<< code_len
;
87 code_len
+= code_len2
;
89 write_bits(&state
->bitbuf
, code
, code_len
);
91 next_in
+= match_length
;
97 get_lit_code(stream
->hufftables
, literal
& 0xFF, &code
, &code_len
);
98 write_bits(&state
->bitbuf
, code
, code_len
);
102 update_state(stream
, start_in
, next_in
, end_in
);
104 assert(stream
->avail_in
<= ISAL_LOOK_AHEAD
);
105 if (stream
->end_of_stream
|| stream
->flush
!= NO_FLUSH
)
106 state
->state
= ZSTATE_FLUSH_READ_BUFFER
;
112 void isal_deflate_finish_base(struct isal_zstream
*stream
)
114 uint32_t literal
= 0, hash
;
115 uint8_t *start_in
, *next_in
, *end_in
, *end
, *next_hash
;
116 uint16_t match_length
;
118 uint64_t code
, code_len
, code2
, code_len2
;
119 struct isal_zstate
*state
= &stream
->internal_state
;
120 uint16_t *last_seen
= state
->head
;
122 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
124 start_in
= stream
->next_in
;
125 end_in
= start_in
+ stream
->avail_in
;
128 if (stream
->avail_in
!= 0) {
129 while (next_in
+ 3 < end_in
) {
130 if (is_full(&state
->bitbuf
)) {
131 update_state(stream
, start_in
, next_in
, end_in
);
135 literal
= *(uint32_t *) next_in
;
136 hash
= compute_hash(literal
) & HASH_MASK
;
137 dist
= (next_in
- state
->file_start
- last_seen
[hash
]) & 0xFFFF;
138 last_seen
[hash
] = (uint64_t) (next_in
- state
->file_start
);
140 if (dist
- 1 < IGZIP_HIST_SIZE
- 1) { /* The -1 are to handle the case when dist = 0 */
142 compare258(next_in
- dist
, next_in
, end_in
- next_in
);
144 if (match_length
>= SHORTEST_MATCH
) {
146 #ifdef ISAL_LIMIT_HASH_UPDATE
149 end
= next_hash
+ match_length
;
153 for (; next_hash
< end
- 3; next_hash
++) {
154 literal
= *(uint32_t *) next_hash
;
155 hash
= compute_hash(literal
) & HASH_MASK
;
157 (uint64_t) (next_hash
- state
->file_start
);
160 get_len_code(stream
->hufftables
, match_length
, &code
,
162 get_dist_code(stream
->hufftables
, dist
, &code2
,
165 code
|= code2
<< code_len
;
166 code_len
+= code_len2
;
168 write_bits(&state
->bitbuf
, code
, code_len
);
170 next_in
+= match_length
;
176 get_lit_code(stream
->hufftables
, literal
& 0xFF, &code
, &code_len
);
177 write_bits(&state
->bitbuf
, code
, code_len
);
182 while (next_in
< end_in
) {
183 if (is_full(&state
->bitbuf
)) {
184 update_state(stream
, start_in
, next_in
, end_in
);
189 get_lit_code(stream
->hufftables
, literal
& 0xFF, &code
, &code_len
);
190 write_bits(&state
->bitbuf
, code
, code_len
);
196 if (!is_full(&state
->bitbuf
)) {
197 get_lit_code(stream
->hufftables
, 256, &code
, &code_len
);
198 write_bits(&state
->bitbuf
, code
, code_len
);
201 if (stream
->end_of_stream
== 1)
202 state
->state
= ZSTATE_TRL
;
204 state
->state
= ZSTATE_SYNC_FLUSH
;
207 update_state(stream
, start_in
, next_in
, end_in
);