static void flush_icf_block(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; struct level_2_buf *level_buf = (struct level_2_buf *)stream->level_buf; struct BitBuf2 *write_buf = &state->bitbuf; struct deflate_icf *icf_buf_encoded_next; set_buf(write_buf, stream->next_out, stream->avail_out); #if defined (USE_BITBUF8) || (USE_BITBUF_ELSE) if (!is_full(write_buf)) flush_bits(write_buf); #endif icf_buf_encoded_next = encode_deflate_icf(level_buf->icf_buf_start + state->count, level_buf->icf_buf_next, write_buf, &level_buf->encode_tables); state->count = icf_buf_encoded_next - level_buf->icf_buf_start; stream->next_out = buffer_ptr(write_buf); stream->total_out += buffer_used(write_buf); stream->avail_out -= buffer_used(write_buf); if (level_buf->icf_buf_next <= icf_buf_encoded_next) { state->count = 0; if (stream->avail_in == 0 && stream->end_of_stream) state->state = ZSTATE_TRL; else if (stream->avail_in == 0 && stream->flush != NO_FLUSH) state->state = ZSTATE_SYNC_FLUSH; else state->state = ZSTATE_NEW_HDR; } }
static void create_icf_block_hdr(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; struct level_2_buf *level_buf = (struct level_2_buf *)stream->level_buf; struct BitBuf2 *write_buf = &state->bitbuf; struct BitBuf2 write_buf_tmp; uint32_t out_size = stream->avail_out; uint8_t *end_out = stream->next_out + out_size; /* Write EOB in icf_buf */ state->hist.ll_hist[256] = 1; level_buf->icf_buf_next->lit_len = 0x100; level_buf->icf_buf_next->lit_dist = NULL_DIST_SYM; level_buf->icf_buf_next->dist_extra = 0; level_buf->icf_buf_next++; state->has_eob_hdr = stream->end_of_stream && !stream->avail_in; if (end_out - stream->next_out >= ISAL_DEF_MAX_HDR_SIZE) { /* Determine whether this is the final block */ if (stream->gzip_flag == IGZIP_GZIP) write_gzip_header_stateless(stream); set_buf(write_buf, stream->next_out, stream->avail_out); create_hufftables_icf(write_buf, &level_buf->encode_tables, &state->hist, state->has_eob_hdr); state->state = ZSTATE_FLUSH_ICF_BUFFER; stream->next_out = buffer_ptr(write_buf); stream->total_out += buffer_used(write_buf); stream->avail_out -= buffer_used(write_buf); } else { /* Start writing into temporary buffer */ write_buf_tmp.m_bits = write_buf->m_bits; write_buf_tmp.m_bit_count = write_buf->m_bit_count; write_buf->m_bits = 0; write_buf->m_bit_count = 0; set_buf(&write_buf_tmp, level_buf->deflate_hdr, ISAL_DEF_MAX_HDR_SIZE); create_hufftables_icf(&write_buf_tmp, &level_buf->encode_tables, &state->hist, state->has_eob_hdr); level_buf->deflate_hdr_count = buffer_used(&write_buf_tmp); level_buf->deflate_hdr_extra_bits = write_buf_tmp.m_bit_count; flush(&write_buf_tmp); state->state = ZSTATE_HDR; } }
static int write_deflate_header_stateless(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; struct isal_hufftables *hufftables = stream->hufftables; uint32_t count; if (hufftables->deflate_hdr_count + 8 >= stream->avail_out) return STATELESS_OVERFLOW; memcpy(stream->next_out, hufftables->deflate_hdr, hufftables->deflate_hdr_count); stream->avail_out -= hufftables->deflate_hdr_count; stream->total_out += hufftables->deflate_hdr_count; stream->next_out += hufftables->deflate_hdr_count; set_buf(&state->bitbuf, stream->next_out, stream->avail_out); write_bits(&state->bitbuf, hufftables->deflate_hdr[hufftables->deflate_hdr_count], hufftables->deflate_hdr_extra_bits); count = buffer_used(&state->bitbuf); stream->next_out = buffer_ptr(&state->bitbuf); stream->avail_out -= count; stream->total_out += count; return COMP_OK; }
static int buffer_unused (Priv * p) { int ret; ret = p->buffer_size - buffer_used (p) - 1; /* 1 byte for indicating full */ return ret; }
int buffer_to_fd(buffer_t *buf, int fd) { int towrite = buffer_used(buf); if(towrite == 0) /* Shouldn't be called in this case! */ abort(); towrite = write(fd, buf->data, towrite); if(towrite > 0) { buffer_takedata(buf, NULL, towrite); buf->total_out += towrite; } return towrite; }
static void flush_write_buffer(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; int bytes = 0; if (stream->avail_out >= 8) { set_buf(&state->bitbuf, stream->next_out, stream->avail_out); flush(&state->bitbuf); stream->next_out = buffer_ptr(&state->bitbuf); bytes = buffer_used(&state->bitbuf); stream->avail_out -= bytes; stream->total_out += bytes; state->state = ZSTATE_NEW_HDR; } }
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); } } }
static int write_deflate_header_stateless(struct isal_zstream *stream) { struct isal_zstate *state = &stream->internal_state; struct isal_hufftables *hufftables = stream->hufftables; uint64_t hdr_extra_bits = hufftables->deflate_hdr[hufftables->deflate_hdr_count]; uint32_t count; if (hufftables->deflate_hdr_count + 8 >= stream->avail_out) return STATELESS_OVERFLOW; memcpy(stream->next_out, hufftables->deflate_hdr, hufftables->deflate_hdr_count); if (stream->end_of_stream == 0) { if (hufftables->deflate_hdr_count > 0) *stream->next_out -= 1; else hdr_extra_bits -= 1; } else state->has_eob_hdr = 1; stream->avail_out -= hufftables->deflate_hdr_count; stream->total_out += hufftables->deflate_hdr_count; stream->next_out += hufftables->deflate_hdr_count; set_buf(&state->bitbuf, stream->next_out, stream->avail_out); write_bits(&state->bitbuf, hdr_extra_bits, hufftables->deflate_hdr_extra_bits); count = buffer_used(&state->bitbuf); stream->next_out = buffer_ptr(&state->bitbuf); stream->avail_out -= count; stream->total_out += count; state->state = ZSTATE_BODY; return COMP_OK; }
static void write_constant_compressed_stateless(struct isal_zstream *stream, uint32_t repeated_length) { /* Assumes repeated_length is at least 1. * Assumes the input end_of_stream is either 0 or 1. */ struct isal_zstate *state = &stream->internal_state; uint32_t rep_bits = ((repeated_length - 1) / 258) * 2; uint32_t rep_bytes = rep_bits / 8; uint32_t rep_extra = (repeated_length - 1) % 258; uint32_t bytes; uint32_t repeated_char = *stream->next_in; uint8_t *start_in = stream->next_in; /* Guarantee there is enough space for the header even in the worst case */ if (stream->avail_out < HEADER_LENGTH + MAX_FIXUP_CODE_LENGTH + rep_bytes + 8) return; /* Assumes the repeated char is either 0 or 0xFF. */ memcpy(stream->next_out, repeated_char_header[repeated_char & 1], HEADER_LENGTH); if (stream->avail_in == repeated_length && stream->end_of_stream > 0) { stream->next_out[0] |= 1; state->has_eob_hdr = 1; state->has_eob = 1; state->state = ZSTATE_TRL; } else { state->state = ZSTATE_NEW_HDR; } memset(stream->next_out + HEADER_LENGTH, 0, rep_bytes); stream->avail_out -= HEADER_LENGTH + rep_bytes; stream->next_out += HEADER_LENGTH + rep_bytes; stream->total_out += HEADER_LENGTH + rep_bytes; set_buf(&state->bitbuf, stream->next_out, stream->avail_out); /* These two lines are basically a modified version of init. */ state->bitbuf.m_bits = 0; state->bitbuf.m_bit_count = rep_bits % 8; /* Add smaller repeat codes as necessary. Code280 can describe repeat * lengths of 115-130 bits. Code10 can describe repeat lengths of 10 * bits. If more than 230 bits, fill code with two code280s. Else if * more than 115 repeates, fill with code10s until one code280 can * finish the rest of the repeats. Else, fill with code10s and * literals */ if (rep_extra > 115) { while (rep_extra > 130 && rep_extra < 230) { write_bits(&state->bitbuf, CODE_10, CODE_10_LENGTH); rep_extra -= 10; } if (rep_extra >= 230) { write_bits(&state->bitbuf, CODE_280 | ((rep_extra / 2 - 115) << CODE_280_LENGTH), CODE_280_TOTAL_LENGTH); rep_extra -= rep_extra / 2; } write_bits(&state->bitbuf, CODE_280 | ((rep_extra - 115) << CODE_280_LENGTH), CODE_280_TOTAL_LENGTH); } else { while (rep_extra >= 10) { write_bits(&state->bitbuf, CODE_10, CODE_10_LENGTH); rep_extra -= 10; } for (; rep_extra > 0; rep_extra--) write_bits(&state->bitbuf, CODE_LIT, CODE_LIT_LENGTH); } write_bits(&state->bitbuf, END_OF_BLOCK, END_OF_BLOCK_LEN); stream->next_in += repeated_length; stream->avail_in -= repeated_length; stream->total_in += repeated_length; bytes = buffer_used(&state->bitbuf); stream->next_out = buffer_ptr(&state->bitbuf); stream->avail_out -= bytes; stream->total_out += bytes; if (stream->gzip_flag) state->crc = crc32_gzip(state->crc, start_in, stream->next_in - start_in); return; }
if (bit_count > MAX_BITBUF_BIT_WRITE) { write_bits(&state->bitbuf, header_bits, MAX_BITBUF_BIT_WRITE); header_bits >>= MAX_BITBUF_BIT_WRITE; bit_count -= MAX_BITBUF_BIT_WRITE; } write_bits(&state->bitbuf, header_bits, bit_count); /* check_space flushes extra bytes in bitbuf. Required because * write_bits_always fails when the next commit makes the buffer * length exceed 64 bits */ check_space(&state->bitbuf, FORCE_FLUSH); count = buffer_used(&state->bitbuf); stream->next_out = buffer_ptr(&state->bitbuf); stream->avail_out -= count; stream->total_out += count; state->state = ZSTATE_BODY; return COMP_OK; } /* Toggle end of stream only works when deflate header is aligned */ void write_header(struct isal_zstream *stream, uint8_t * deflate_hdr, uint32_t deflate_hdr_count, uint32_t extra_bits_count, uint32_t next_state, uint32_t toggle_end_of_stream) { struct isal_zstate *state = &stream->internal_state;
static inline INT32 buffer_space(text_buffer *text) { return text->bufsize - buffer_used(text); }
INLINE INT32 buffer_space(text_buffer *text) { return text->bufsize - buffer_used(text); }