uzlib.h 4.8 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*
 * uzlib  -  tiny deflate/inflate library (deflate, gzip, zlib)
 *
 * Copyright (c) 2003 by Joergen Ibsen / Jibz
 * All Rights Reserved
 * http://www.ibsensoftware.com/
 *
 * Copyright (c) 2014-2018 by Paul Sokolovsky
 *
10 11 12
 * Optimised for MicroPython:
 * Copyright (c) 2023 by Jim Mussared
 *
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
 * This software is provided 'as-is', without any express
 * or implied warranty.  In no event will the authors be
 * held liable for any damages arising from the use of
 * this software.
 *
 * Permission is granted to anyone to use this software
 * for any purpose, including commercial applications,
 * and to alter it and redistribute it freely, subject to
 * the following restrictions:
 *
 * 1. The origin of this software must not be
 *    misrepresented; you must not claim that you
 *    wrote the original software. If you use this
 *    software in a product, an acknowledgment in
 *    the product documentation would be appreciated
 *    but is not required.
 *
 * 2. Altered source versions must be plainly marked
 *    as such, and must not be misrepresented as
 *    being the original software.
 *
 * 3. This notice may not be removed or altered from
 *    any source distribution.
 */

#ifndef UZLIB_H_INCLUDED
#define UZLIB_H_INCLUDED

#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>

#include "uzlib_conf.h"
#if UZLIB_CONF_DEBUG_LOG
#include <stdio.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* ok status, more data produced */
55
#define UZLIB_OK             0
56
/* end of compressed stream reached */
57 58 59 60
#define UZLIB_DONE           1
#define UZLIB_DATA_ERROR    (-3)
#define UZLIB_CHKSUM_ERROR  (-4)
#define UZLIB_DICT_ERROR    (-5)
61 62

/* checksum types */
63 64 65
#define UZLIB_CHKSUM_NONE  0
#define UZLIB_CHKSUM_ADLER 1
#define UZLIB_CHKSUM_CRC   2
66 67 68 69 70 71 72 73 74 75 76

/* helper macros */
#define TINF_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*(arr)))

/* data structures */

typedef struct {
   unsigned short table[16];  /* table of code length counts */
   unsigned short trans[288]; /* code -> symbol translation table */
} TINF_TREE;

77
typedef struct _uzlib_uncomp_t {
78 79 80 81 82 83 84 85 86
    /* Pointer to the next byte in the input buffer */
    const unsigned char *source;
    /* Pointer to the next byte past the input buffer (source_limit = source + len) */
    const unsigned char *source_limit;
    /* If source_limit == NULL, or source >= source_limit, this function
       will be used to read next byte from source stream. The function may
       also return -1 in case of EOF (or irrecoverable error). Note that
       besides returning the next byte, it may also update source and
       source_limit fields, thus allowing for buffered operation. */
87 88
    void *source_read_data;
    int (*source_read_cb)(void *);
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114

    unsigned int tag;
    unsigned int bitcount;

    /* Destination (output) buffer start */
    unsigned char *dest_start;
    /* Current pointer in dest buffer */
    unsigned char *dest;
    /* Pointer past the end of the dest buffer, similar to source_limit */
    unsigned char *dest_limit;

    /* Accumulating checksum */
    unsigned int checksum;
    char checksum_type;
    bool eof;

    int btype;
    int bfinal;
    unsigned int curlen;
    int lzOff;
    unsigned char *dict_ring;
    unsigned int dict_size;
    unsigned int dict_idx;

    TINF_TREE ltree; /* dynamic length/symbol tree */
    TINF_TREE dtree; /* dynamic distance tree */
115
} uzlib_uncomp_t;
116 117 118 119 120 121 122

#define TINF_PUT(d, c) \
    { \
        *d->dest++ = c; \
        if (d->dict_ring) { d->dict_ring[d->dict_idx++] = c; if (d->dict_idx == d->dict_size) d->dict_idx = 0; } \
    }

123
unsigned char uzlib_get_byte(uzlib_uncomp_t *d);
124 125 126

/* Decompression API */

127 128 129
void uzlib_uncompress_init(uzlib_uncomp_t *d, void *dict, unsigned int dictLen);
int  uzlib_uncompress(uzlib_uncomp_t *d);
int  uzlib_uncompress_chksum(uzlib_uncomp_t *d);
130

131 132 133
#define UZLIB_HEADER_ZLIB             0
#define UZLIB_HEADER_GZIP             1
int uzlib_parse_zlib_gzip_header(uzlib_uncomp_t *d, int *wbits);
134 135 136

/* Compression API */

137 138 139 140 141
typedef struct {
    void *dest_write_data;
    void (*dest_write_cb)(void *data, uint8_t byte);
    unsigned long outbits;
    int noutbits;
142 143 144 145
    uint8_t *hist_buf;
    size_t hist_max;
    size_t hist_start;
    size_t hist_len;
146 147 148 149
} uzlib_lz77_state_t;

void uzlib_lz77_init(uzlib_lz77_state_t *state, uint8_t *hist, size_t hist_max);
void uzlib_lz77_compress(uzlib_lz77_state_t *state, const uint8_t *src, unsigned len);
150

151 152
void uzlib_start_block(uzlib_lz77_state_t *state);
void uzlib_finish_block(uzlib_lz77_state_t *state);
153 154 155 156

/* Checksum API */

/* prev_sum is previous value for incremental computation, 1 initially */
157
uint32_t uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum);
158
/* crc is previous value for incremental computation, 0xffffffff initially */
159
uint32_t uzlib_crc32(const void *data, unsigned int length, uint32_t crc);
160 161 162 163 164 165

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* UZLIB_H_INCLUDED */