Skip to content

Commit

Permalink
genlz77: Support dynamic dict and hash sizes.
Browse files Browse the repository at this point in the history
Also, dependecy-inject hash table, so uzlib_compress() is allocation-free.
These changes are implemented by introducing struct uzlib_comp to hold
compression parameters and state.
  • Loading branch information
pfalcon committed Sep 16, 2020
1 parent 4c230f0 commit 0422e65
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
22 changes: 15 additions & 7 deletions src/genlz77.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,33 @@
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "defl_static.h"
#include "uzlib.h"

#if 0
#define HASH_BITS 12
#else
#define HASH_BITS data->hash_bits
#endif

#define HASH_SIZE (1<<HASH_BITS)

/* Minimum and maximum length of matches to look for, inclusive */
#define MIN_MATCH 3
#define MAX_MATCH 258

/* Max offset of the match to look for, inclusive */
#if 0
#define MAX_OFFSET 32768
#else
#define MAX_OFFSET data->dict_size
#endif

/* Hash function can be defined as macro or as inline function */

/*#define HASH(p) (p[0] + p[1] + p[2])*/

/* This is hash function from liblzf */
static inline int HASH(const uint8_t *p) {
static inline int HASH(struct uzlib_comp *data, const uint8_t *p) {
int v = (p[0] << 16) | (p[1] << 8) | p[2];
int hash = ((v >> (3*8 - HASH_BITS)) - v) & (HASH_SIZE - 1);
return hash;
Expand Down Expand Up @@ -85,14 +95,12 @@ static inline void copy(void *data, unsigned offset, unsigned len)
#endif


void uzlib_compress(void *data, const uint8_t *src, unsigned slen)
void uzlib_compress(struct uzlib_comp *data, const uint8_t *src, unsigned slen)
{
const uint8_t *hashtable[HASH_SIZE] = {0};

const uint8_t *top = src + slen - MIN_MATCH;
while (src < top) {
int h = HASH(src);
const uint8_t **bucket = &hashtable[h & (HASH_SIZE - 1)];
int h = HASH(data, src);
const uint8_t **bucket = &data->hash_table[h & (HASH_SIZE - 1)];
const uint8_t *subs = *bucket;
*bucket = src;
if (subs && src > subs && (src - subs) <= MAX_OFFSET && !memcmp(src, subs, MIN_MATCH)) {
Expand Down
14 changes: 13 additions & 1 deletion src/uzlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <stdint.h>
#include <stdbool.h>

#include "defl_static.h"

#include "uzlib_conf.h"
#if UZLIB_CONF_DEBUG_LOG
#include <stdio.h>
Expand Down Expand Up @@ -117,7 +119,17 @@ int TINFCC uzlib_gzip_parse_header(TINF_DATA *d);

/* Compression API */

void TINFCC uzlib_compress(void *data, const uint8_t *src, unsigned slen);
typedef const uint8_t *uzlib_hash_entry_t;

struct uzlib_comp {
struct Outbuf out;

uzlib_hash_entry_t *hash_table;
unsigned int hash_bits;
unsigned int dict_size;
};

void TINFCC uzlib_compress(struct uzlib_comp *c, const uint8_t *src, unsigned slen);

/* Checksum API */

Expand Down

0 comments on commit 0422e65

Please sign in to comment.