4 #include "huff_codes.h"
7 extern const struct isal_hufftables hufftables_default
;
9 void isal_deflate_init_base(struct isal_zstream
*stream
)
11 struct isal_zstate
*state
= &stream
->internal_state
;
14 uint32_t *crc
= state
->crc
;
17 stream
->total_out
= 0;
18 stream
->hufftables
= (struct isal_hufftables
*)&hufftables_default
;
20 state
->b_bytes_valid
= 0;
21 state
->b_bytes_processed
= 0;
23 state
->has_eob_hdr
= 0;
25 state
->last_flush
= 0;
26 state
->has_gzip_hdr
= 0;
27 state
->state
= ZSTATE_NEW_HDR
;
30 state
->tmp_out_start
= 0;
31 state
->tmp_out_end
= 0;
33 state
->file_start
= state
->buffer
;
39 for (i
= 0; i
< HASH_SIZE
; i
++)
40 state
->head
[i
] = (uint16_t) - (IGZIP_D
+ 1);
44 uint32_t get_crc_base(uint32_t * crc
)
49 static inline void update_state(struct isal_zstream
*stream
, struct isal_zstate
*state
,
52 uint32_t bytes_written
;
54 stream
->total_in
+= stream
->next_in
- start_in
;
56 bytes_written
= buffer_used(&state
->bitbuf
);
57 stream
->total_out
+= bytes_written
;
58 stream
->next_out
+= bytes_written
;
59 stream
->avail_out
-= bytes_written
;
63 void isal_deflate_body_base(struct isal_zstream
*stream
)
65 uint32_t literal
, hash
;
66 uint8_t *start_in
, *next_in
, *end_in
, *end
, *next_hash
;
67 uint16_t match_length
;
68 uint32_t dist
, bytes_to_buffer
, offset
;
69 uint64_t code
, code_len
, code2
, code_len2
;
70 struct isal_zstate
*state
= &stream
->internal_state
;
71 uint16_t *last_seen
= state
->head
;
72 uint32_t *crc
= state
->crc
;
74 if (stream
->avail_in
== 0) {
75 if (stream
->end_of_stream
|| stream
->flush
!= NO_FLUSH
)
76 state
->state
= ZSTATE_FLUSH_READ_BUFFER
;
80 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
81 start_in
= stream
->next_in
;
83 while (stream
->avail_in
!= 0) {
85 IGZIP_D
+ IGZIP_LA
- (state
->b_bytes_valid
- state
->b_bytes_processed
);
87 if (bytes_to_buffer
> IGZIP_D
)
88 bytes_to_buffer
= IGZIP_D
;
90 if (stream
->avail_in
< IGZIP_D
)
91 bytes_to_buffer
= stream
->avail_in
;
93 if (bytes_to_buffer
> BSIZE
- state
->b_bytes_valid
) {
94 if (state
->b_bytes_valid
- state
->b_bytes_processed
> IGZIP_LA
) {
95 /* There was an out buffer overflow last round,
96 * complete the processing of data */
100 /* Not enough room in the buffer, shift the
101 * buffer down to make space for the new data */
102 offset
= state
->b_bytes_processed
- IGZIP_D
; // state->b_bytes_valid - (IGZIP_D + IGZIP_LA);
103 memmove(state
->buffer
, state
->buffer
+ offset
,
106 state
->b_bytes_processed
-= offset
;
107 state
->b_bytes_valid
-= offset
;
108 state
->file_start
-= offset
;
110 stream
->avail_in
-= bytes_to_buffer
;
111 memcpy(state
->buffer
+ state
->b_bytes_valid
, stream
->next_in
,
113 update_crc(crc
, stream
->next_in
, bytes_to_buffer
);
114 stream
->next_in
+= bytes_to_buffer
;
117 /* There is enough space in the buffer, copy in the new data */
118 stream
->avail_in
-= bytes_to_buffer
;
119 memcpy(state
->buffer
+ state
->b_bytes_valid
, stream
->next_in
,
121 update_crc(crc
, stream
->next_in
, bytes_to_buffer
);
122 stream
->next_in
+= bytes_to_buffer
;
125 state
->b_bytes_valid
+= bytes_to_buffer
;
127 end_in
= state
->buffer
+ state
->b_bytes_valid
- IGZIP_LA
;
129 next_in
= state
->b_bytes_processed
+ state
->buffer
;
131 while (next_in
< end_in
) {
133 if (is_full(&state
->bitbuf
)) {
134 state
->b_bytes_processed
= next_in
- state
->buffer
;
135 update_state(stream
, state
, start_in
);
139 literal
= *(uint32_t *) next_in
;
140 hash
= compute_hash(literal
) & HASH_MASK
;
141 dist
= (next_in
- state
->file_start
- last_seen
[hash
]) & 0xFFFF;
142 last_seen
[hash
] = (uint64_t) (next_in
- state
->file_start
);
144 if (dist
- 1 < IGZIP_D
- 1) { /* The -1 are to handle the case when dist = 0 */
145 assert(next_in
- dist
>= state
->buffer
);
148 match_length
= compare258(next_in
- dist
, next_in
, 258);
150 if (match_length
>= SHORTEST_MATCH
) {
152 #ifdef LIMIT_HASH_UPDATE
155 end
= next_hash
+ match_length
;
159 for (; next_hash
< end
; next_hash
++) {
160 literal
= *(uint32_t *) next_hash
;
161 hash
= compute_hash(literal
) & HASH_MASK
;
163 (uint64_t) (next_hash
- state
->file_start
);
166 get_len_code(stream
->hufftables
, match_length
, &code
,
168 get_dist_code(stream
->hufftables
, dist
, &code2
,
171 code
|= code2
<< code_len
;
172 code_len
+= code_len2
;
174 write_bits(&state
->bitbuf
, code
, code_len
);
176 next_in
+= match_length
;
182 get_lit_code(stream
->hufftables
, literal
& 0xFF, &code
, &code_len
);
183 write_bits(&state
->bitbuf
, code
, code_len
);
187 state
->b_bytes_processed
= next_in
- state
->buffer
;
191 update_state(stream
, state
, start_in
);
193 if (stream
->avail_in
== 0) {
194 if (stream
->end_of_stream
|| stream
->flush
!= NO_FLUSH
)
195 state
->state
= ZSTATE_FLUSH_READ_BUFFER
;
203 void isal_deflate_finish_base(struct isal_zstream
*stream
)
205 uint32_t literal
= 0, hash
;
206 uint8_t *next_in
, *end_in
, *end
, *next_hash
;
207 uint16_t match_length
;
209 uint64_t code
, code_len
, code2
, code_len2
;
210 struct isal_zstate
*state
= &stream
->internal_state
;
211 uint16_t *last_seen
= state
->head
;
213 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
215 end_in
= state
->b_bytes_valid
+ (uint8_t *) state
->buffer
;
217 next_in
= state
->b_bytes_processed
+ state
->buffer
;
219 while (next_in
< end_in
) {
221 if (is_full(&state
->bitbuf
)) {
222 state
->b_bytes_processed
= next_in
- state
->buffer
;
223 update_state(stream
, state
, stream
->next_in
);
227 literal
= *(uint32_t *) next_in
;
228 hash
= compute_hash(literal
) & HASH_MASK
;
229 dist
= (next_in
- state
->file_start
- last_seen
[hash
]) & 0xFFFF;
230 last_seen
[hash
] = (uint64_t) (next_in
- state
->file_start
);
232 if (dist
- 1 < IGZIP_D
- 1) { /* The -1 are to handle the case when dist = 0 */
233 assert(next_in
- dist
>= state
->buffer
);
234 match_length
= compare258(next_in
- dist
, next_in
, end_in
- next_in
);
236 if (match_length
>= SHORTEST_MATCH
) {
238 #ifdef LIMIT_HASH_UPDATE
241 end
= next_hash
+ match_length
;
245 for (; next_hash
< end
; next_hash
++) {
246 literal
= *(uint32_t *) next_hash
;
247 hash
= compute_hash(literal
) & HASH_MASK
;
249 (uint64_t) (next_hash
- state
->file_start
);
252 get_len_code(stream
->hufftables
, match_length
, &code
,
254 get_dist_code(stream
->hufftables
, dist
, &code2
, &code_len2
);
256 code
|= code2
<< code_len
;
257 code_len
+= code_len2
;
259 write_bits(&state
->bitbuf
, code
, code_len
);
261 next_in
+= match_length
;
267 get_lit_code(stream
->hufftables
, literal
& 0xFF, &code
, &code_len
);
268 write_bits(&state
->bitbuf
, code
, code_len
);
273 state
->b_bytes_processed
= next_in
- state
->buffer
;
275 if (is_full(&state
->bitbuf
) || state
->left_over
> 0) {
276 update_state(stream
, state
, stream
->next_in
);
280 get_lit_code(stream
->hufftables
, 256, &code
, &code_len
);
281 write_bits(&state
->bitbuf
, code
, code_len
);
284 update_state(stream
, state
, stream
->next_in
);
286 if (stream
->end_of_stream
== 1)
287 state
->state
= ZSTATE_TRL
;
289 state
->state
= ZSTATE_SYNC_FLUSH
;