static int isal_deflate_int_stateless(struct isal_zstream *stream) { uint32_t repeat_length; struct isal_zstate *state = &stream->internal_state; if (stream->gzip_flag == IGZIP_GZIP) if (write_gzip_header_stateless(stream)) return STATELESS_OVERFLOW; if (stream->avail_in >= 8 && (*(uint64_t *) stream->next_in == 0 || *(uint64_t *) stream->next_in == ~(uint64_t) 0)) { repeat_length = detect_repeated_char_length(stream->next_in, stream->avail_in); if (stream->avail_in == repeat_length || repeat_length >= MIN_REPEAT_LEN) write_constant_compressed_stateless(stream, repeat_length); } if (stream->level == 0) { if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_HDR) { write_deflate_header_unaligned_stateless(stream); if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_HDR) return STATELESS_OVERFLOW; reset_match_history(stream); } state->file_start = stream->next_in - stream->total_in; isal_deflate_pass(stream); } else if (stream->level == 1) { if (stream->level_buf == NULL || stream->level_buf_size < ISAL_DEF_LVL1_MIN) { /* Default to internal buffer if invalid size is supplied */ stream->level_buf = state->buffer; stream->level_buf_size = sizeof(state->buffer); } if (state->state == ZSTATE_NEW_HDR || state->state == ZSTATE_HDR) reset_match_history(stream); state->count = 0; state->file_start = stream->next_in - stream->total_in; isal_deflate_icf_pass(stream); } else return ISAL_INVALID_LEVEL; if (state->state == ZSTATE_END || (state->state == ZSTATE_NEW_HDR && stream->flush == FULL_FLUSH)) return COMP_OK; else return STATELESS_OVERFLOW; }
void isal_deflate_init_01(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; stream->total_in = 0; stream->total_out = 0; stream->hufftables = (struct isal_hufftables *)&hufftables_default; stream->flush = 0; state->b_bytes_valid = 0; state->b_bytes_processed = 0; state->has_eob = 0; state->has_eob_hdr = 0; state->left_over = 0; state->last_flush = 0; state->has_gzip_hdr = 0; state->state = ZSTATE_NEW_HDR; state->count = 0; state->tmp_out_start = 0; state->tmp_out_end = 0; state->file_start = state->buffer; init(&state->bitbuf); memset(state->crc, 0, sizeof(state->crc)); *state->crc = 0x9db42487; reset_match_history(stream); return; }
static void sync_flush(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; uint64_t bits_to_write = 0xFFFF0000, bits_len; uint64_t code = 0, len = 0, bytes; int flush_size; if (stream->avail_out >= 8) { set_buf(&state->bitbuf, stream->next_out, stream->avail_out); if (!state->has_eob) get_lit_code(stream->hufftables, 256, &code, &len); flush_size = (-(state->bitbuf.m_bit_count + len + 3)) % 8; bits_to_write <<= flush_size + 3; bits_len = 32 + len + flush_size + 3; #ifdef USE_BITBUFB /* Write Bits Always */ state->state = ZSTATE_NEW_HDR; #else /* Not Write Bits Always */ state->state = ZSTATE_FLUSH_WRITE_BUFFER; #endif state->has_eob = 0; if (len > 0) bits_to_write = (bits_to_write << len) | code; write_bits(&state->bitbuf, bits_to_write, bits_len); bytes = buffer_used(&state->bitbuf); stream->next_out = buffer_ptr(&state->bitbuf); stream->avail_out -= bytes; stream->total_out += bytes; if (stream->flush == FULL_FLUSH) { /* Clear match history so there are no cross * block length distance pairs */ reset_match_history(stream); } } }
static void sync_flush(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; uint64_t bits_to_write = 0xFFFF0000, bits_len; uint64_t bytes; int flush_size; if (stream->avail_out >= 8) { set_buf(&state->bitbuf, stream->next_out, stream->avail_out); flush_size = (-(state->bitbuf.m_bit_count + 3)) % 8; bits_to_write <<= flush_size + 3; bits_len = 32 + flush_size + 3; #ifdef USE_BITBUFB /* Write Bits Always */ state->state = ZSTATE_NEW_HDR; #else /* Not Write Bits Always */ state->state = ZSTATE_FLUSH_WRITE_BUFFER; #endif state->has_eob = 0; write_bits(&state->bitbuf, bits_to_write, bits_len); bytes = buffer_used(&state->bitbuf); stream->next_out = buffer_ptr(&state->bitbuf); stream->avail_out -= bytes; stream->total_out += bytes; if (stream->flush == FULL_FLUSH) { /* Clear match history so there are no cross * block length distance pairs */ state->file_start -= state->b_bytes_processed; state->b_bytes_valid -= state->b_bytes_processed; state->b_bytes_processed = 0; reset_match_history(stream); } } }
int isal_deflate_stateless(struct isal_zstream *stream) { uint8_t *next_in = stream->next_in; const uint32_t avail_in = stream->avail_in; const uint32_t total_in = stream->total_in; uint8_t *next_out = stream->next_out; const uint32_t avail_out = stream->avail_out; const uint32_t total_out = stream->total_out; const uint32_t gzip_flag = stream->gzip_flag; uint32_t crc32 = 0; uint32_t stored_len; /* Final block has already been written */ stream->internal_state.has_eob_hdr = 0; init(&stream->internal_state.bitbuf); stream->internal_state.state = ZSTATE_NEW_HDR; stream->internal_state.crc = 0; if (stream->flush == NO_FLUSH) stream->end_of_stream = 1; if (stream->flush != NO_FLUSH && stream->flush != FULL_FLUSH) return INVALID_FLUSH; if (stream->level != 0 && stream->level != 1) return ISAL_INVALID_LEVEL; if (avail_in == 0) stored_len = STORED_BLK_HDR_BZ; else stored_len = STORED_BLK_HDR_BZ * ((avail_in + STORED_BLK_MAX_BZ - 1) / STORED_BLK_MAX_BZ) + avail_in; /* at least 1 byte compressed data in the case of empty dynamic block which only contains the EOB */ if (stream->gzip_flag == IGZIP_GZIP) stored_len += gzip_hdr_bytes + gzip_trl_bytes; else if (stream->gzip_flag == IGZIP_GZIP_NO_HDR) stored_len += gzip_trl_bytes; /* the output buffer should be no less than 8 bytes while empty stored deflate block is 5 bytes only */ if (stream->avail_out < 8) return STATELESS_OVERFLOW; if (isal_deflate_int_stateless(stream) == COMP_OK) return COMP_OK; else { if (stream->flush == FULL_FLUSH) { stream->internal_state.file_start = (uint8_t *) & stream->internal_state.buffer; reset_match_history(stream); } stream->internal_state.has_eob_hdr = 0; } if (avail_out < stored_len) return STATELESS_OVERFLOW; stream->next_in = next_in; stream->avail_in = avail_in; stream->total_in = total_in; stream->next_out = next_out; stream->avail_out = avail_out; stream->total_out = total_out; stream->gzip_flag = gzip_flag; if (stream->gzip_flag) crc32 = crc32_gzip(0x0, next_in, avail_in); return write_stored_block_stateless(stream, stored_len, crc32); }