/ 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