22#if DETWS_ENABLE_WS_DEFLATE
28constexpr int MIN_MATCH = 3;
29constexpr int MAX_MATCH = 258;
30constexpr int HASH_BITS = 10;
31constexpr int HASH_SIZE = 1 << HASH_BITS;
32constexpr int HASH_MASK = HASH_SIZE - 1;
33constexpr int WINDOW = 512;
34constexpr int WIN_MASK = WINDOW - 1;
35constexpr int MAX_CHAIN = 64;
36constexpr uint16_t NONE = 0xFFFF;
39const short LEN_BASE[29] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27,
40 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
41const short LEN_EXTRA[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
44const short DIST_BASE[30] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129,
45 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
46const short DIST_EXTRA[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
47 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
52 uint16_t head[HASH_SIZE];
53 uint16_t prev[WINDOW];
54 uint16_t ll_code[288];
59static_assert(
sizeof(Tables) <= DEFLATE_SCRATCH_SIZE,
"bump DEFLATE_SCRATCH_SIZE");
62uint16_t reverse_bits(uint16_t code,
int len)
65 for (
int k = 0; k < len; k++)
67 r = (uint16_t)((r << 1) | (code & 1));
75void build_fixed(Tables *t)
78 for (; sym < 144; sym++)
80 for (; sym < 256; sym++)
82 for (; sym < 280; sym++)
84 for (; sym < 288; sym++)
86 for (sym = 0; sym < 30; sym++)
90 uint16_t bl_count[16];
91 memset(bl_count, 0,
sizeof(bl_count));
92 for (sym = 0; sym < 288; sym++)
93 bl_count[t->ll_len[sym]]++;
94 uint16_t next_code[16];
97 for (
int bits = 1; bits <= 15; bits++)
99 code = (uint16_t)((code + bl_count[bits - 1]) << 1);
100 next_code[bits] = code;
102 for (sym = 0; sym < 288; sym++)
104 int len = t->ll_len[sym];
105 t->ll_code[sym] = reverse_bits(next_code[len]++, len);
109 for (sym = 0; sym < 30; sym++)
110 t->d_code[sym] = reverse_bits((uint16_t)sym, 5);
124void put_bits(BitWriter *w, uint32_t bits,
int n)
126 w->acc |= bits << w->nbits;
128 while (w->nbits >= 8)
130 if (w->cnt >= w->cap)
135 w->out[w->cnt++] = (uint8_t)(w->acc & 0xFF);
142void align_byte(BitWriter *w)
146 if (w->cnt >= w->cap)
151 w->out[w->cnt++] = (uint8_t)(w->acc & 0xFF);
158inline int hash3(
const uint8_t *p)
160 return (
int)(((uint32_t)p[0] << 8 ^ (uint32_t)p[1] << 4 ^ (uint32_t)p[2]) & HASH_MASK);
164void emit_literal(BitWriter *w,
const Tables *t, uint8_t b)
166 put_bits(w, t->ll_code[b], t->ll_len[b]);
170void emit_match(BitWriter *w,
const Tables *t,
int len,
int dist)
173 while (li < 28 && len >= LEN_BASE[li + 1])
176 put_bits(w, t->ll_code[lsym], t->ll_len[lsym]);
178 put_bits(w, (uint32_t)(len - LEN_BASE[li]), LEN_EXTRA[li]);
181 while (di < 29 && dist >= DIST_BASE[di + 1])
183 put_bits(w, t->d_code[di], t->d_len[di]);
185 put_bits(w, (uint32_t)(dist - DIST_BASE[di]), DIST_EXTRA[di]);
189DeflateResult deflate_raw(
const uint8_t *src,
size_t src_len, uint8_t *dst,
size_t dst_cap,
size_t *out_len,
190 void *scratch,
size_t scratch_len)
192 if (scratch_len < DEFLATE_SCRATCH_SIZE)
193 return DeflateResult::DEFLATE_ERR_SCRATCH;
195 Tables *t = (Tables *)scratch;
197 for (
int i = 0; i < HASH_SIZE; i++)
220 if (i + MIN_MATCH <= src_len)
222 int h = hash3(src + i);
223 uint16_t cand = t->head[h];
224 int chain = MAX_CHAIN;
225 size_t max_len = src_len - i;
226 if (max_len > (
size_t)MAX_MATCH)
228 while (cand != NONE && chain > 0)
231 size_t dist = i - cand;
232 if (dist > (
size_t)WINDOW)
235 while (l < max_len && src[cand + l] == src[i + l])
237 if ((
int)l > best_len)
240 best_dist = (int)dist;
244 cand = t->prev[cand & WIN_MASK];
249 if (best_len >= MIN_MATCH)
251 emit_match(&w, t, best_len, best_dist);
252 advance = (size_t)best_len;
256 emit_literal(&w, t, src[i]);
264 size_t end = i + advance;
267 if (i + MIN_MATCH <= src_len)
269 int h = hash3(src + i);
270 t->prev[i & WIN_MASK] = t->head[h];
271 t->head[h] = (uint16_t)i;
280 put_bits(&w, t->ll_code[256], t->ll_len[256]);
284 const uint8_t marker[4] = {0x00, 0x00, 0xff, 0xff};
285 for (
int k = 0; k < 4; k++)
292 w.out[w.cnt++] = marker[k];
296 return DeflateResult::DEFLATE_ERR_OVERFLOW;
297 *out_len = w.cnt - 4;
298 return DeflateResult::DEFLATE_OK;
Bounded RFC 1951 DEFLATE compressor (DEFLATE) - no heap.