22#if PC_ENABLE_WS_DEFLATE
31#define PC_MAX_MATCH 258
32#define PC_HASH_BITS 10
33#define PC_HASH_SIZE (1 << PC_HASH_BITS)
34#define PC_HASH_MASK (PC_HASH_SIZE - 1)
36#define PC_WIN_MASK (PC_WINDOW - 1)
37#define PC_MAX_CHAIN 64
41const short LEN_BASE[29] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27,
42 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
43const 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};
46const short DIST_BASE[30] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129,
47 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};
48const short DIST_EXTRA[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
49 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
54 uint16_t head[PC_HASH_SIZE];
55 uint16_t prev[PC_WINDOW];
56 uint16_t ll_code[288];
61static_assert(
sizeof(Tables) <= DEFLATE_SCRATCH_SIZE,
"bump DEFLATE_SCRATCH_SIZE");
64uint16_t reverse_bits(uint16_t code,
int len)
67 for (
int k = 0; k < len; k++)
69 r = (uint16_t)((r << 1) | (code & 1));
77void build_fixed(Tables *t)
80 for (; sym < 144; sym++)
84 for (; sym < 256; sym++)
88 for (; sym < 280; sym++)
92 for (; sym < 288; sym++)
96 for (sym = 0; sym < 30; sym++)
102 uint16_t bl_count[16];
103 memset(bl_count, 0,
sizeof(bl_count));
104 for (sym = 0; sym < 288; sym++)
106 bl_count[t->ll_len[sym]]++;
108 uint16_t next_code[16];
111 for (
int bits = 1; bits <= 15; bits++)
113 code = (uint16_t)((code + bl_count[bits - 1]) << 1);
114 next_code[bits] = code;
116 for (sym = 0; sym < 288; sym++)
118 int len = t->ll_len[sym];
119 t->ll_code[sym] = reverse_bits(next_code[len]++, len);
123 for (sym = 0; sym < 30; sym++)
125 t->d_code[sym] = reverse_bits((uint16_t)sym, 5);
130inline int hash3(
const uint8_t *p)
132 return (
int)(((uint32_t)p[0] << 8 ^ (uint32_t)p[1] << 4 ^ (uint32_t)p[2]) & PC_HASH_MASK);
136void emit_literal(
pc_bit_writer *w,
const Tables *t, uint8_t b)
142void emit_match(
pc_bit_writer *w,
const Tables *t,
int len,
int dist)
145 while (li < 28 && len >= LEN_BASE[li + 1])
153 pc_bitw_put(w, (uint32_t)(len - LEN_BASE[li]), LEN_EXTRA[li]);
160 while (di < 29 && dist >= DIST_BASE[di + 1])
167 pc_bitw_put(w, (uint32_t)(dist - DIST_BASE[di]), DIST_EXTRA[di]);
172DeflateResult deflate_raw(
const uint8_t *src,
size_t src_len, uint8_t *dst,
size_t dst_cap,
size_t *out_len,
173 void *scratch,
size_t scratch_len)
175 if (scratch_len < DEFLATE_SCRATCH_SIZE)
177 return DeflateResult::DEFLATE_ERR_SCRATCH;
180 Tables *t = (Tables *)scratch;
182 for (
int i = 0; i < PC_HASH_SIZE; i++)
184 t->head[i] = PC_NONE;
207 if (i + PC_MIN_MATCH <= src_len)
209 int h = hash3(src + i);
210 uint16_t cand = t->head[h];
211 int chain = PC_MAX_CHAIN;
212 size_t max_len = src_len - i;
213 if (max_len > (
size_t)PC_MAX_MATCH)
215 max_len = PC_MAX_MATCH;
217 while (cand != PC_NONE && chain > 0)
220 size_t dist = i - cand;
221 if (dist > (
size_t)PC_WINDOW)
226 while (l < max_len && src[cand + l] == src[i + l])
230 if ((
int)l > best_len)
233 best_dist = (int)dist;
239 cand = t->prev[cand & PC_WIN_MASK];
244 if (best_len >= PC_MIN_MATCH)
246 emit_match(&w, t, best_len, best_dist);
247 advance = (size_t)best_len;
251 emit_literal(&w, t, src[i]);
259 size_t end = i + advance;
262 if (i + PC_MIN_MATCH <= src_len)
264 int h = hash3(src + i);
265 t->prev[i & PC_WIN_MASK] = t->head[h];
266 t->head[h] = (uint16_t)i;
279 static const uint8_t marker[4] = {0x00, 0x00, 0xff, 0xff};
280 for (
int k = 0; k < 4; k++)
287 w.
out[w.
cnt++] = marker[k];
292 return DeflateResult::DEFLATE_ERR_OVERFLOW;
294 *out_len = w.
cnt - 4;
295 return DeflateResult::DEFLATE_OK;
LSB-first bit writer over a caller-owned byte buffer - one source of truth.
void pc_bitw_align(pc_bit_writer *w)
Flush any partial byte, padding the high bits with zero (byte alignment).
void pc_bitw_put(pc_bit_writer *w, uint32_t bits, int n)
Append the low n bits of bits, LSB-first, spilling any completed bytes to the output.
Bounded RFC 1951 DEFLATE compressor (DEFLATE) - no heap.
LSB-first bit writer over the caller's output buffer; overflow latches once cap is exceeded.
int nbits
bits currently buffered (< 8 between calls)
size_t cnt
bytes written so far
uint32_t acc
bit accumulator (LSB-first)