19 #if HEATSHRINK_DEBUGGING_LOGS 23 #define LOG(...) fprintf(stderr, __VA_ARGS__) 24 #define ASSERT(X) assert(X) 25 static const char *state_names[] = {
57 #define MATCH_NOT_FOUND ((uint16_t)-1) 77 #if HEATSHRINK_DYNAMIC_ALLOC 79 uint8_t lookahead_sz2) {
83 (lookahead_sz2 > window_sz2)) {
91 size_t buf_sz = (2 << window_sz2);
99 #if HEATSHRINK_USE_INDEX 100 size_t index_sz = buf_sz*
sizeof(uint16_t);
109 LOG(
"-- allocated encoder with buffer size of %zu (%u byte input size)\n",
116 #if HEATSHRINK_USE_INDEX 117 size_t index_sz =
sizeof(
struct hs_index) + hse->search_index->size;
141 hse->loop_detect = (uint32_t)-1;
146 uint8_t *in_buf,
size_t size,
size_t *input_size) {
147 if ((hse ==
NULL) || (in_buf ==
NULL) || (input_size ==
NULL)) {
160 uint16_t cp_sz = rem < size ? rem :
size;
166 LOG(
"-- sunk %u bytes (of %zu) into encoder at %d, input buffer now has %u\n",
169 LOG(
"-- internal buffer is now full\n");
182 uint16_t end,
const uint16_t maxlen, uint16_t *match_length);
199 uint8_t *out_buf,
size_t out_buf_size,
size_t *output_size) {
200 if ((hse ==
NULL) || (out_buf ==
NULL) || (output_size ==
NULL)) {
203 if (out_buf_size == 0) {
204 LOG(
"-- MISUSE: output buffer size is 0\n");
215 LOG(
"-- polling, state %u (%s), flags 0x%02x\n",
218 uint8_t in_state = hse->
state;
249 LOG(
"-- bad state %s\n", state_names[hse->
state]);
253 if (hse->
state == in_state) {
262 LOG(
"-- setting is_finishing flag\n");
272 LOG(
"## step_search, scan @ +%d (%d/%d), input size %d\n",
276 if (msi >= hse->
input_size - (fin ? 0 : lookahead_sz)) {
279 LOG(
"-- end of search @ %d, saving backlog\n", msi);
284 uint16_t end = input_offset + msi;
288 start = end - window_length + 1;
290 start = end - window_length + 1;
291 if (start < lookahead_sz) { start = lookahead_sz; }
293 start = input_offset;
296 uint16_t max_possible = lookahead_sz;
301 uint16_t match_length = 0;
303 start, end, max_possible, &match_length);
306 LOG(
"ss Match not found\n");
312 LOG(
"ss Found match of %d bytes at %d\n", match_length, match_pos);
392 LOG(
"-- saving backlog\n");
404 LOG(
"-- flushing remaining byte (bit_index == 0x%02x)\n", hse->
bit_index);
414 LOG(
"-- adding tag bit: %d\n", tag);
433 #if HEATSHRINK_USE_INDEX 452 memset(last, 0xFF,
sizeof(last));
454 uint8_t *
const data = hse->
buffer;
458 const uint16_t end = input_offset + hse->
input_size;
460 for (uint16_t i=0; i<end; i++) {
462 uint16_t lv = last[v];
498 uint16_t end,
const uint16_t maxlen, uint16_t *match_length) {
499 LOG(
"-- scanning for match of buf[%u:%u] between buf[%u:%u] (max %u bytes)\n",
500 end, end + maxlen, start, end + maxlen - 1, maxlen);
501 uint8_t *buf = hse->
buffer;
503 uint16_t match_maxlen = 0;
505 const uint16_t break_even_point = 3;
507 uint8_t *
const needlepoint = &buf[end];
508 #if HEATSHRINK_USE_INDEX 510 int16_t pos = hsi->
index[end];
512 while (pos >= start) {
513 uint8_t *
const pospoint = &buf[pos];
519 if (pospoint[match_maxlen] != needlepoint[match_maxlen]) {
520 pos = hsi->
index[pos];
524 for (len = 1; len < maxlen; len++) {
525 if (pospoint[len] != needlepoint[len])
break;
528 if (len > match_maxlen) {
531 if (len == maxlen) {
break; }
533 pos = hsi->
index[pos];
536 for (int16_t pos=end - 1; pos >= start; pos--) {
537 uint8_t *
const pospoint = &buf[pos];
538 if ((pospoint[match_maxlen] == needlepoint[match_maxlen])
539 && (*pospoint == *needlepoint)) {
540 for (len=1; len<maxlen; len++) {
542 LOG(
" --> cmp buf[%d] == 0x%02x against %02x (start %u)\n",
543 pos + len, pospoint[len], needlepoint[len], start);
545 if (pospoint[len] != needlepoint[len]) {
break; }
547 if (len > match_maxlen) {
550 if (len == maxlen) {
break; }
556 if (match_maxlen >= break_even_point) {
557 LOG(
"-- best match: %u bytes at -%u\n",
558 match_maxlen, end - match_index);
559 *match_length = match_maxlen;
560 return end - match_index;
562 LOG(
"-- none found\n");
578 LOG(
"-- pushing %d outgoing bits: 0x%02x\n", count, bits);
590 LOG(
"++ push_bits: %d bits, input of 0x%02x\n", count, bits);
594 if (count == 8 && hse->
bit_index == 0x80) {
597 for (
int i=count - 1; i>=0; i--) {
598 bool bit = bits & (1 << i);
601 LOG(
" -- setting bit %d at bit index 0x%02x, byte => 0x%02x\n",
618 uint8_t c = hse->
buffer[input_offset];
619 LOG(
"-- yielded literal byte 0x%02x ('%c') from +%d\n",
620 c,
isprint(c) ? c :
'.', input_offset);
633 uint16_t rem = input_buf_sz - msi;
634 uint16_t shift_sz = input_buf_sz + rem;
637 &hse->
buffer[input_buf_sz - rem],
#define HEATSHRINK_FREE(P, SZ)
static void do_indexing(heatshrink_encoder *hse)
uint16_t match_scan_index
static void push_bits(heatshrink_encoder *hse, uint8_t count, uint8_t bits, output_info *oi)
static HSE_state st_step_search(heatshrink_encoder *hse)
static HSE_state st_yield_br_length(heatshrink_encoder *hse, output_info *oi)
#define HEATSHRINK_MAX_WINDOW_BITS
static int on_final_literal(heatshrink_encoder *hse)
uint8_t outgoing_bits_count
static int is_finishing(heatshrink_encoder *hse)
#define HEATSHRINK_ENCODER_INDEX(HSE)
static HSE_state st_yield_literal(heatshrink_encoder *hse, output_info *oi)
static HSE_state st_yield_tag_bit(heatshrink_encoder *hse, output_info *oi)
#define HEATSHRINK_MIN_WINDOW_BITS
#define HEATSHRINK_ENCODER_WINDOW_BITS(HSE)
#define HEATSHRINK_BACKREF_MARKER
static int backlog_is_filled(heatshrink_encoder *hse)
static int has_literal(heatshrink_encoder *hse)
static void add_tag_bit(heatshrink_encoder *hse, output_info *oi, uint8_t tag)
static HSE_state st_save_backlog(heatshrink_encoder *hse)
static void push_literal_byte(heatshrink_encoder *hse, output_info *oi)
#define HEATSHRINK_LITERAL_MARKER
static uint16_t find_longest_match(heatshrink_encoder *hse, uint16_t start, uint16_t end, const uint16_t maxlen, uint16_t *match_length)
heatshrink_encoder * heatshrink_encoder_alloc(uint8_t window_sz2, uint8_t lookahead_sz2)
static void save_backlog(heatshrink_encoder *hse)
static uint16_t get_input_buffer_size(heatshrink_encoder *hse)
void heatshrink_encoder_free(heatshrink_encoder *hse)
static uint8_t push_outgoing_bits(heatshrink_encoder *hse, output_info *oi)
static HSE_state st_yield_br_index(heatshrink_encoder *hse, output_info *oi)
HSE_finish_res heatshrink_encoder_finish(heatshrink_encoder *hse)
static int can_take_byte(output_info *oi)
static uint16_t get_lookahead_size(heatshrink_encoder *hse)
HSE_poll_res heatshrink_encoder_poll(heatshrink_encoder *hse, uint8_t *out_buf, size_t out_buf_size, size_t *output_size)
HSE_sink_res heatshrink_encoder_sink(heatshrink_encoder *hse, uint8_t *in_buf, size_t size, size_t *input_size)
static int backlog_is_partial(heatshrink_encoder *hse)
static HSE_state st_flush_bit_buffer(heatshrink_encoder *hse, output_info *oi)
#define HEATSHRINK_MALLOC(SZ)
struct hs_index * search_index
static uint16_t get_input_offset(heatshrink_encoder *hse)
void heatshrink_encoder_reset(heatshrink_encoder *hse)
#define HEATSHRINK_ENCODER_LOOKAHEAD_BITS(HSE)
#define HEATSHRINK_MIN_LOOKAHEAD_BITS
static heatshrink_encoder hse