1 /**********************************************************************
2 Copyright(c) 2011-2016 Intel Corporation All rights reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 **********************************************************************/
38 #ifndef IGZIP_USE_GZIP_FORMAT
42 #define MAX_WRITE_BITS_SIZE 8
43 #define FORCE_FLUSH 64
44 #define MIN_OBUF_SIZE 224
45 #define NON_EMPTY_BLOCK_SIZE 6
46 #define MAX_SYNC_FLUSH_SIZE NON_EMPTY_BLOCK_SIZE + MAX_WRITE_BITS_SIZE
50 #include "igzip_lib.h"
51 #include "repeated_char_result.h"
53 extern const uint8_t gzip_hdr
[];
54 extern const uint32_t gzip_hdr_bytes
;
55 extern const uint32_t gzip_trl_bytes
;
56 extern const struct isal_hufftables hufftables_default
;
58 extern uint32_t crc32_gzip(uint32_t init_crc
, const unsigned char *buf
, uint64_t len
);
60 static int write_stored_block_stateless(struct isal_zstream
*stream
, uint32_t stored_len
,
63 static int write_gzip_header_stateless(struct isal_zstream
*stream
);
65 static int write_deflate_header_stateless(struct isal_zstream
*stream
);
66 static int write_deflate_header_unaligned_stateless(struct isal_zstream
*stream
);
67 static int write_trailer_stateless(struct isal_zstream
*stream
, uint32_t avail_in
,
70 void isal_deflate_body_stateless(struct isal_zstream
*stream
);
72 unsigned int detect_repeated_char(uint8_t * buf
, uint32_t size
);
74 #define STORED_BLK_HDR_BZ 5
75 #define STORED_BLK_MAX_BZ 65535
77 void isal_deflate_body(struct isal_zstream
*stream
);
78 void isal_deflate_finish(struct isal_zstream
*stream
);
79 uint32_t crc_512to32_01(uint32_t * crc
);
80 uint32_t get_crc(uint32_t * crc
);
82 /*****************************************************************/
84 /* Forward declarations */
85 static inline void reset_match_history(struct isal_zstream
*stream
);
86 void write_header(struct isal_zstream
*stream
);
87 void write_deflate_header(struct isal_zstream
*stream
);
88 void write_trailer(struct isal_zstream
*stream
);
97 struct slver isal_deflate_init_slver_01030081
;
98 struct slver isal_deflate_init_slver
= { 0x0081, 0x03, 0x01 };
100 struct slver isal_deflate_slver_01030082
;
101 struct slver isal_deflate_slver
= { 0x0082, 0x03, 0x01 };
103 struct slver isal_deflate_stateless_slver_01010083
;
104 struct slver isal_deflate_stateless_slver
= { 0x0083, 0x01, 0x01 };
106 /*****************************************************************/
108 uint32_t file_size(struct isal_zstate
*state
)
110 return state
->b_bytes_valid
+ (uint32_t) (state
->buffer
- state
->file_start
);
114 void sync_flush(struct isal_zstream
*stream
)
116 struct isal_zstate
*state
= &stream
->internal_state
;
117 uint64_t bits_to_write
= 0xFFFF0000, bits_len
;
118 uint64_t code
= 0, len
= 0, bytes
;
121 if (stream
->avail_out
>= 8) {
122 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
125 get_lit_code(stream
->hufftables
, 256, &code
, &len
);
127 flush_size
= (-(state
->bitbuf
.m_bit_count
+ len
+ 3)) % 8;
129 bits_to_write
<<= flush_size
+ 3;
130 bits_len
= 32 + len
+ flush_size
+ 3;
132 #ifdef USE_BITBUFB /* Write Bits Always */
133 state
->state
= ZSTATE_NEW_HDR
;
134 #else /* Not Write Bits Always */
135 state
->state
= ZSTATE_FLUSH_WRITE_BUFFER
;
140 bits_to_write
= (bits_to_write
<< len
) | code
;
142 write_bits(&state
->bitbuf
, bits_to_write
, bits_len
);
144 bytes
= buffer_used(&state
->bitbuf
);
145 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
146 stream
->avail_out
-= bytes
;
147 stream
->total_out
+= bytes
;
149 if (stream
->flush
== FULL_FLUSH
) {
150 /* Clear match history so there are no cross
151 * block length distance pairs */
152 reset_match_history(stream
);
157 static void flush_write_buffer(struct isal_zstream
*stream
)
159 struct isal_zstate
*state
= &stream
->internal_state
;
161 if (stream
->avail_out
>= 8) {
162 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
163 flush(&state
->bitbuf
);
164 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
165 bytes
= buffer_used(&state
->bitbuf
);
166 stream
->avail_out
-= bytes
;
167 stream
->total_out
+= bytes
;
168 state
->state
= ZSTATE_NEW_HDR
;
172 static void isal_deflate_int(struct isal_zstream
*stream
)
174 struct isal_zstate
*state
= &stream
->internal_state
;
175 if (state
->state
== ZSTATE_NEW_HDR
|| state
->state
== ZSTATE_HDR
)
176 write_header(stream
);
178 if (state
->state
== ZSTATE_BODY
)
179 isal_deflate_body(stream
);
181 if (state
->state
== ZSTATE_FLUSH_READ_BUFFER
)
182 isal_deflate_finish(stream
);
184 if (state
->state
== ZSTATE_SYNC_FLUSH
)
187 if (state
->state
== ZSTATE_FLUSH_WRITE_BUFFER
)
188 flush_write_buffer(stream
);
190 if (state
->state
== ZSTATE_TRL
)
191 write_trailer(stream
);
194 static uint32_t write_constant_compressed_stateless(struct isal_zstream
*stream
,
195 uint32_t repeated_char
,
196 uint32_t repeated_length
,
197 uint32_t end_of_stream
)
199 /* Assumes repeated_length is at least 1.
200 * Assumes the input end_of_stream is either 0 or 1. */
201 struct isal_zstate
*state
= &stream
->internal_state
;
202 uint32_t rep_bits
= ((repeated_length
- 1) / 258) * 2;
203 uint32_t rep_bytes
= rep_bits
/ 8;
204 uint32_t rep_extra
= (repeated_length
- 1) % 258;
207 /* Guarantee there is enough space for the header even in the worst case */
208 if (stream
->avail_out
< HEADER_LENGTH
+ MAX_FIXUP_CODE_LENGTH
+ rep_bytes
+ 8)
209 return STATELESS_OVERFLOW
;
211 /* Assumes the repeated char is either 0 or 0xFF. */
212 memcpy(stream
->next_out
, repeated_char_header
[repeated_char
& 1], HEADER_LENGTH
);
214 if (end_of_stream
> 0)
215 stream
->next_out
[0] |= 1;
217 memset(stream
->next_out
+ HEADER_LENGTH
, 0, rep_bytes
);
218 stream
->avail_out
-= HEADER_LENGTH
+ rep_bytes
;
219 stream
->next_out
+= HEADER_LENGTH
+ rep_bytes
;
220 stream
->total_out
+= HEADER_LENGTH
+ rep_bytes
;
222 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
224 /* These two lines are basically a modified version of init. */
225 state
->bitbuf
.m_bits
= 0;
226 state
->bitbuf
.m_bit_count
= rep_bits
% 8;
228 /* Add smaller repeat codes as necessary. Code280 can describe repeat
229 * lengths of 115-130 bits. Code10 can describe repeat lengths of 10
230 * bits. If more than 230 bits, fill code with two code280s. Else if
231 * more than 115 repeates, fill with code10s until one code280 can
232 * finish the rest of the repeats. Else, fill with code10s and
234 if (rep_extra
> 115) {
235 while (rep_extra
> 130 && rep_extra
< 230) {
236 write_bits(&state
->bitbuf
, CODE_10
, CODE_10_LENGTH
);
240 if (rep_extra
>= 230) {
241 write_bits(&state
->bitbuf
,
242 CODE_280
| ((rep_extra
/ 2 - 115) << CODE_280_LENGTH
),
243 CODE_280_TOTAL_LENGTH
);
244 rep_extra
-= rep_extra
/ 2;
247 write_bits(&state
->bitbuf
,
248 CODE_280
| ((rep_extra
- 115) << CODE_280_LENGTH
),
249 CODE_280_TOTAL_LENGTH
);
252 while (rep_extra
>= 10) {
254 write_bits(&state
->bitbuf
, CODE_10
, CODE_10_LENGTH
);
258 for (; rep_extra
> 0; rep_extra
--)
259 write_bits(&state
->bitbuf
, CODE_LIT
, CODE_LIT_LENGTH
);
262 write_bits(&state
->bitbuf
, END_OF_BLOCK
, END_OF_BLOCK_LEN
);
264 stream
->next_in
+= repeated_length
;
265 stream
->avail_in
-= repeated_length
;
266 stream
->total_in
+= repeated_length
;
268 bytes
= buffer_used(&state
->bitbuf
);
269 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
270 stream
->avail_out
-= bytes
;
271 stream
->total_out
+= bytes
;
276 int detect_repeated_char_length(uint8_t * in
, uint32_t length
)
278 /* This currently assumes the first 8 bytes are the same character.
279 * This won't work effectively if the input stream isn't aligned well. */
280 uint8_t *p_8
, *end
= in
+ length
;
281 uint64_t *p_64
= (uint64_t *) in
;
283 uint8_t c
= (uint8_t) w
;
285 for (; (p_64
<= (uint64_t *) (end
- 8)) && (w
== *p_64
); p_64
++) ;
287 p_8
= (uint8_t *) p_64
;
289 for (; (p_8
< end
) && (c
== *p_8
); p_8
++) ;
294 static int isal_deflate_int_stateless(struct isal_zstream
*stream
, uint8_t * next_in
,
295 const uint32_t avail_in
)
298 uint32_t repeated_char_length
;
301 if (write_gzip_header_stateless(stream
))
302 return STATELESS_OVERFLOW
;
306 && (*(uint64_t *) stream
->next_in
== 0
307 || *(uint64_t *) stream
->next_in
== ~(uint64_t) 0))
308 repeated_char_length
=
309 detect_repeated_char_length(stream
->next_in
, stream
->avail_in
);
311 repeated_char_length
= 0;
313 if (stream
->avail_in
== repeated_char_length
) {
314 if (write_constant_compressed_stateless(stream
,
316 repeated_char_length
, 1) != COMP_OK
)
317 return STATELESS_OVERFLOW
;
320 crc32
= crc32_gzip(0x0, next_in
, avail_in
);
323 /* write_trailer_stateless is required because if flushes out the last of the output */
324 if (write_trailer_stateless(stream
, avail_in
, crc32
) != COMP_OK
)
325 return STATELESS_OVERFLOW
;
328 } else if (repeated_char_length
>= MIN_REPEAT_LEN
) {
329 if (write_constant_compressed_stateless
330 (stream
, stream
->next_in
[0], repeated_char_length
, 0) != COMP_OK
)
331 return STATELESS_OVERFLOW
;
334 if (write_deflate_header_unaligned_stateless(stream
) != COMP_OK
)
335 return STATELESS_OVERFLOW
;
336 if (stream
->avail_out
< 8)
337 return STATELESS_OVERFLOW
;
339 isal_deflate_body_stateless(stream
);
341 if (!stream
->internal_state
.has_eob
)
342 return STATELESS_OVERFLOW
;
345 crc32
= crc32_gzip(0x0, next_in
, avail_in
);
348 if (write_trailer_stateless(stream
, avail_in
, crc32
) != COMP_OK
)
349 return STATELESS_OVERFLOW
;
354 static int write_stored_block_stateless(struct isal_zstream
*stream
,
355 uint32_t stored_len
, uint32_t crc32
)
357 uint64_t stored_blk_hdr
;
365 if (stream
->avail_out
< stored_len
)
366 return STATELESS_OVERFLOW
;
368 stream
->avail_out
-= stored_len
;
369 stream
->total_out
+= stored_len
;
370 avail_in
= stream
->avail_in
;
373 memcpy(stream
->next_out
, gzip_hdr
, gzip_hdr_bytes
);
374 stream
->next_out
+= gzip_hdr_bytes
;
378 if (avail_in
>= STORED_BLK_MAX_BZ
) {
379 stored_blk_hdr
= 0xFFFF00;
380 copy_size
= STORED_BLK_MAX_BZ
;
382 stored_blk_hdr
= ~avail_in
;
383 stored_blk_hdr
<<= 24;
384 stored_blk_hdr
|= (avail_in
& 0xFFFF) << 8;
385 copy_size
= avail_in
;
388 avail_in
-= copy_size
;
390 /* Handle BFINAL bit */
392 stored_blk_hdr
|= 0x1;
394 memcpy(stream
->next_out
, &stored_blk_hdr
, STORED_BLK_HDR_BZ
);
395 stream
->next_out
+= STORED_BLK_HDR_BZ
;
397 memcpy(stream
->next_out
, stream
->next_in
, copy_size
);
398 stream
->next_out
+= copy_size
;
399 stream
->next_in
+= copy_size
;
400 stream
->total_in
+= copy_size
;
401 } while (avail_in
!= 0);
404 gzip_trl
= stream
->avail_in
;
406 gzip_trl
|= crc32
& 0xFFFFFFFF;
407 memcpy(stream
->next_out
, &gzip_trl
, gzip_trl_bytes
);
408 stream
->next_out
+= gzip_trl_bytes
;
411 stream
->avail_in
= 0;
415 static inline void reset_match_history(struct isal_zstream
*stream
)
417 struct isal_zstate
*state
= &stream
->internal_state
;
418 uint16_t *head
= stream
->internal_state
.head
;
421 for (i
= 0; i
< sizeof(state
->head
) / 2; i
++)
423 (uint16_t) (state
->b_bytes_processed
+ state
->buffer
- state
->file_start
-
427 void isal_deflate_init_01(struct isal_zstream
*stream
)
429 struct isal_zstate
*state
= &stream
->internal_state
;
431 stream
->total_in
= 0;
432 stream
->total_out
= 0;
433 stream
->hufftables
= (struct isal_hufftables
*)&hufftables_default
;
436 state
->b_bytes_valid
= 0;
437 state
->b_bytes_processed
= 0;
439 state
->has_eob_hdr
= 0;
440 state
->left_over
= 0;
441 state
->last_flush
= 0;
442 state
->has_gzip_hdr
= 0;
443 state
->state
= ZSTATE_NEW_HDR
;
446 state
->tmp_out_start
= 0;
447 state
->tmp_out_end
= 0;
449 state
->file_start
= state
->buffer
;
451 init(&state
->bitbuf
);
453 memset(state
->crc
, 0, sizeof(state
->crc
));
454 *state
->crc
= 0x9db42487;
456 reset_match_history(stream
);
461 int isal_deflate_stateless(struct isal_zstream
*stream
)
463 uint8_t *next_in
= stream
->next_in
;
464 const uint32_t avail_in
= stream
->avail_in
;
466 uint8_t *next_out
= stream
->next_out
;
467 const uint32_t avail_out
= stream
->avail_out
;
471 uint32_t dyn_min_len
;
473 uint32_t select_stored_blk
= 0;
476 stored_len
= STORED_BLK_HDR_BZ
;
479 STORED_BLK_HDR_BZ
* ((avail_in
+ STORED_BLK_MAX_BZ
- 1) /
480 STORED_BLK_MAX_BZ
) + avail_in
;
483 at least 1 byte compressed data in the case of empty dynamic block which only
487 dyn_min_len
= stream
->hufftables
->deflate_hdr_count
+ 1;
489 dyn_min_len
+= gzip_hdr_bytes
+ gzip_trl_bytes
+ 1;
490 stored_len
+= gzip_hdr_bytes
+ gzip_trl_bytes
;
493 min_len
= dyn_min_len
;
495 if (stored_len
< dyn_min_len
) {
496 min_len
= stored_len
;
497 select_stored_blk
= 1;
501 the output buffer should be no less than 8 bytes
502 while empty stored deflate block is 5 bytes only
504 if (avail_out
< min_len
|| stream
->avail_out
< 8)
505 return STATELESS_OVERFLOW
;
507 if (!select_stored_blk
) {
508 if (isal_deflate_int_stateless(stream
, next_in
, avail_in
) == COMP_OK
)
511 if (avail_out
< stored_len
)
512 return STATELESS_OVERFLOW
;
514 isal_deflate_init(stream
);
516 stream
->next_in
= next_in
;
517 stream
->avail_in
= avail_in
;
518 stream
->total_in
= 0;
520 stream
->next_out
= next_out
;
521 stream
->avail_out
= avail_out
;
522 stream
->total_out
= 0;
525 crc32
= crc32_gzip(0x0, next_in
, avail_in
);
527 return write_stored_block_stateless(stream
, stored_len
, crc32
);
530 int isal_deflate(struct isal_zstream
*stream
)
532 struct isal_zstate
*state
= &stream
->internal_state
;
536 if (stream
->flush
< 3) {
538 state
->last_flush
= stream
->flush
;
540 if (state
->state
>= TMP_OFFSET_SIZE
) {
541 size
= state
->tmp_out_end
- state
->tmp_out_start
;
542 if (size
> stream
->avail_out
)
543 size
= stream
->avail_out
;
544 memcpy(stream
->next_out
, state
->tmp_out_buff
+ state
->tmp_out_start
,
546 stream
->next_out
+= size
;
547 stream
->avail_out
-= size
;
548 stream
->total_out
+= size
;
549 state
->tmp_out_start
+= size
;
551 if (state
->tmp_out_start
== state
->tmp_out_end
)
552 state
->state
-= TMP_OFFSET_SIZE
;
554 if (stream
->avail_out
== 0 || state
->state
== ZSTATE_END
)
557 assert(state
->tmp_out_start
== state
->tmp_out_end
);
559 isal_deflate_int(stream
);
561 if (stream
->avail_out
== 0)
564 else if (stream
->avail_out
< 8) {
569 next_out
= stream
->next_out
;
570 avail_out
= stream
->avail_out
;
571 total_out
= stream
->total_out
;
573 stream
->next_out
= state
->tmp_out_buff
;
574 stream
->avail_out
= sizeof(state
->tmp_out_buff
);
575 stream
->total_out
= 0;
577 isal_deflate_int(stream
);
579 state
->tmp_out_start
= 0;
580 state
->tmp_out_end
= stream
->total_out
;
582 stream
->next_out
= next_out
;
583 stream
->avail_out
= avail_out
;
584 stream
->total_out
= total_out
;
585 if (state
->tmp_out_end
) {
586 size
= state
->tmp_out_end
;
587 if (size
> stream
->avail_out
)
588 size
= stream
->avail_out
;
589 memcpy(stream
->next_out
, state
->tmp_out_buff
, size
);
590 stream
->next_out
+= size
;
591 stream
->avail_out
-= size
;
592 stream
->total_out
+= size
;
593 state
->tmp_out_start
+= size
;
594 if (state
->tmp_out_start
!= state
->tmp_out_end
)
595 state
->state
+= TMP_OFFSET_SIZE
;
606 static int write_gzip_header_stateless(struct isal_zstream
*stream
)
608 if (gzip_hdr_bytes
>= stream
->avail_out
)
609 return STATELESS_OVERFLOW
;
611 stream
->avail_out
-= gzip_hdr_bytes
;
612 stream
->total_out
+= gzip_hdr_bytes
;
614 memcpy(stream
->next_out
, gzip_hdr
, gzip_hdr_bytes
);
616 stream
->next_out
+= gzip_hdr_bytes
;
621 static void write_gzip_header(struct isal_zstream
*stream
)
623 struct isal_zstate
*state
= &stream
->internal_state
;
624 int bytes_to_write
= gzip_hdr_bytes
;
626 bytes_to_write
-= state
->count
;
628 if (bytes_to_write
> stream
->avail_out
)
629 bytes_to_write
= stream
->avail_out
;
631 memcpy(stream
->next_out
, gzip_hdr
+ state
->count
, bytes_to_write
);
632 state
->count
+= bytes_to_write
;
634 if (state
->count
== gzip_hdr_bytes
) {
636 state
->has_gzip_hdr
= 1;
639 stream
->avail_out
-= bytes_to_write
;
640 stream
->total_out
+= bytes_to_write
;
641 stream
->next_out
+= bytes_to_write
;
646 static int write_deflate_header_stateless(struct isal_zstream
*stream
)
648 struct isal_zstate
*state
= &stream
->internal_state
;
649 struct isal_hufftables
*hufftables
= stream
->hufftables
;
652 if (hufftables
->deflate_hdr_count
+ 8 >= stream
->avail_out
)
653 return STATELESS_OVERFLOW
;
655 memcpy(stream
->next_out
, hufftables
->deflate_hdr
, hufftables
->deflate_hdr_count
);
657 stream
->avail_out
-= hufftables
->deflate_hdr_count
;
658 stream
->total_out
+= hufftables
->deflate_hdr_count
;
659 stream
->next_out
+= hufftables
->deflate_hdr_count
;
661 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
663 write_bits(&state
->bitbuf
, hufftables
->deflate_hdr
[hufftables
->deflate_hdr_count
],
664 hufftables
->deflate_hdr_extra_bits
);
666 count
= buffer_used(&state
->bitbuf
);
667 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
668 stream
->avail_out
-= count
;
669 stream
->total_out
+= count
;
674 static int write_deflate_header_unaligned_stateless(struct isal_zstream
*stream
)
676 struct isal_zstate
*state
= &stream
->internal_state
;
677 struct isal_hufftables
*hufftables
= stream
->hufftables
;
680 uint64_t *header_next
;
681 uint64_t *header_end
;
682 uint64_t header_bits
;
684 if (state
->bitbuf
.m_bit_count
== 0)
685 return write_deflate_header_stateless(stream
);
687 if (hufftables
->deflate_hdr_count
+ 16 >= stream
->avail_out
)
688 return STATELESS_OVERFLOW
;
690 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
692 header_next
= (uint64_t *) hufftables
->deflate_hdr
;
693 header_end
= header_next
+ hufftables
->deflate_hdr_count
/ 8;
695 /* Write out Complete Header bits */
696 for (; header_next
< header_end
; header_next
++) {
697 header_bits
= *header_next
;
698 write_bits(&state
->bitbuf
, header_bits
, 32);
700 write_bits(&state
->bitbuf
, header_bits
, 32);
703 header_bits
= *header_next
;
705 (hufftables
->deflate_hdr_count
& 0x7) * 8 + hufftables
->deflate_hdr_extra_bits
;
707 if (bit_count
> MAX_BITBUF_BIT_WRITE
) {
708 write_bits(&state
->bitbuf
, header_bits
, MAX_BITBUF_BIT_WRITE
);
709 header_bits
>>= MAX_BITBUF_BIT_WRITE
;
710 bit_count
-= MAX_BITBUF_BIT_WRITE
;
714 write_bits(&state
->bitbuf
, header_bits
, bit_count
);
716 /* check_space flushes extra bytes in bitbuf. Required because
717 * write_bits_always fails when the next commit makes the buffer
718 * length exceed 64 bits */
719 check_space(&state
->bitbuf
, FORCE_FLUSH
);
721 count
= buffer_used(&state
->bitbuf
);
722 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
723 stream
->avail_out
-= count
;
724 stream
->total_out
+= count
;
729 void write_header(struct isal_zstream
*stream
)
731 struct isal_zstate
*state
= &stream
->internal_state
;
732 struct isal_hufftables
*hufftables
= stream
->hufftables
;
735 state
->state
= ZSTATE_HDR
;
737 if (state
->bitbuf
.m_bit_count
!= 0) {
738 if (stream
->avail_out
< 8)
740 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
741 flush(&state
->bitbuf
);
742 count
= buffer_used(&state
->bitbuf
);
743 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
744 stream
->avail_out
-= count
;
745 stream
->total_out
+= count
;
748 if (!state
->has_gzip_hdr
)
749 write_gzip_header(stream
);
752 count
= hufftables
->deflate_hdr_count
- state
->count
;
755 if (count
> stream
->avail_out
)
756 count
= stream
->avail_out
;
758 memcpy(stream
->next_out
, hufftables
->deflate_hdr
+ state
->count
, count
);
760 if (state
->count
== 0 && count
> 0) {
761 if (!stream
->end_of_stream
)
762 *stream
->next_out
&= 0xfe;
764 state
->has_eob_hdr
= 1;
767 stream
->next_out
+= count
;
768 stream
->avail_out
-= count
;
769 stream
->total_out
+= count
;
770 state
->count
+= count
;
772 count
= hufftables
->deflate_hdr_count
- state
->count
;
775 if ((count
== 0) && (stream
->avail_out
>= 8)) {
777 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
779 write_bits(&state
->bitbuf
,
780 hufftables
->deflate_hdr
[hufftables
->deflate_hdr_count
],
781 hufftables
->deflate_hdr_extra_bits
);
783 state
->state
= ZSTATE_BODY
;
786 count
= buffer_used(&state
->bitbuf
);
787 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
788 stream
->avail_out
-= count
;
789 stream
->total_out
+= count
;
794 uint32_t get_crc_01(uint32_t * crc
)
796 return crc_512to32_01(crc
);
799 void write_trailer(struct isal_zstream
*stream
)
801 struct isal_zstate
*state
= &stream
->internal_state
;
804 if (stream
->avail_out
>= 8) {
805 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
807 /* the flush() will pad to the next byte and write up to 8 bytes
808 * to the output stream/buffer.
810 if (!state
->has_eob_hdr
) {
811 /* If the final header has not been written, write a
812 * final block. This block is a static huffman block
813 * which only contains the end of block symbol. The code
814 * that happens to do this is the fist 10 bits of
816 state
->has_eob_hdr
= 1;
817 write_bits(&state
->bitbuf
, 0x003, 10);
818 if (is_full(&state
->bitbuf
)) {
819 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
820 bytes
= buffer_used(&state
->bitbuf
);
821 stream
->avail_out
-= bytes
;
822 stream
->total_out
+= bytes
;
827 flush(&state
->bitbuf
);
828 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
829 bytes
= buffer_used(&state
->bitbuf
);
832 uint32_t *crc
= state
->crc
;
834 if (!is_full(&state
->bitbuf
)) {
835 *(uint64_t *) stream
->next_out
=
836 ((uint64_t) file_size(state
) << 32) | get_crc(crc
);
837 stream
->next_out
+= 8;
839 state
->state
= ZSTATE_END
;
842 state
->state
= ZSTATE_END
;
845 stream
->avail_out
-= bytes
;
846 stream
->total_out
+= bytes
;
850 static int write_trailer_stateless(struct isal_zstream
*stream
, uint32_t avail_in
,
854 struct isal_zstate
*state
= &stream
->internal_state
;
857 if (stream
->avail_out
< 8) {
858 ret
= STATELESS_OVERFLOW
;
860 set_buf(&state
->bitbuf
, stream
->next_out
, stream
->avail_out
);
862 /* the flush() will pad to the next byte and write up to 8 bytes
863 * to the output stream/buffer.
865 flush(&state
->bitbuf
);
866 stream
->next_out
= buffer_ptr(&state
->bitbuf
);
867 bytes
= buffer_used(&state
->bitbuf
);
869 if (is_full(&state
->bitbuf
)) {
870 ret
= STATELESS_OVERFLOW
;
872 *(uint64_t *) stream
->next_out
= ((uint64_t) avail_in
<< 32) | crc32
;
873 stream
->next_out
+= 8;
877 stream
->avail_out
-= bytes
;
878 stream
->total_out
+= bytes
;