igzip: Add stateful dictionary support
Change-Id: I75dbac947787bc0041674468c88d0aa41b8b082f Signed-off-by: Roy Oursler <roy.j.oursler@intel.com>
This commit is contained in:
parent
82a6ac65dc
commit
ed15402f5b
@ -59,7 +59,8 @@ lsrc_x86_64 += \
|
|||||||
igzip/igzip_inflate_multibinary.asm \
|
igzip/igzip_inflate_multibinary.asm \
|
||||||
igzip/encode_df_04.asm \
|
igzip/encode_df_04.asm \
|
||||||
igzip/encode_df_06.asm \
|
igzip/encode_df_06.asm \
|
||||||
igzip/proc_heap.asm
|
igzip/proc_heap.asm \
|
||||||
|
igzip/igzip_deflate_hash.asm
|
||||||
|
|
||||||
src_include += -I $(srcdir)/igzip
|
src_include += -I $(srcdir)/igzip
|
||||||
extern_hdrs += include/igzip_lib.h
|
extern_hdrs += include/igzip_lib.h
|
||||||
|
@ -222,4 +222,10 @@ _STORED_BLK equ 0
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
IGZIP_NO_HIST equ 0
|
||||||
|
IGZIP_HIST equ 1
|
||||||
|
IGZIP_DICT_HIST equ 2
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
# define to_be32(x) _byteswap_ulong(x)
|
# define to_be32(x) _byteswap_ulong(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern void isal_deflate_hash_lvl0(struct isal_zstream *stream, uint8_t * dict, int dict_len);
|
||||||
extern const uint8_t gzip_hdr[];
|
extern const uint8_t gzip_hdr[];
|
||||||
extern const uint32_t gzip_hdr_bytes;
|
extern const uint32_t gzip_hdr_bytes;
|
||||||
extern const uint32_t gzip_trl_bytes;
|
extern const uint32_t gzip_trl_bytes;
|
||||||
@ -125,6 +126,9 @@ struct slver isal_deflate_stateless_slver = { 0x0083, 0x01, 0x01 };
|
|||||||
struct slver isal_deflate_set_hufftables_slver_00_01_008b;
|
struct slver isal_deflate_set_hufftables_slver_00_01_008b;
|
||||||
struct slver isal_deflate_set_hufftables_slver = { 0x008b, 0x01, 0x00 };
|
struct slver isal_deflate_set_hufftables_slver = { 0x008b, 0x01, 0x00 };
|
||||||
|
|
||||||
|
struct slver isal_deflate_set_dict_slver_00_01_008c;
|
||||||
|
struct slver isal_deflate_set_dict_slver = { 0x008c, 0x01, 0x00 };
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
// isal_adler32_bam1 - adler with (B | A minus 1) storage
|
// isal_adler32_bam1 - adler with (B | A minus 1) storage
|
||||||
@ -188,7 +192,7 @@ void sync_flush(struct isal_zstream *stream)
|
|||||||
if (stream->flush == FULL_FLUSH) {
|
if (stream->flush == FULL_FLUSH) {
|
||||||
/* Clear match history so there are no cross
|
/* Clear match history so there are no cross
|
||||||
* block length distance pairs */
|
* block length distance pairs */
|
||||||
reset_match_history(stream);
|
state->has_hist = IGZIP_NO_HIST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -757,7 +761,7 @@ static inline void reset_match_history(struct isal_zstream *stream)
|
|||||||
uint16_t *head = stream->internal_state.head;
|
uint16_t *head = stream->internal_state.head;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
state->has_hist = 0;
|
state->has_hist = IGZIP_NO_HIST;
|
||||||
|
|
||||||
if ((stream->total_in & 0xFFFF) == 0)
|
if ((stream->total_in & 0xFFFF) == 0)
|
||||||
memset(stream->internal_state.head, 0, sizeof(stream->internal_state.head));
|
memset(stream->internal_state.head, 0, sizeof(stream->internal_state.head));
|
||||||
@ -786,21 +790,17 @@ void isal_deflate_init(struct isal_zstream *stream)
|
|||||||
state->b_bytes_processed = 0;
|
state->b_bytes_processed = 0;
|
||||||
state->has_eob = 0;
|
state->has_eob = 0;
|
||||||
state->has_eob_hdr = 0;
|
state->has_eob_hdr = 0;
|
||||||
state->has_hist = 0;
|
state->has_hist = IGZIP_NO_HIST;
|
||||||
state->state = ZSTATE_NEW_HDR;
|
state->state = ZSTATE_NEW_HDR;
|
||||||
state->count = 0;
|
state->count = 0;
|
||||||
|
|
||||||
state->tmp_out_start = 0;
|
state->tmp_out_start = 0;
|
||||||
state->tmp_out_end = 0;
|
state->tmp_out_end = 0;
|
||||||
|
|
||||||
state->file_start = stream->next_in;
|
|
||||||
|
|
||||||
init(&state->bitbuf);
|
init(&state->bitbuf);
|
||||||
|
|
||||||
state->crc = 0;
|
state->crc = 0;
|
||||||
|
|
||||||
memset(state->head, 0, sizeof(state->head));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,6 +844,40 @@ void isal_deflate_stateless_init(struct isal_zstream *stream)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void isal_deflate_hash(struct isal_zstream *stream, uint8_t * dict, uint32_t dict_len)
|
||||||
|
{
|
||||||
|
isal_deflate_hash_lvl0(stream, dict, dict_len);
|
||||||
|
stream->internal_state.has_hist = IGZIP_HIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
int isal_deflate_set_dict(struct isal_zstream *stream, uint8_t * dict, uint32_t dict_len)
|
||||||
|
{
|
||||||
|
struct isal_zstate *state = &stream->internal_state;
|
||||||
|
|
||||||
|
if (state->state != ZSTATE_NEW_HDR || state->b_bytes_processed != state->b_bytes_valid)
|
||||||
|
return ISAL_INVALID_STATE;
|
||||||
|
|
||||||
|
if (dict_len <= 0)
|
||||||
|
return COMP_OK;
|
||||||
|
|
||||||
|
if (dict_len > IGZIP_HIST_SIZE) {
|
||||||
|
dict = dict + dict_len - IGZIP_HIST_SIZE;
|
||||||
|
dict_len = IGZIP_HIST_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(state->buffer, dict, dict_len);
|
||||||
|
state->b_bytes_processed = dict_len;
|
||||||
|
state->b_bytes_valid = dict_len;
|
||||||
|
|
||||||
|
/* Reset history to prevent out of bounds matches this works because
|
||||||
|
* dictionary must set at least 1 element in the history */
|
||||||
|
memset(stream->internal_state.head, -1, sizeof(stream->internal_state.head));
|
||||||
|
|
||||||
|
state->has_hist = IGZIP_DICT_HIST;
|
||||||
|
|
||||||
|
return COMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int isal_deflate_stateless(struct isal_zstream *stream)
|
int isal_deflate_stateless(struct isal_zstream *stream)
|
||||||
{
|
{
|
||||||
uint8_t *next_in = stream->next_in;
|
uint8_t *next_in = stream->next_in;
|
||||||
@ -963,6 +997,11 @@ int isal_deflate(struct isal_zstream *stream)
|
|||||||
avail_in = stream->avail_in;
|
avail_in = stream->avail_in;
|
||||||
stream->total_in -= state->b_bytes_valid - state->b_bytes_processed;
|
stream->total_in -= state->b_bytes_valid - state->b_bytes_processed;
|
||||||
|
|
||||||
|
if (state->has_hist == IGZIP_NO_HIST)
|
||||||
|
reset_match_history(stream);
|
||||||
|
else if (state->has_hist == IGZIP_DICT_HIST)
|
||||||
|
isal_deflate_hash(stream, state->buffer, state->b_bytes_processed);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
size = avail_in;
|
size = avail_in;
|
||||||
if (size > sizeof(state->buffer) - state->b_bytes_valid) {
|
if (size > sizeof(state->buffer) - state->b_bytes_valid) {
|
||||||
|
@ -208,3 +208,22 @@ void isal_deflate_finish_base(struct isal_zstream *stream)
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void isal_deflate_hash_lvl0_base(struct isal_zstream *stream, uint8_t * dict,
|
||||||
|
uint32_t dict_len)
|
||||||
|
{
|
||||||
|
uint8_t *next_in = dict;
|
||||||
|
uint8_t *end_in = dict + dict_len - SHORTEST_MATCH;
|
||||||
|
uint32_t literal;
|
||||||
|
uint32_t hash;
|
||||||
|
uint16_t lookup_val = stream->total_in - dict_len;
|
||||||
|
uint16_t *last_seen = stream->internal_state.head;
|
||||||
|
|
||||||
|
while (next_in <= end_in) {
|
||||||
|
literal = *(uint32_t *) next_in;
|
||||||
|
hash = compute_hash(literal) & HASH_MASK;
|
||||||
|
last_seen[hash] = lookup_val;
|
||||||
|
lookup_val++;
|
||||||
|
next_in++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -43,6 +43,8 @@ struct deflate_icf *encode_deflate_icf_base(struct deflate_icf *next_in,
|
|||||||
uint32_t crc32_gzip_base(uint32_t init_crc, const unsigned char *buf, uint64_t len);
|
uint32_t crc32_gzip_base(uint32_t init_crc, const unsigned char *buf, uint64_t len);
|
||||||
uint32_t adler32_base(uint32_t init, const unsigned char *buf, uint64_t len);
|
uint32_t adler32_base(uint32_t init, const unsigned char *buf, uint64_t len);
|
||||||
int decode_huffman_code_block_stateless_base(struct inflate_state *s);
|
int decode_huffman_code_block_stateless_base(struct inflate_state *s);
|
||||||
|
void isal_deflate_hash_lvl0_base(struct isal_zstream *stream, uint8_t * dict,
|
||||||
|
uint32_t dict_len);
|
||||||
|
|
||||||
void isal_deflate_body(struct isal_zstream *stream)
|
void isal_deflate_body(struct isal_zstream *stream)
|
||||||
{
|
{
|
||||||
@ -91,3 +93,8 @@ int decode_huffman_code_block_stateless(struct inflate_state *s)
|
|||||||
{
|
{
|
||||||
return decode_huffman_code_block_stateless_base(s);
|
return decode_huffman_code_block_stateless_base(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void isal_deflate_hash_lvl0(struct isal_zstream *stream, uint8_t * dict, uint32_t dict_len)
|
||||||
|
{
|
||||||
|
return isal_deflate_hash_lvl0_base(stream, dict, dict_len);
|
||||||
|
}
|
||||||
|
@ -212,7 +212,7 @@ MARK __body_compute_hash_ %+ ARCH
|
|||||||
and hash, HASH_MASK
|
and hash, HASH_MASK
|
||||||
and hash2, HASH_MASK
|
and hash2, HASH_MASK
|
||||||
|
|
||||||
cmp dword [stream + _internal_state_has_hist], 0
|
cmp dword [stream + _internal_state_has_hist], IGZIP_NO_HIST
|
||||||
je write_first_byte
|
je write_first_byte
|
||||||
|
|
||||||
jmp loop2
|
jmp loop2
|
||||||
@ -545,7 +545,7 @@ write_first_byte:
|
|||||||
cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end]
|
cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end]
|
||||||
ja output_end
|
ja output_end
|
||||||
|
|
||||||
mov dword [stream + _internal_state_has_hist], 1
|
mov dword [stream + _internal_state_has_hist], IGZIP_HIST
|
||||||
|
|
||||||
mov [stream + _internal_state_head + 2 * hash], f_i %+ w
|
mov [stream + _internal_state_head + 2 * hash], f_i %+ w
|
||||||
|
|
||||||
|
@ -363,6 +363,7 @@ decode_huffman_code_block_stateless_ %+ ARCH %+ :
|
|||||||
mov dword [state + _copy_overflow_dist], 0
|
mov dword [state + _copy_overflow_dist], 0
|
||||||
|
|
||||||
mov tmp3 %+ d, dword [state + _total_out]
|
mov tmp3 %+ d, dword [state + _total_out]
|
||||||
|
add tmp3 %+ d, dword [state + _dict_length]
|
||||||
sub tmp3, next_out
|
sub tmp3, next_out
|
||||||
neg tmp3
|
neg tmp3
|
||||||
|
|
||||||
@ -658,6 +659,7 @@ end:
|
|||||||
sub end_out, next_out
|
sub end_out, next_out
|
||||||
mov dword [state + _avail_out], end_out %+ d
|
mov dword [state + _avail_out], end_out %+ d
|
||||||
sub next_out, [rsp + start_out_mem_offset]
|
sub next_out, [rsp + start_out_mem_offset]
|
||||||
|
sub next_out %+ d, [state + _dict_length]
|
||||||
mov [state + _total_out], next_out %+ d
|
mov [state + _total_out], next_out %+ d
|
||||||
mov [state + _next_in], next_in
|
mov [state + _next_in], next_in
|
||||||
sub end_in, next_in
|
sub end_in, next_in
|
||||||
|
61
igzip/igzip_deflate_hash.asm
Normal file
61
igzip/igzip_deflate_hash.asm
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
%include "options.asm"
|
||||||
|
%include "lz0a_const.asm"
|
||||||
|
%include "data_struct2.asm"
|
||||||
|
%include "huffman.asm"
|
||||||
|
%include "reg_sizes.asm"
|
||||||
|
|
||||||
|
%define DICT_SLOP 4
|
||||||
|
|
||||||
|
%ifidn __OUTPUT_FORMAT__, win64
|
||||||
|
%define arg1 rcx
|
||||||
|
%define arg2 rdx
|
||||||
|
%define arg3 r8
|
||||||
|
%else
|
||||||
|
%define arg1 rdi
|
||||||
|
%define arg2 rsi
|
||||||
|
%define arg3 rdx
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%define stream arg1
|
||||||
|
|
||||||
|
%define dict_offset arg2
|
||||||
|
|
||||||
|
%define dict_len arg3
|
||||||
|
%define f_i arg3
|
||||||
|
|
||||||
|
%define data r9
|
||||||
|
|
||||||
|
%define hash r10
|
||||||
|
|
||||||
|
%define f_i_end r11
|
||||||
|
|
||||||
|
global isal_deflate_hash_lvl0_01
|
||||||
|
isal_deflate_hash_lvl0_01:
|
||||||
|
%ifnidn (arg1, stream)
|
||||||
|
mov stream, arg1
|
||||||
|
%endif
|
||||||
|
%ifnidn (arg2, dict_next)
|
||||||
|
mov dict_offset, arg2
|
||||||
|
%endif
|
||||||
|
|
||||||
|
mov f_i_end %+ d, dword [stream + _total_in]
|
||||||
|
neg f_i
|
||||||
|
add f_i, f_i_end
|
||||||
|
|
||||||
|
sub dict_offset, f_i
|
||||||
|
|
||||||
|
sub f_i_end, DICT_SLOP
|
||||||
|
cmp f_i, f_i_end
|
||||||
|
jg end
|
||||||
|
|
||||||
|
main_loop:
|
||||||
|
mov data %+ d, [f_i + dict_offset]
|
||||||
|
compute_hash hash, data
|
||||||
|
and hash, HASH_MASK
|
||||||
|
mov [stream + _internal_state_head + 2 * hash], f_i %+ w
|
||||||
|
|
||||||
|
add f_i, 1
|
||||||
|
cmp f_i, f_i_end
|
||||||
|
jle main_loop
|
||||||
|
end:
|
||||||
|
ret
|
@ -52,26 +52,31 @@ int usage(void)
|
|||||||
" -X use compression level X with 0 <= X <= 1\n"
|
" -X use compression level X with 0 <= X <= 1\n"
|
||||||
" -b <size> input buffer size, 0 buffers all the input\n"
|
" -b <size> input buffer size, 0 buffers all the input\n"
|
||||||
" -i <iter> number of iterations (at least 1)\n"
|
" -i <iter> number of iterations (at least 1)\n"
|
||||||
" -o <file> output file for compresed data\n");
|
" -o <file> output file for compresed data\n"
|
||||||
|
" -d <file> dictionary file used by compression\n");
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
FILE *in = NULL, *out = NULL;
|
FILE *in = NULL, *out = NULL, *dict = NULL;
|
||||||
unsigned char *inbuf, *outbuf, *level_buf = NULL;
|
unsigned char *inbuf, *outbuf, *level_buf = NULL, *dictbuf = NULL;
|
||||||
int i, c, iterations = 0, inbuf_size = 0;
|
int i, c, iterations = 0, inbuf_size = 0;
|
||||||
uint64_t infile_size, outbuf_size;
|
uint64_t infile_size, outbuf_size, dictfile_size;
|
||||||
struct isal_huff_histogram histogram;
|
struct isal_huff_histogram histogram;
|
||||||
struct isal_hufftables hufftables_custom;
|
struct isal_hufftables hufftables_custom;
|
||||||
int level = 0, level_size = 0, avail_in;
|
int level = 0, level_size = 0, avail_in;
|
||||||
char *in_file_name = NULL, *out_file_name = NULL;
|
char *in_file_name = NULL, *out_file_name = NULL, *dict_file_name = NULL;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "h01i:b:o:")) != -1) {
|
while ((c = getopt(argc, argv, "h01i:b:o:d:")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'o':
|
case 'o':
|
||||||
out_file_name = optarg;
|
out_file_name = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
dict_file_name = optarg;
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
iterations = atoi(optarg);
|
iterations = atoi(optarg);
|
||||||
if (iterations < 1)
|
if (iterations < 1)
|
||||||
@ -112,6 +117,15 @@ int main(int argc, char *argv[])
|
|||||||
printf("outfile=%s\n", out_file_name);
|
printf("outfile=%s\n", out_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dict_file_name != NULL) {
|
||||||
|
dict = fopen(dict_file_name, "rb");
|
||||||
|
if (!dict) {
|
||||||
|
fprintf(stderr, "Can't open %s for reading\n", dict_file_name);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
printf("outfile=%s\n", dict_file_name);
|
||||||
|
}
|
||||||
|
|
||||||
printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024);
|
printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024);
|
||||||
printf("igzip_file_perf: \n");
|
printf("igzip_file_perf: \n");
|
||||||
fflush(0);
|
fflush(0);
|
||||||
@ -123,6 +137,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
outbuf_size = 2 * infile_size + BUF_SIZE;
|
outbuf_size = 2 * infile_size + BUF_SIZE;
|
||||||
|
|
||||||
|
dictfile_size = 0;
|
||||||
|
if (dict_file_name != NULL)
|
||||||
|
dictfile_size = get_filesize(dict);
|
||||||
|
|
||||||
if (iterations == 0) {
|
if (iterations == 0) {
|
||||||
iterations = infile_size ? RUN_MEM_SIZE / infile_size : MIN_TEST_LOOPS;
|
iterations = infile_size ? RUN_MEM_SIZE / infile_size : MIN_TEST_LOOPS;
|
||||||
if (iterations < MIN_TEST_LOOPS)
|
if (iterations < MIN_TEST_LOOPS)
|
||||||
@ -140,6 +158,14 @@ int main(int argc, char *argv[])
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dictfile_size != 0) {
|
||||||
|
dictbuf = malloc(dictfile_size);
|
||||||
|
if (dictbuf == NULL) {
|
||||||
|
fprintf(stderr, "Can't allocate dictionary buffer memory\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (level_size != 0) {
|
if (level_size != 0) {
|
||||||
level_buf = malloc(level_size);
|
level_buf = malloc(level_size);
|
||||||
if (level_buf == NULL) {
|
if (level_buf == NULL) {
|
||||||
@ -158,11 +184,18 @@ int main(int argc, char *argv[])
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dictfile_size != (uint32_t) fread(dictbuf, 1, dictfile_size, dict)) {
|
||||||
|
fprintf(stderr, "Couldn't fit all of dictionary file into buffer\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
struct perf start, stop;
|
struct perf start, stop;
|
||||||
perf_start(&start);
|
perf_start(&start);
|
||||||
|
|
||||||
for (i = 0; i < iterations; i++) {
|
for (i = 0; i < iterations; i++) {
|
||||||
isal_deflate_init(&stream);
|
isal_deflate_init(&stream);
|
||||||
|
if (dict_file_name != NULL)
|
||||||
|
isal_deflate_set_dict(&stream, dictbuf, dictfile_size);
|
||||||
stream.end_of_stream = 0;
|
stream.end_of_stream = 0;
|
||||||
stream.flush = NO_FLUSH;
|
stream.flush = NO_FLUSH;
|
||||||
stream.level = level;
|
stream.level = level;
|
||||||
|
@ -126,7 +126,7 @@ skip_SLOP:
|
|||||||
|
|
||||||
mov curr_data %+ d, [file_start + f_i]
|
mov curr_data %+ d, [file_start + f_i]
|
||||||
|
|
||||||
cmp dword [stream + _internal_state_has_hist], 0
|
cmp dword [stream + _internal_state_has_hist], IGZIP_NO_HIST
|
||||||
jne skip_write_first_byte
|
jne skip_write_first_byte
|
||||||
|
|
||||||
cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end]
|
cmp m_out_buf, [stream + _internal_state_bitbuf_m_out_end]
|
||||||
@ -135,7 +135,7 @@ skip_SLOP:
|
|||||||
compute_hash hash, curr_data
|
compute_hash hash, curr_data
|
||||||
and hash %+ d, HASH_MASK
|
and hash %+ d, HASH_MASK
|
||||||
mov [stream + _internal_state_head + 2 * hash], f_i %+ w
|
mov [stream + _internal_state_head + 2 * hash], f_i %+ w
|
||||||
mov dword [stream + _internal_state_has_hist], 1
|
mov dword [stream + _internal_state_has_hist], IGZIP_HIST
|
||||||
jmp encode_literal
|
jmp encode_literal
|
||||||
|
|
||||||
skip_write_first_byte:
|
skip_write_first_byte:
|
||||||
|
@ -193,7 +193,7 @@ MARK __body_compute_hash_ %+ ARCH
|
|||||||
and hash, HASH_MASK
|
and hash, HASH_MASK
|
||||||
and hash2, HASH_MASK
|
and hash2, HASH_MASK
|
||||||
|
|
||||||
cmp dword [stream + _internal_state_has_hist], 0
|
cmp dword [stream + _internal_state_has_hist], IGZIP_NO_HIST
|
||||||
je write_first_byte
|
je write_first_byte
|
||||||
|
|
||||||
jmp loop2
|
jmp loop2
|
||||||
@ -482,7 +482,7 @@ write_first_byte:
|
|||||||
cmp m_out_buf, [rsp + m_out_end]
|
cmp m_out_buf, [rsp + m_out_end]
|
||||||
ja output_end
|
ja output_end
|
||||||
|
|
||||||
mov dword [stream + _internal_state_has_hist], 1
|
mov dword [stream + _internal_state_has_hist], IGZIP_HIST
|
||||||
|
|
||||||
mov [stream + _internal_state_head + 2 * hash], f_i %+ w
|
mov [stream + _internal_state_head + 2 * hash], f_i %+ w
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ isal_deflate_icf_finish_01:
|
|||||||
|
|
||||||
mov curr_data %+ d, [file_start + f_i]
|
mov curr_data %+ d, [file_start + f_i]
|
||||||
|
|
||||||
cmp dword [stream + _internal_state_has_hist], 0
|
cmp dword [stream + _internal_state_has_hist], IGZIP_NO_HIST
|
||||||
jne skip_write_first_byte
|
jne skip_write_first_byte
|
||||||
|
|
||||||
cmp m_out_buf, [rsp + m_out_end]
|
cmp m_out_buf, [rsp + m_out_end]
|
||||||
@ -131,7 +131,7 @@ isal_deflate_icf_finish_01:
|
|||||||
compute_hash hash, curr_data
|
compute_hash hash, curr_data
|
||||||
and hash %+ d, HASH_MASK
|
and hash %+ d, HASH_MASK
|
||||||
mov [stream + _internal_state_head + 2 * hash], f_i %+ w
|
mov [stream + _internal_state_head + 2 * hash], f_i %+ w
|
||||||
mov dword [stream + _internal_state_has_hist], 1
|
mov dword [stream + _internal_state_has_hist], IGZIP_HIST
|
||||||
jmp encode_literal
|
jmp encode_literal
|
||||||
|
|
||||||
skip_write_first_byte:
|
skip_write_first_byte:
|
||||||
|
@ -87,6 +87,9 @@ struct slver isal_inflate_stateless_slver = { 0x0089, 0x01, 0x00 };
|
|||||||
struct slver isal_inflate_slver_0001008a;
|
struct slver isal_inflate_slver_0001008a;
|
||||||
struct slver isal_inflate_slver = { 0x008a, 0x01, 0x00 };
|
struct slver isal_inflate_slver = { 0x008a, 0x01, 0x00 };
|
||||||
|
|
||||||
|
struct slver isal_inflate_set_dict_slver_0001008d;
|
||||||
|
struct slver isal_inflate_set_dict_slver = { 0x008d, 0x01, 0x00 };
|
||||||
|
|
||||||
/*Performs a copy of length repeat_length data starting at dest -
|
/*Performs a copy of length repeat_length data starting at dest -
|
||||||
* lookback_distance into dest. This copy copies data previously copied when the
|
* lookback_distance into dest. This copy copies data previously copied when the
|
||||||
* src buffer and the dest buffer overlap. */
|
* src buffer and the dest buffer overlap. */
|
||||||
@ -1064,7 +1067,7 @@ int decode_huffman_code_block_stateless_base(struct inflate_state *state)
|
|||||||
return ISAL_END_INPUT;
|
return ISAL_END_INPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (look_back_dist > state->total_out)
|
if (look_back_dist > state->total_out + state->dict_length)
|
||||||
return ISAL_INVALID_LOOKBACK;
|
return ISAL_INVALID_LOOKBACK;
|
||||||
|
|
||||||
if (state->avail_out < repeat_length) {
|
if (state->avail_out < repeat_length) {
|
||||||
@ -1103,6 +1106,7 @@ void isal_inflate_init(struct inflate_state *state)
|
|||||||
state->next_out = NULL;
|
state->next_out = NULL;
|
||||||
state->avail_out = 0;
|
state->avail_out = 0;
|
||||||
state->total_out = 0;
|
state->total_out = 0;
|
||||||
|
state->dict_length = 0;
|
||||||
state->block_state = ISAL_BLOCK_NEW_HDR;
|
state->block_state = ISAL_BLOCK_NEW_HDR;
|
||||||
state->bfinal = 0;
|
state->bfinal = 0;
|
||||||
state->crc_flag = 0;
|
state->crc_flag = 0;
|
||||||
@ -1115,6 +1119,26 @@ void isal_inflate_init(struct inflate_state *state)
|
|||||||
state->tmp_out_valid = 0;
|
state->tmp_out_valid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isal_inflate_set_dict(struct inflate_state *state, uint8_t * dict, uint32_t dict_len)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (state->block_state != ISAL_BLOCK_NEW_HDR
|
||||||
|
|| state->tmp_out_processed != state->tmp_out_valid)
|
||||||
|
return ISAL_INVALID_STATE;
|
||||||
|
|
||||||
|
if (dict_len > IGZIP_HIST_SIZE) {
|
||||||
|
dict = dict + dict_len - IGZIP_HIST_SIZE;
|
||||||
|
dict_len = IGZIP_HIST_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(state->tmp_out_buffer, dict, dict_len);
|
||||||
|
state->tmp_out_processed = dict_len;
|
||||||
|
state->tmp_out_valid = dict_len;
|
||||||
|
state->dict_length = dict_len;
|
||||||
|
|
||||||
|
return COMP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int isal_inflate_stateless(struct inflate_state *state)
|
int isal_inflate_stateless(struct inflate_state *state)
|
||||||
{
|
{
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
@ -1123,6 +1147,7 @@ int isal_inflate_stateless(struct inflate_state *state)
|
|||||||
state->read_in = 0;
|
state->read_in = 0;
|
||||||
state->read_in_length = 0;
|
state->read_in_length = 0;
|
||||||
state->block_state = ISAL_BLOCK_NEW_HDR;
|
state->block_state = ISAL_BLOCK_NEW_HDR;
|
||||||
|
state->dict_length = 0;
|
||||||
state->bfinal = 0;
|
state->bfinal = 0;
|
||||||
state->crc = 0;
|
state->crc = 0;
|
||||||
state->total_out = 0;
|
state->total_out = 0;
|
||||||
|
@ -71,6 +71,9 @@ extern adler32_base
|
|||||||
extern adler32_avx2_4
|
extern adler32_avx2_4
|
||||||
extern adler32_sse
|
extern adler32_sse
|
||||||
|
|
||||||
|
extern isal_deflate_hash_lvl0_base
|
||||||
|
extern isal_deflate_hash_lvl0_01
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|
||||||
%include "multibinary.asm"
|
%include "multibinary.asm"
|
||||||
@ -101,3 +104,6 @@ mbin_dispatch_init5 crc32_gzip, crc32_gzip_base, crc32_gzip_base, crc32_gzip_01,
|
|||||||
|
|
||||||
mbin_interface isal_adler32
|
mbin_interface isal_adler32
|
||||||
mbin_dispatch_init5 isal_adler32, adler32_base, adler32_sse, adler32_sse, adler32_avx2_4
|
mbin_dispatch_init5 isal_adler32, adler32_base, adler32_sse, adler32_sse, adler32_avx2_4
|
||||||
|
|
||||||
|
mbin_interface isal_deflate_hash_lvl0
|
||||||
|
mbin_dispatch_init5 isal_deflate_hash_lvl0, isal_deflate_hash_lvl0_base, isal_deflate_hash_lvl0_01, isal_deflate_hash_lvl0_01, isal_deflate_hash_lvl0_01
|
||||||
|
@ -210,6 +210,29 @@ void create_rand_repeat_data(uint8_t * data, int size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void create_rand_dict(uint8_t * dict, uint32_t dict_len, uint8_t * buf, uint32_t buf_len)
|
||||||
|
{
|
||||||
|
uint32_t dict_chunk_size, buf_chunk_size;
|
||||||
|
while (dict_len > 0) {
|
||||||
|
dict_chunk_size = rand() % IGZIP_K;
|
||||||
|
dict_chunk_size = (dict_len >= dict_chunk_size) ? dict_chunk_size : dict_len;
|
||||||
|
|
||||||
|
buf_chunk_size = rand() % IGZIP_K;
|
||||||
|
buf_chunk_size = (buf_len >= buf_chunk_size) ? buf_chunk_size : buf_len;
|
||||||
|
|
||||||
|
if (rand() % 3 == 0 && buf_len >= dict_len)
|
||||||
|
memcpy(dict, buf, dict_chunk_size);
|
||||||
|
else
|
||||||
|
create_rand_repeat_data(dict, dict_chunk_size);
|
||||||
|
|
||||||
|
dict_len -= dict_chunk_size;
|
||||||
|
dict += dict_chunk_size;
|
||||||
|
buf_len -= buf_chunk_size;
|
||||||
|
buf += buf_chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int get_rand_data_length(void)
|
int get_rand_data_length(void)
|
||||||
{
|
{
|
||||||
int max_mask =
|
int max_mask =
|
||||||
@ -435,7 +458,8 @@ int inflate_stateless_pass(uint8_t * compress_buf, uint64_t compress_len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
|
int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
|
||||||
uint8_t * uncompress_buf, uint32_t * uncompress_len, uint32_t gzip_flag)
|
uint8_t * uncompress_buf, uint32_t * uncompress_len, uint32_t gzip_flag,
|
||||||
|
uint8_t * dict, uint32_t dict_len)
|
||||||
{
|
{
|
||||||
struct inflate_state *state = NULL;
|
struct inflate_state *state = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -452,6 +476,9 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
|
|||||||
|
|
||||||
isal_inflate_init(state);
|
isal_inflate_init(state);
|
||||||
|
|
||||||
|
if (dict != NULL)
|
||||||
|
isal_inflate_set_dict(state, dict, dict_len);
|
||||||
|
|
||||||
state->next_in = NULL;
|
state->next_in = NULL;
|
||||||
state->next_out = NULL;
|
state->next_out = NULL;
|
||||||
state->avail_in = 0;
|
state->avail_in = 0;
|
||||||
@ -583,7 +610,7 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len,
|
|||||||
|
|
||||||
/* Inflate the compressed data and check that the decompressed data agrees with the input data */
|
/* Inflate the compressed data and check that the decompressed data agrees with the input data */
|
||||||
int inflate_check(uint8_t * z_buf, int z_size, uint8_t * in_buf, int in_size,
|
int inflate_check(uint8_t * z_buf, int z_size, uint8_t * in_buf, int in_size,
|
||||||
uint32_t gzip_flag)
|
uint32_t gzip_flag, uint8_t * dict, uint32_t dict_len)
|
||||||
{
|
{
|
||||||
/* Test inflate with reference inflate */
|
/* Test inflate with reference inflate */
|
||||||
|
|
||||||
@ -613,11 +640,13 @@ int inflate_check(uint8_t * z_buf, int z_size, uint8_t * in_buf, int in_size,
|
|||||||
z_size -= zlib_hdr_bytes;
|
z_size -= zlib_hdr_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inflate_type == 0) {
|
if (inflate_type == 0 && dict == NULL) {
|
||||||
ret = inflate_stateless_pass(z_buf, z_size, test_buf, &test_size, gzip_flag);
|
ret = inflate_stateless_pass(z_buf, z_size, test_buf, &test_size, gzip_flag);
|
||||||
inflate_type = 1;
|
inflate_type = 1;
|
||||||
} else {
|
} else {
|
||||||
ret = inflate_multi_pass(z_buf, z_size, test_buf, &test_size, gzip_flag);
|
ret =
|
||||||
|
inflate_multi_pass(z_buf, z_size, test_buf, &test_size, gzip_flag, dict,
|
||||||
|
dict_len);
|
||||||
inflate_type = 0;
|
inflate_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,7 +825,7 @@ void set_random_hufftable(struct isal_zstream *stream)
|
|||||||
* compression*/
|
* compression*/
|
||||||
int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
|
int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
|
||||||
uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
|
uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
|
||||||
uint32_t level)
|
uint32_t level, uint8_t * dict, uint32_t dict_len)
|
||||||
{
|
{
|
||||||
int ret = IGZIP_COMP_OK;
|
int ret = IGZIP_COMP_OK;
|
||||||
uint8_t *in_buf = NULL, *out_buf = NULL;
|
uint8_t *in_buf = NULL, *out_buf = NULL;
|
||||||
@ -946,7 +975,7 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed
|
|||||||
/* Compress the input data into the outbuffer in one call to isal_deflate */
|
/* Compress the input data into the outbuffer in one call to isal_deflate */
|
||||||
int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
|
int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed_buf,
|
||||||
uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
|
uint32_t * compressed_size, uint32_t flush_type, uint32_t gzip_flag,
|
||||||
uint32_t level)
|
uint32_t level, uint8_t * dict, uint32_t dict_len)
|
||||||
{
|
{
|
||||||
int ret = IGZIP_COMP_OK;
|
int ret = IGZIP_COMP_OK;
|
||||||
struct isal_zstream stream;
|
struct isal_zstream stream;
|
||||||
@ -967,6 +996,9 @@ int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compresse
|
|||||||
if (state->state != ZSTATE_NEW_HDR)
|
if (state->state != ZSTATE_NEW_HDR)
|
||||||
return COMPRESS_INCORRECT_STATE;
|
return COMPRESS_INCORRECT_STATE;
|
||||||
|
|
||||||
|
if (dict != NULL)
|
||||||
|
isal_deflate_set_dict(&stream, dict, dict_len);
|
||||||
|
|
||||||
stream.flush = flush_type;
|
stream.flush = flush_type;
|
||||||
stream.avail_in = data_size;
|
stream.avail_in = data_size;
|
||||||
stream.next_in = data;
|
stream.next_in = data;
|
||||||
@ -1153,7 +1185,9 @@ int compress_stateless_full_flush(uint8_t * data, uint32_t data_size, uint8_t *
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Verify that blocks are independent */
|
/* Verify that blocks are independent */
|
||||||
ret = inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size, 0);
|
ret =
|
||||||
|
inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size, 0, NULL,
|
||||||
|
0);
|
||||||
|
|
||||||
if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE) {
|
if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE) {
|
||||||
break;
|
break;
|
||||||
@ -1272,7 +1306,7 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed
|
|||||||
if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_END) {
|
if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_END) {
|
||||||
ret =
|
ret =
|
||||||
inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size,
|
inflate_check(out_buf, stream.next_out - out_buf, in_buf, in_size,
|
||||||
0);
|
0, NULL, 0);
|
||||||
|
|
||||||
if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE)
|
if (ret == INFLATE_INVALID_LOOK_BACK_DISTANCE)
|
||||||
break;
|
break;
|
||||||
@ -1425,7 +1459,7 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size, uint32_t flush_
|
|||||||
compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level);
|
compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag);
|
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0);
|
||||||
|
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -1473,7 +1507,7 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size, uint32_t flush_
|
|||||||
ret =
|
ret =
|
||||||
compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level);
|
compress_stateless(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag);
|
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0);
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
if (ret) {
|
if (ret) {
|
||||||
printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag);
|
printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag);
|
||||||
@ -1511,7 +1545,8 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size, uint32_t flush_
|
|||||||
print_error(overflow);
|
print_error(overflow);
|
||||||
if (overflow == 0) {
|
if (overflow == 0) {
|
||||||
overflow =
|
overflow =
|
||||||
inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag);
|
inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag,
|
||||||
|
NULL, 0);
|
||||||
printf("inflate ret = %d\n", overflow);
|
printf("inflate ret = %d\n", overflow);
|
||||||
print_error(overflow);
|
print_error(overflow);
|
||||||
}
|
}
|
||||||
@ -1553,7 +1588,7 @@ int test_compress_stateless(uint8_t * in_data, uint32_t in_size, uint32_t flush_
|
|||||||
ret = compress_stateless_full_flush(in_buf, in_size, z_buf, &z_size, level);
|
ret = compress_stateless_full_flush(in_buf, in_size, z_buf, &z_size, level);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = inflate_check(z_buf, z_size, in_buf, in_size, 0);
|
ret = inflate_check(z_buf, z_size, in_buf, in_size, 0, NULL, 0);
|
||||||
else if (ret == COMPRESS_LOOP_COUNT_OVERFLOW)
|
else if (ret == COMPRESS_LOOP_COUNT_OVERFLOW)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
@ -1583,8 +1618,8 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type)
|
|||||||
{
|
{
|
||||||
int ret = IGZIP_COMP_OK, fin_ret = IGZIP_COMP_OK;
|
int ret = IGZIP_COMP_OK, fin_ret = IGZIP_COMP_OK;
|
||||||
uint32_t overflow = 0, gzip_flag, level;
|
uint32_t overflow = 0, gzip_flag, level;
|
||||||
uint32_t z_size = 0, z_size_max = 0, z_compressed_size;
|
uint32_t z_size = 0, z_size_max = 0, z_compressed_size, dict_len = 0;
|
||||||
uint8_t *z_buf = NULL;
|
uint8_t *z_buf = NULL, *dict = NULL;
|
||||||
|
|
||||||
/* Test a non overflow case */
|
/* Test a non overflow case */
|
||||||
if (flush_type == NO_FLUSH)
|
if (flush_type == NO_FLUSH)
|
||||||
@ -1617,17 +1652,32 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type)
|
|||||||
}
|
}
|
||||||
create_rand_repeat_data(z_buf, z_size);
|
create_rand_repeat_data(z_buf, z_size);
|
||||||
|
|
||||||
|
if (rand() % 8 == 0) {
|
||||||
|
dict_len = (rand() % IGZIP_HIST_SIZE) + 1;
|
||||||
|
dict = malloc(dict_len);
|
||||||
|
if (dict == NULL) {
|
||||||
|
print_error(MALLOC_FAILED);
|
||||||
|
return MALLOC_FAILED;
|
||||||
|
}
|
||||||
|
create_rand_dict(dict, dict_len, z_buf, z_size);
|
||||||
|
}
|
||||||
|
|
||||||
ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
|
ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
|
||||||
gzip_flag, level);
|
gzip_flag, level, dict, dict_len);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag);
|
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, dict, dict_len);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag);
|
printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag);
|
||||||
print_uint8_t(z_buf, z_size);
|
print_uint8_t(z_buf, z_size);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
if (dict != NULL) {
|
||||||
|
printf("Using Dictionary: ");
|
||||||
|
print_uint8_t(dict, dict_len);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
printf("Data: ");
|
printf("Data: ");
|
||||||
print_uint8_t(in_buf, in_size);
|
print_uint8_t(in_buf, in_size);
|
||||||
#endif
|
#endif
|
||||||
@ -1635,23 +1685,45 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type)
|
|||||||
print_error(ret);
|
print_error(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dict != NULL) {
|
||||||
|
free(dict);
|
||||||
|
dict = NULL;
|
||||||
|
dict_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
fin_ret |= ret;
|
fin_ret |= ret;
|
||||||
|
|
||||||
z_compressed_size = z_size;
|
z_compressed_size = z_size;
|
||||||
z_size = z_size_max;
|
z_size = z_size_max;
|
||||||
create_rand_repeat_data(z_buf, z_size_max);
|
create_rand_repeat_data(z_buf, z_size_max);
|
||||||
|
|
||||||
|
if (rand() % 8 == 0) {
|
||||||
|
dict_len = (rand() % IGZIP_HIST_SIZE) + 1;
|
||||||
|
dict = malloc(dict_len);
|
||||||
|
if (dict == NULL) {
|
||||||
|
print_error(MALLOC_FAILED);
|
||||||
|
return MALLOC_FAILED;
|
||||||
|
}
|
||||||
|
create_rand_dict(dict, dict_len, z_buf, z_size);
|
||||||
|
}
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level);
|
compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type, gzip_flag, level,
|
||||||
|
dict, dict_len);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag);
|
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, dict, dict_len);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag);
|
printf("Compressed array at level %d with gzip flag %d: ", level, gzip_flag);
|
||||||
print_uint8_t(z_buf, z_size);
|
print_uint8_t(z_buf, z_size);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
if (dict != NULL) {
|
||||||
|
printf("Using Dictionary: ");
|
||||||
|
print_uint8_t(dict, dict_len);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
printf("Data: ");
|
printf("Data: ");
|
||||||
print_uint8_t(in_buf, in_size);
|
print_uint8_t(in_buf, in_size);
|
||||||
#endif
|
#endif
|
||||||
@ -1659,6 +1731,12 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type)
|
|||||||
print_error(ret);
|
print_error(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dict != NULL) {
|
||||||
|
free(dict);
|
||||||
|
dict = NULL;
|
||||||
|
dict_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
fin_ret |= ret;
|
fin_ret |= ret;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -1671,11 +1749,13 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type)
|
|||||||
create_rand_repeat_data(z_buf, z_size_max);
|
create_rand_repeat_data(z_buf, z_size_max);
|
||||||
|
|
||||||
overflow = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
|
overflow = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
|
||||||
gzip_flag, level);
|
gzip_flag, level, dict, dict_len);
|
||||||
|
|
||||||
if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
|
if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
|
||||||
if (overflow == 0)
|
if (overflow == 0)
|
||||||
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag);
|
ret =
|
||||||
|
inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, dict,
|
||||||
|
dict_len);
|
||||||
|
|
||||||
/* Rarely single pass overflow will compresses data
|
/* Rarely single pass overflow will compresses data
|
||||||
* better than the initial run. This is to stop that
|
* better than the initial run. This is to stop that
|
||||||
@ -1707,11 +1787,13 @@ int test_compress(uint8_t * in_buf, uint32_t in_size, uint32_t flush_type)
|
|||||||
|
|
||||||
overflow =
|
overflow =
|
||||||
compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type,
|
compress_multi_pass(in_buf, in_size, z_buf, &z_size, flush_type,
|
||||||
gzip_flag, level);
|
gzip_flag, level, dict, dict_len);
|
||||||
|
|
||||||
if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
|
if (overflow != COMPRESS_OUT_BUFFER_OVERFLOW) {
|
||||||
if (overflow == 0)
|
if (overflow == 0)
|
||||||
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag);
|
ret =
|
||||||
|
inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag,
|
||||||
|
dict, dict_len);
|
||||||
|
|
||||||
/* Rarely multi pass overflow will compresses data
|
/* Rarely multi pass overflow will compresses data
|
||||||
* better than the initial run. This is to stop that
|
* better than the initial run. This is to stop that
|
||||||
@ -1775,7 +1857,7 @@ int test_flush(uint8_t * in_buf, uint32_t in_size)
|
|||||||
|
|
||||||
/* Test invalid flush */
|
/* Test invalid flush */
|
||||||
ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
|
ret = compress_single_pass(in_buf, in_size, z_buf, &z_size, flush_type,
|
||||||
gzip_flag, level);
|
gzip_flag, level, NULL, 0);
|
||||||
|
|
||||||
if (ret == COMPRESS_GENERAL_ERROR)
|
if (ret == COMPRESS_GENERAL_ERROR)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -1793,7 +1875,7 @@ int test_flush(uint8_t * in_buf, uint32_t in_size)
|
|||||||
ret = compress_swap_flush(in_buf, in_size, z_buf, &z_size, rand() % 3, gzip_flag);
|
ret = compress_swap_flush(in_buf, in_size, z_buf, &z_size, rand() % 3, gzip_flag);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag);
|
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
@ -1844,7 +1926,7 @@ int test_full_flush(uint8_t * in_buf, uint32_t in_size)
|
|||||||
ret = compress_full_flush(in_buf, in_size, z_buf, &z_size, gzip_flag, level);
|
ret = compress_full_flush(in_buf, in_size, z_buf, &z_size, gzip_flag, level);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag);
|
ret = inflate_check(z_buf, z_size, in_buf, in_size, gzip_flag, NULL, 0);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
#ifdef VERBOSE
|
#ifdef VERBOSE
|
||||||
@ -1887,7 +1969,8 @@ int test_inflate(struct vect_result *in_vector)
|
|||||||
ret = IGZIP_COMP_OK;
|
ret = IGZIP_COMP_OK;
|
||||||
|
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
ret = inflate_multi_pass(compress_buf, compress_len, out_buf, &out_size, 0);
|
ret = inflate_multi_pass(compress_buf, compress_len, out_buf, &out_size,
|
||||||
|
0, NULL, 0);
|
||||||
|
|
||||||
if (ret == INFLATE_LEFTOVER_INPUT)
|
if (ret == INFLATE_LEFTOVER_INPUT)
|
||||||
ret = ISAL_DECOMP_OK;
|
ret = ISAL_DECOMP_OK;
|
||||||
|
@ -89,6 +89,7 @@ FIELD _read_in_length,4, 4
|
|||||||
FIELD _lit_huff_code, _inflate_huff_code_large_size, _inflate_huff_code_large_align
|
FIELD _lit_huff_code, _inflate_huff_code_large_size, _inflate_huff_code_large_align
|
||||||
FIELD _dist_huff_code,_inflate_huff_code_small_size, _inflate_huff_code_small_align
|
FIELD _dist_huff_code,_inflate_huff_code_small_size, _inflate_huff_code_small_align
|
||||||
FIELD _block_state, 4, 4
|
FIELD _block_state, 4, 4
|
||||||
|
FIELD _dict_length, 4, 4
|
||||||
FIELD _bfinal, 4, 4
|
FIELD _bfinal, 4, 4
|
||||||
FIELD _crc_flag, 4, 4
|
FIELD _crc_flag, 4, 4
|
||||||
FIELD _crc, 4, 4
|
FIELD _crc, 4, 4
|
||||||
|
@ -156,7 +156,7 @@ enum {IGZIP_LIT_TABLE_SIZE = ISAL_DEF_LIT_SYMBOLS};
|
|||||||
#define STATELESS_OVERFLOW -1
|
#define STATELESS_OVERFLOW -1
|
||||||
#define ISAL_INVALID_OPERATION -9
|
#define ISAL_INVALID_OPERATION -9
|
||||||
#define ISAL_INVALID_LEVEL -4 /* Invalid Compression level set */
|
#define ISAL_INVALID_LEVEL -4 /* Invalid Compression level set */
|
||||||
|
#define ISAL_INVALID_STATE -3
|
||||||
/**
|
/**
|
||||||
* @enum isal_zstate_state
|
* @enum isal_zstate_state
|
||||||
* @brief Compression State please note ZSTATE_TRL only applies for GZIP compression
|
* @brief Compression State please note ZSTATE_TRL only applies for GZIP compression
|
||||||
@ -264,6 +264,10 @@ struct isal_mod_hist {
|
|||||||
#define ISAL_DEF_LVL1_EXTRA_LARGE (ISAL_DEF_LVL1_REQ + ISAL_DEF_LVL1_TOKEN_SIZE * 128 * IGZIP_K)
|
#define ISAL_DEF_LVL1_EXTRA_LARGE (ISAL_DEF_LVL1_REQ + ISAL_DEF_LVL1_TOKEN_SIZE * 128 * IGZIP_K)
|
||||||
#define ISAL_DEF_LVL1_DEFAULT ISAL_DEF_LVL1_LARGE
|
#define ISAL_DEF_LVL1_DEFAULT ISAL_DEF_LVL1_LARGE
|
||||||
|
|
||||||
|
#define IGZIP_NO_HIST 0
|
||||||
|
#define IGZIP_HIST 1
|
||||||
|
#define IGZIP_DICT_HIST 2
|
||||||
|
|
||||||
/** @brief Holds Bit Buffer information*/
|
/** @brief Holds Bit Buffer information*/
|
||||||
struct BitBuf2 {
|
struct BitBuf2 {
|
||||||
uint64_t m_bits; //!< bits in the bit buffer
|
uint64_t m_bits; //!< bits in the bit buffer
|
||||||
@ -410,6 +414,7 @@ struct inflate_state {
|
|||||||
struct inflate_huff_code_large lit_huff_code; //!< Structure for decoding lit/len symbols
|
struct inflate_huff_code_large lit_huff_code; //!< Structure for decoding lit/len symbols
|
||||||
struct inflate_huff_code_small dist_huff_code; //!< Structure for decoding dist symbols
|
struct inflate_huff_code_small dist_huff_code; //!< Structure for decoding dist symbols
|
||||||
enum isal_block_state block_state; //!< Current decompression state
|
enum isal_block_state block_state; //!< Current decompression state
|
||||||
|
uint32_t dict_length; //!< Length of dictionary used
|
||||||
uint32_t bfinal; //!< Flag identifying final block
|
uint32_t bfinal; //!< Flag identifying final block
|
||||||
uint32_t crc_flag; //!< Flag identifying whether to track of crc
|
uint32_t crc_flag; //!< Flag identifying whether to track of crc
|
||||||
uint32_t crc; //!< Contains crc of output if crc_flag is set
|
uint32_t crc; //!< Contains crc of output if crc_flag is set
|
||||||
@ -506,6 +511,22 @@ int isal_deflate_set_hufftables(struct isal_zstream *stream,
|
|||||||
void isal_deflate_stateless_init(struct isal_zstream *stream);
|
void isal_deflate_stateless_init(struct isal_zstream *stream);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set compression dictionary to use
|
||||||
|
*
|
||||||
|
* This function is to be called after isal_deflate_init, or after completing a
|
||||||
|
* SYNC_FLUSH or FULL_FLUSH and before the next call do isal_deflate. If the
|
||||||
|
* dictionary is longer than IGZIP_HIST_SIZE, only the last IGZIP_HIST_SIZE
|
||||||
|
* bytes will be used.
|
||||||
|
*
|
||||||
|
* @param stream Structure holding state information on the compression streams.
|
||||||
|
* @param dict: Array containing dictionary to use.
|
||||||
|
* @param dict_len: Lenth of dict.
|
||||||
|
* @returns COMP_OK,
|
||||||
|
* ISAL_INVALID_STATE (dictionary could not be set)
|
||||||
|
*/
|
||||||
|
int isal_deflate_set_dict(struct isal_zstream *stream, uint8_t *dict, uint32_t dict_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fast data (deflate) compression for storage applications.
|
* @brief Fast data (deflate) compression for storage applications.
|
||||||
*
|
*
|
||||||
@ -546,6 +567,9 @@ void isal_deflate_stateless_init(struct isal_zstream *stream);
|
|||||||
* not include previous blocks so new blocks are fully independent. Switching
|
* not include previous blocks so new blocks are fully independent. Switching
|
||||||
* between flush types is supported.
|
* between flush types is supported.
|
||||||
*
|
*
|
||||||
|
* If a compression dictionary is required, the dictionary can be set calling
|
||||||
|
* isal_deflate_set_dictionary before calling isal_deflate.
|
||||||
|
*
|
||||||
* If the gzip_flag is set to IGZIP_GZIP, a generic gzip header and the gzip
|
* If the gzip_flag is set to IGZIP_GZIP, a generic gzip header and the gzip
|
||||||
* trailer are written around the deflate compressed data. If gzip_flag is set
|
* trailer are written around the deflate compressed data. If gzip_flag is set
|
||||||
* to IGZIP_GZIP_NO_HDR, then only the gzip trailer is written.
|
* to IGZIP_GZIP_NO_HDR, then only the gzip trailer is written.
|
||||||
@ -598,6 +622,21 @@ int isal_deflate_stateless(struct isal_zstream *stream);
|
|||||||
*/
|
*/
|
||||||
void isal_inflate_init(struct inflate_state *state);
|
void isal_inflate_init(struct inflate_state *state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set decompression dictionary to use
|
||||||
|
*
|
||||||
|
* This function is to be called after isal_inflate_init. If the dictionary is
|
||||||
|
* longer than IGZIP_HIST_SIZE, only the last IGZIP_HIST_SIZE bytes will be
|
||||||
|
* used.
|
||||||
|
*
|
||||||
|
* @param state: Structure holding state information on the decompression stream.
|
||||||
|
* @param dict: Array containing dictionary to use.
|
||||||
|
* @param dict_len: Lenth of dict.
|
||||||
|
* @returns COMP_OK,
|
||||||
|
* ISAL_INVALID_STATE (dictionary could not be set)
|
||||||
|
*/
|
||||||
|
int isal_inflate_set_dict(struct inflate_state *state, uint8_t *dict, uint32_t dict_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Fast data (deflate) decompression for storage applications.
|
* @brief Fast data (deflate) decompression for storage applications.
|
||||||
*
|
*
|
||||||
@ -617,6 +656,9 @@ void isal_inflate_init(struct inflate_state *state);
|
|||||||
* in state->crc. Alternatively, if the crc_flag is set to ISAL_ZLIB_NO_HDR the
|
* in state->crc. Alternatively, if the crc_flag is set to ISAL_ZLIB_NO_HDR the
|
||||||
* adler32 of the output is stored in state->crc.
|
* adler32 of the output is stored in state->crc.
|
||||||
*
|
*
|
||||||
|
* If a dictionary is required, a call to isal_inflate_set_dict will set the
|
||||||
|
* dictionary.
|
||||||
|
*
|
||||||
* @param state Structure holding state information on the compression streams.
|
* @param state Structure holding state information on the compression streams.
|
||||||
* @return ISAL_DECOMP_OK (if everything is ok),
|
* @return ISAL_DECOMP_OK (if everything is ok),
|
||||||
* ISAL_END_INPUT (if all input was decompressed),
|
* ISAL_END_INPUT (if all input was decompressed),
|
||||||
@ -625,6 +667,7 @@ void isal_inflate_init(struct inflate_state *state);
|
|||||||
* ISAL_INVALID_SYMBOL,
|
* ISAL_INVALID_SYMBOL,
|
||||||
* ISAL_INVALID_LOOKBACK.
|
* ISAL_INVALID_LOOKBACK.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int isal_inflate(struct inflate_state *state);
|
int isal_inflate(struct inflate_state *state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user