From 34c341db357b6638072d9f26dfa40b82f990bfa8 Mon Sep 17 00:00:00 2001 From: Roy Oursler Date: Wed, 21 Jun 2017 14:05:33 -0700 Subject: [PATCH] igzip: Add reset functions for both deflate and inflate. Change-Id: I8677a4365ac5c2343751660176f3b2eb4746ddfe Signed-off-by: Roy Oursler --- igzip/data_struct2.asm | 2 + igzip/igzip.c | 46 ++++++++++++-- igzip/igzip_inflate.c | 20 ++++++ igzip/igzip_rand_test.c | 137 ++++++++++++++++++++++++++++++++++++++-- include/igzip_lib.h | 20 ++++++ 5 files changed, 217 insertions(+), 8 deletions(-) diff --git a/igzip/data_struct2.asm b/igzip/data_struct2.asm index 56d304f..edac60d 100644 --- a/igzip/data_struct2.asm +++ b/igzip/data_struct2.asm @@ -129,6 +129,7 @@ FIELD _count, 4, 4 FIELD _tmp_out_buff, 16, 1 FIELD _tmp_out_start, 4, 4 FIELD _tmp_out_end, 4, 4 +FIELD _has_wrap_hdr, 4, 4 FIELD _has_eob, 4, 4 FIELD _has_eob_hdr, 4, 4 FIELD _has_hist, 4, 4 @@ -182,6 +183,7 @@ _internal_state_count equ _internal_state+_count _internal_state_tmp_out_buff equ _internal_state+_tmp_out_buff _internal_state_tmp_out_start equ _internal_state+_tmp_out_start _internal_state_tmp_out_end equ _internal_state+_tmp_out_end +_internal_state_has_wrap_hdr equ _internal_state+_has_wrap_hdr _internal_state_has_eob equ _internal_state+_has_eob _internal_state_has_eob_hdr equ _internal_state+_has_eob_hdr _internal_state_has_hist equ _internal_state+_has_hist diff --git a/igzip/igzip.c b/igzip/igzip.c index 390bfa5..01fcb0b 100644 --- a/igzip/igzip.c +++ b/igzip/igzip.c @@ -114,6 +114,9 @@ struct slver { struct slver isal_deflate_init_slver_01030081; struct slver isal_deflate_init_slver = { 0x0081, 0x03, 0x01 }; +struct slver isal_deflate_reset_slver_0001008e; +struct slver isal_deflate_reset_slver = { 0x008e, 0x01, 0x00 }; + struct slver isal_deflate_stateless_init_slver_00010084; struct slver isal_deflate_stateless_init_slver = { 0x0084, 0x01, 0x00 }; @@ -788,6 +791,7 @@ void isal_deflate_init(struct isal_zstream *stream) state->b_bytes_valid = 0; state->b_bytes_processed = 0; + state->has_wrap_hdr = 0; state->has_eob = 0; state->has_eob_hdr = 0; state->has_hist = IGZIP_NO_HIST; @@ -804,6 +808,31 @@ void isal_deflate_init(struct isal_zstream *stream) return; } +void isal_deflate_reset(struct isal_zstream *stream) +{ + struct isal_zstate *state = &stream->internal_state; + + stream->total_in = 0; + stream->total_out = 0; + + state->b_bytes_valid = 0; + state->b_bytes_processed = 0; + state->has_wrap_hdr = 0; + state->has_eob = 0; + state->has_eob_hdr = 0; + state->has_hist = IGZIP_NO_HIST; + state->state = ZSTATE_NEW_HDR; + state->count = 0; + + state->tmp_out_start = 0; + state->tmp_out_end = 0; + + init(&state->bitbuf); + + state->crc = 0; + +} + int isal_deflate_set_hufftables(struct isal_zstream *stream, struct isal_hufftables *hufftables, int type) { @@ -840,6 +869,7 @@ void isal_deflate_stateless_init(struct isal_zstream *stream) stream->end_of_stream = 0; stream->flush = NO_FLUSH; stream->gzip_flag = 0; + stream->internal_state.has_wrap_hdr = 0; stream->internal_state.state = ZSTATE_NEW_HDR; return; } @@ -880,6 +910,7 @@ int isal_deflate_set_dict(struct isal_zstream *stream, uint8_t * dict, uint32_t int isal_deflate_stateless(struct isal_zstream *stream) { + struct isal_zstate *state = &stream->internal_state; uint8_t *next_in = stream->next_in; const uint32_t avail_in = stream->avail_in; const uint32_t total_in = stream->total_in; @@ -888,6 +919,7 @@ int isal_deflate_stateless(struct isal_zstream *stream) const uint32_t avail_out = stream->avail_out; const uint32_t total_out = stream->total_out; const uint32_t gzip_flag = stream->gzip_flag; + const uint32_t has_wrap_hdr = state->has_wrap_hdr; uint32_t stored_len; @@ -958,6 +990,7 @@ int isal_deflate_stateless(struct isal_zstream *stream) stream->total_out = total_out; stream->gzip_flag = gzip_flag; + state->has_wrap_hdr = has_wrap_hdr; init(&stream->internal_state.bitbuf); stream->internal_state.count = 0; @@ -1085,10 +1118,14 @@ static int write_stream_header_stateless(struct isal_zstream *stream) const uint8_t *hdr; uint32_t next_flag; + if (stream->internal_state.has_wrap_hdr) + return COMP_OK; + if (stream->gzip_flag == IGZIP_ZLIB) { hdr_bytes = zlib_hdr_bytes; hdr = zlib_hdr; next_flag = IGZIP_ZLIB_NO_HDR; + } else { hdr_bytes = gzip_hdr_bytes; hdr = gzip_hdr; @@ -1104,6 +1141,7 @@ static int write_stream_header_stateless(struct isal_zstream *stream) memcpy(stream->next_out, hdr, hdr_bytes); stream->next_out += hdr_bytes; + stream->internal_state.has_wrap_hdr = 1; stream->gzip_flag = next_flag; return COMP_OK; @@ -1115,16 +1153,16 @@ static void write_stream_header(struct isal_zstream *stream) int bytes_to_write; uint32_t hdr_bytes; const uint8_t *hdr; - uint32_t next_flag; + + if (stream->internal_state.has_wrap_hdr) + return; if (stream->gzip_flag == IGZIP_ZLIB) { hdr_bytes = zlib_hdr_bytes; hdr = zlib_hdr; - next_flag = IGZIP_ZLIB_NO_HDR; } else { hdr_bytes = gzip_hdr_bytes; hdr = gzip_hdr; - next_flag = IGZIP_GZIP_NO_HDR; } bytes_to_write = hdr_bytes; @@ -1138,7 +1176,7 @@ static void write_stream_header(struct isal_zstream *stream) if (state->count == hdr_bytes) { state->count = 0; - stream->gzip_flag = next_flag; + state->has_wrap_hdr = 1; } stream->avail_out -= bytes_to_write; diff --git a/igzip/igzip_inflate.c b/igzip/igzip_inflate.c index 1fcf654..6b3f1f0 100644 --- a/igzip/igzip_inflate.c +++ b/igzip/igzip_inflate.c @@ -81,6 +81,9 @@ struct slver { struct slver isal_inflate_init_slver_00010088; struct slver isal_inflate_init_slver = { 0x0088, 0x01, 0x00 }; +struct slver isal_inflate_reset_slver_0001008f; +struct slver isal_inflate_reset_slver = { 0x008f, 0x01, 0x00 }; + struct slver isal_inflate_stateless_slver_00010089; struct slver isal_inflate_stateless_slver = { 0x0089, 0x01, 0x00 }; @@ -1119,6 +1122,23 @@ void isal_inflate_init(struct inflate_state *state) state->tmp_out_valid = 0; } +void isal_inflate_reset(struct inflate_state *state) +{ + state->read_in = 0; + state->read_in_length = 0; + state->total_out = 0; + state->dict_length = 0; + state->block_state = ISAL_BLOCK_NEW_HDR; + state->bfinal = 0; + state->crc = 0; + state->type0_block_len = 0; + state->copy_overflow_length = 0; + state->copy_overflow_distance = 0; + state->tmp_in_size = 0; + state->tmp_out_processed = 0; + state->tmp_out_valid = 0; +} + int isal_inflate_set_dict(struct inflate_state *state, uint8_t * dict, uint32_t dict_len) { diff --git a/igzip/igzip_rand_test.c b/igzip/igzip_rand_test.c index 5f713ec..e93f792 100644 --- a/igzip/igzip_rand_test.c +++ b/igzip/igzip_rand_test.c @@ -467,6 +467,7 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len, uint32_t comp_tmp_size = 0, uncomp_tmp_size = 0; uint32_t comp_processed = 0, uncomp_processed = 0; int32_t read_in_old = 0; + uint32_t reset_test_flag = 0; state = malloc(sizeof(struct inflate_state)); if (state == NULL) { @@ -474,10 +475,14 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len, exit(0); } + create_rand_repeat_data((uint8_t *) state, sizeof(state)); isal_inflate_init(state); - if (dict != NULL) - isal_inflate_set_dict(state, dict, dict_len); + if (rand() % 4 == 0) { + /* Test reset */ + reset_test_flag = 1; + create_rand_repeat_data((uint8_t *) state, sizeof(state)); + } state->next_in = NULL; state->next_out = NULL; @@ -485,6 +490,12 @@ int inflate_multi_pass(uint8_t * compress_buf, uint64_t compress_len, state->avail_out = 0; state->crc_flag = gzip_flag; + if (reset_test_flag) + isal_inflate_reset(state); + + if (dict != NULL) + isal_inflate_set_dict(state, dict, dict_len); + if (gzip_flag == IGZIP_GZIP || gzip_flag == IGZIP_GZIP_NO_HDR) compress_len -= gzip_trl_bytes; else if (gzip_flag == IGZIP_ZLIB || gzip_flag == IGZIP_ZLIB_NO_HDR) @@ -836,6 +847,8 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed uint32_t loop_count = 0; uint32_t level_buf_size; uint8_t *level_buf = NULL; + struct isal_hufftables *huff_tmp; + uint32_t reset_test_flag = 0; #ifdef VERBOSE printf("Starting Compress Multi Pass\n"); @@ -848,6 +861,20 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed if (state->state != ZSTATE_NEW_HDR) return COMPRESS_INCORRECT_STATE; + if (rand() % 4 == 0) { + /* Test reset */ + reset_test_flag = 1; + huff_tmp = stream.hufftables; + create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); + + /* Restore variables not necessarily set by user */ + stream.hufftables = huff_tmp; + stream.end_of_stream = 0; + stream.level = 0; + stream.level_buf = NULL; + stream.level_buf_size = 0; + } + stream.flush = flush_type; stream.end_of_stream = 0; @@ -865,6 +892,12 @@ int compress_multi_pass(uint8_t * data, uint32_t data_size, uint8_t * compressed stream.level_buf_size = level_buf_size; } + if (reset_test_flag) + isal_deflate_reset(&stream); + + if (dict != NULL) + isal_deflate_set_dict(&stream, dict, dict_len); + while (1) { loop_count++; @@ -982,6 +1015,8 @@ int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compresse struct isal_zstate *state = &stream.internal_state; uint32_t level_buf_size; uint8_t *level_buf = NULL; + struct isal_hufftables *huff_tmp; + uint32_t reset_test_flag = 0; #ifdef VERBOSE printf("Starting Compress Single Pass\n"); @@ -996,8 +1031,19 @@ int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compresse if (state->state != ZSTATE_NEW_HDR) return COMPRESS_INCORRECT_STATE; - if (dict != NULL) - isal_deflate_set_dict(&stream, dict, dict_len); + if (rand() % 4 == 0) { + /* Test reset */ + reset_test_flag = 1; + huff_tmp = stream.hufftables; + create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); + + /* Restore variables not necessarily set by user */ + stream.hufftables = huff_tmp; + stream.end_of_stream = 0; + stream.level = 0; + stream.level_buf = NULL; + stream.level_buf_size = 0; + } stream.flush = flush_type; stream.avail_in = data_size; @@ -1016,6 +1062,11 @@ int compress_single_pass(uint8_t * data, uint32_t data_size, uint8_t * compresse stream.level_buf_size = level_buf_size; } + if (reset_test_flag) + isal_deflate_reset(&stream); + + if (dict != NULL) + isal_deflate_set_dict(&stream, dict, dict_len); ret = isal_deflate_with_checks(&stream, data_size, *compressed_size, data, data_size, data_size, compressed_buf, *compressed_size, 0); @@ -1042,6 +1093,8 @@ int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_ struct isal_zstream stream; uint32_t level_buf_size; uint8_t *level_buf = NULL; + struct isal_hufftables *huff_tmp; + uint32_t reset_test_flag = 0; create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); @@ -1049,6 +1102,20 @@ int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_ set_random_hufftable(&stream); + if (rand() % 4 == 0) { + /* Test reset */ + reset_test_flag = 1; + huff_tmp = stream.hufftables; + create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); + + /* Restore variables not necessarily set by user */ + stream.hufftables = huff_tmp; + stream.end_of_stream = 0; + stream.level = 0; + stream.level_buf = NULL; + stream.level_buf_size = 0; + } + stream.avail_in = data_size; stream.next_in = data; stream.flush = flush_type; @@ -1061,6 +1128,7 @@ int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_ if (level >= 1) { level_buf_size = rand() % IBUF_SIZE; + /* printf("level_buf_size = %d\n", level_buf_size); */ if (level_buf_size >= ISAL_DEF_LVL1_MIN) { level_buf = malloc(level_buf_size); create_rand_repeat_data(level_buf, level_buf_size); @@ -1069,6 +1137,10 @@ int compress_stateless(uint8_t * data, uint32_t data_size, uint8_t * compressed_ } } + if (reset_test_flag) { + isal_deflate_reset(&stream); + /* printf("post reset level_buf_size = %d\n", level_buf_size); */ + } ret = isal_deflate_stateless(&stream); if (level_buf != NULL) @@ -1116,6 +1188,8 @@ int compress_stateless_full_flush(uint8_t * data, uint32_t data_size, uint8_t * uint32_t in_processed = 00; struct isal_zstream stream; uint32_t loop_count = 0; + struct isal_hufftables *huff_tmp; + uint32_t reset_test_flag = 0; #ifdef VERBOSE printf("Starting Stateless Compress Full Flush\n"); @@ -1125,6 +1199,20 @@ int compress_stateless_full_flush(uint8_t * data, uint32_t data_size, uint8_t * isal_deflate_stateless_init(&stream); + if (rand() % 4 == 0) { + /* Test reset */ + reset_test_flag = 1; + huff_tmp = stream.hufftables; + create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); + + /* Restore variables not necessarily set by user */ + stream.hufftables = huff_tmp; + stream.end_of_stream = 0; + stream.level = 0; + stream.level_buf = NULL; + stream.level_buf_size = 0; + } + stream.flush = FULL_FLUSH; stream.end_of_stream = 0; stream.avail_out = *compressed_size; @@ -1141,6 +1229,9 @@ int compress_stateless_full_flush(uint8_t * data, uint32_t data_size, uint8_t * } } + if (reset_test_flag) + isal_deflate_reset(&stream); + while (1) { loop_count++; @@ -1228,6 +1319,8 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed struct isal_zstream stream; struct isal_zstate *state = &stream.internal_state; uint32_t loop_count = 0; + struct isal_hufftables *huff_tmp; + uint32_t reset_test_flag = 0; #ifdef VERBOSE printf("Starting Compress Full Flush\n"); @@ -1240,6 +1333,20 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed if (state->state != ZSTATE_NEW_HDR) return COMPRESS_INCORRECT_STATE; + if (rand() % 4 == 0) { + /* Test reset */ + reset_test_flag = 1; + huff_tmp = stream.hufftables; + create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); + + /* Restore variables not necessarily set by user */ + stream.hufftables = huff_tmp; + stream.end_of_stream = 0; + stream.level = 0; + stream.level_buf = NULL; + stream.level_buf_size = 0; + } + stream.flush = FULL_FLUSH; stream.end_of_stream = 0; stream.avail_out = *compressed_size; @@ -1258,6 +1365,9 @@ int compress_full_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed } } + if (reset_test_flag) + isal_deflate_reset(&stream); + while (1) { loop_count++; @@ -1344,6 +1454,8 @@ int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed struct isal_zstream stream; struct isal_zstate *state = &stream.internal_state; uint32_t partial_size; + struct isal_hufftables *huff_tmp; + uint32_t reset_test_flag = 0; #ifdef VERBOSE printf("Starting Compress Swap Flush\n"); @@ -1356,6 +1468,20 @@ int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed if (state->state != ZSTATE_NEW_HDR) return COMPRESS_INCORRECT_STATE; + if (rand() % 4 == 0) { + /* Test reset */ + reset_test_flag = 1; + huff_tmp = stream.hufftables; + create_rand_repeat_data((uint8_t *) & stream, sizeof(stream)); + + /* Restore variables not necessarily set by user */ + stream.hufftables = huff_tmp; + stream.end_of_stream = 0; + stream.level = 0; + stream.level_buf = NULL; + stream.level_buf_size = 0; + } + partial_size = rand() % (data_size + 1); stream.flush = flush_type; @@ -1366,6 +1492,9 @@ int compress_swap_flush(uint8_t * data, uint32_t data_size, uint8_t * compressed stream.end_of_stream = 0; stream.gzip_flag = gzip_flag; + if (reset_test_flag) + isal_deflate_reset(&stream); + ret = isal_deflate_with_checks(&stream, data_size, *compressed_size, data, partial_size, partial_size, compressed_buf, *compressed_size, 0); diff --git a/include/igzip_lib.h b/include/igzip_lib.h index a7098db..a51a4da 100644 --- a/include/igzip_lib.h +++ b/include/igzip_lib.h @@ -294,6 +294,7 @@ struct isal_zstate { uint8_t tmp_out_buff[16]; //!< temporary array uint32_t tmp_out_start; //!< temporary variable uint32_t tmp_out_end; //!< temporary variable + uint32_t has_wrap_hdr; //!< keeps track of wrapper header uint32_t has_eob; //!< keeps track of eob on the last deflate block uint32_t has_eob_hdr; //!< keeps track of eob hdr (with BFINAL set) uint32_t has_hist; //!< flag to track if there is match history @@ -479,6 +480,17 @@ int isal_create_hufftables_subset(struct isal_hufftables * hufftables, */ void isal_deflate_init(struct isal_zstream *stream); +/** + * @brief Reinitialize compression stream data structure. Performs the same + * action as isal_deflate_init, but does not change user supplied input such as + * the level, flush type, compression wrapper (like gzip), hufftables, and + * end_of_stream_flag. + * + * @param stream Structure holding state information on the compression streams. + * @returns none + */ +void isal_deflate_reset(struct isal_zstream *stream); + /** * @brief Set stream to use a new Huffman code * @@ -622,6 +634,14 @@ int isal_deflate_stateless(struct isal_zstream *stream); */ void isal_inflate_init(struct inflate_state *state); +/** + * @brief Reinitialize decompression state data structure + * + * @param state Structure holding state information on the compression streams. + * @returns none + */ +void isal_inflate_reset(struct inflate_state *state); + /** * @brief Set decompression dictionary to use *