/ SHARP_BadApple / heatshrink_decoder.h
heatshrink_decoder.h
1 // SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries 2 // 3 // SPDX-License-Identifier: MIT 4 5 #ifndef HEATSHRINK_DECODER_H 6 #define HEATSHRINK_DECODER_H 7 8 #include <stdint.h> 9 #include <stddef.h> 10 #include "heatshrink_common.h" 11 #include "heatshrink_config.h" 12 13 typedef enum { 14 HSDR_SINK_OK, /* data sunk, ready to poll */ 15 HSDR_SINK_FULL, /* out of space in internal buffer */ 16 HSDR_SINK_ERROR_NULL=-1, /* NULL argument */ 17 } HSD_sink_res; 18 19 typedef enum { 20 HSDR_POLL_EMPTY, /* input exhausted */ 21 HSDR_POLL_MORE, /* more data remaining, call again w/ fresh output buffer */ 22 HSDR_POLL_ERROR_NULL=-1, /* NULL arguments */ 23 HSDR_POLL_ERROR_UNKNOWN=-2, 24 } HSD_poll_res; 25 26 typedef enum { 27 HSDR_FINISH_DONE, /* output is done */ 28 HSDR_FINISH_MORE, /* more output remains */ 29 HSDR_FINISH_ERROR_NULL=-1, /* NULL arguments */ 30 } HSD_finish_res; 31 32 #if HEATSHRINK_DYNAMIC_ALLOC 33 #define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(BUF) \ 34 ((BUF)->input_buffer_size) 35 #define HEATSHRINK_DECODER_WINDOW_BITS(BUF) \ 36 ((BUF)->window_sz2) 37 #define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ 38 ((BUF)->lookahead_sz2) 39 #else 40 #define HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_) \ 41 HEATSHRINK_STATIC_INPUT_BUFFER_SIZE 42 #define HEATSHRINK_DECODER_WINDOW_BITS(_) \ 43 (HEATSHRINK_STATIC_WINDOW_BITS) 44 #define HEATSHRINK_DECODER_LOOKAHEAD_BITS(BUF) \ 45 (HEATSHRINK_STATIC_LOOKAHEAD_BITS) 46 #endif 47 48 typedef struct { 49 uint16_t input_size; /* bytes in input buffer */ 50 uint16_t input_index; /* offset to next unprocessed input byte */ 51 uint16_t output_count; /* how many bytes to output */ 52 uint16_t output_index; /* index for bytes to output */ 53 uint16_t head_index; /* head of window buffer */ 54 uint8_t state; /* current state machine node */ 55 uint8_t current_byte; /* current byte of input */ 56 uint8_t bit_index; /* current bit index */ 57 58 #if HEATSHRINK_DYNAMIC_ALLOC 59 /* Fields that are only used if dynamically allocated. */ 60 uint8_t window_sz2; /* window buffer bits */ 61 uint8_t lookahead_sz2; /* lookahead bits */ 62 uint16_t input_buffer_size; /* input buffer size */ 63 64 /* Input buffer, then expansion window buffer */ 65 uint8_t buffers[]; 66 #else 67 /* Input buffer, then expansion window buffer */ 68 uint8_t buffers[(1 << HEATSHRINK_DECODER_WINDOW_BITS(_)) 69 + HEATSHRINK_DECODER_INPUT_BUFFER_SIZE(_)]; 70 #endif 71 } heatshrink_decoder; 72 73 #if HEATSHRINK_DYNAMIC_ALLOC 74 /* Allocate a decoder with an input buffer of INPUT_BUFFER_SIZE bytes, 75 * an expansion buffer size of 2^WINDOW_SZ2, and a lookahead 76 * size of 2^lookahead_sz2. (The window buffer and lookahead sizes 77 * must match the settings used when the data was compressed.) 78 * Returns NULL on error. */ 79 heatshrink_decoder *heatshrink_decoder_alloc(uint16_t input_buffer_size, 80 uint8_t expansion_buffer_sz2, uint8_t lookahead_sz2); 81 82 /* Free a decoder. */ 83 void heatshrink_decoder_free(heatshrink_decoder *hsd); 84 #endif 85 86 /* Reset a decoder. */ 87 void heatshrink_decoder_reset(heatshrink_decoder *hsd); 88 89 /* Sink at most SIZE bytes from IN_BUF into the decoder. *INPUT_SIZE is set to 90 * indicate how many bytes were actually sunk (in case a buffer was filled). */ 91 HSD_sink_res heatshrink_decoder_sink(heatshrink_decoder *hsd, 92 uint8_t *in_buf, size_t size, size_t *input_size); 93 94 /* Poll for output from the decoder, copying at most OUT_BUF_SIZE bytes into 95 * OUT_BUF (setting *OUTPUT_SIZE to the actual amount copied). */ 96 HSD_poll_res heatshrink_decoder_poll(heatshrink_decoder *hsd, 97 uint8_t *out_buf, size_t out_buf_size, size_t *output_size); 98 99 /* Notify the dencoder that the input stream is finished. 100 * If the return value is HSDR_FINISH_MORE, there is still more output, so 101 * call heatshrink_decoder_poll and repeat. */ 102 HSD_finish_res heatshrink_decoder_finish(heatshrink_decoder *hsd); 103 104 #endif