#define MAX_BITS 15
/* All codes must not exceed MAX_BITS bits */
-#define BIT_BUF_SIZE 32
+#define BIT_BUF_SIZE 64
/* size of bit buffer in bi_buf */
#define END_BLOCK 256
unsigned long bits_sent; /* bit length of compressed data sent mod 2^32 */
#endif
- uint32_t bi_buf;
+ uint64_t bi_buf;
/* Output buffer. bits are inserted starting at the bottom (least
* significant bits).
*/
#endif
}
+/* ===========================================================================
+ * Output a 64-bit unsigned int LSB first on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+static inline void put_uint64(deflate_state *s, uint64_t lld) {
+#if defined(UNALIGNED_OK)
+ *(uint64_t *)(&s->pending_buf[s->pending]) = lld;
+ s->pending += 8;
+#else
+ put_byte(s, (lld & 0xff));
+ put_byte(s, ((lld >> 8) & 0xff));
+ put_byte(s, ((lld >> 16) & 0xff));
+ put_byte(s, ((lld >> 24) & 0xff));
+ put_byte(s, ((lld >> 32) & 0xff));
+ put_byte(s, ((lld >> 40) & 0xff));
+ put_byte(s, ((lld >> 48) & 0xff));
+ put_byte(s, ((lld >> 56) & 0xff));
+#endif
+}
+
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
/* Minimum amount of lookahead, except at the end of the input file.
* See deflate.c for comments about the MIN_MATCH+1.
/* Bit buffer and deflate code stderr tracing */
#ifdef ZLIB_DEBUG
# define send_bits_trace(s, value, length) { \
- Tracevv((stderr, " l %2d v %4x ", length, value)); \
+ Tracevv((stderr, " l %2d v %4llx ", length, value)); \
Assert(length > 0 && length <= BIT_BUF_SIZE, "invalid length"); \
}
# define send_code_trace(s, c) \
#endif
/* If not enough room in bi_buf, use (valid) bits from bi_buf and
- * (32 - bi_valid) bits from value, leaving (width - (32-bi_valid))
+ * (64 - bi_valid) bits from value, leaving (width - (64-bi_valid))
* unused bits in value.
*/
#define send_bits(s, t_val, t_len, bi_buf, bi_valid) {\
- uint32_t val = (uint32_t)t_val;\
+ uint64_t val = (uint64_t)t_val;\
uint32_t len = (uint32_t)t_len;\
uint32_t total_bits = bi_valid + len;\
send_bits_trace(s, val, len);\
bi_buf |= val << bi_valid;\
bi_valid = total_bits;\
} else if (bi_valid == BIT_BUF_SIZE) {\
- put_uint32(s, bi_buf);\
+ put_uint64(s, bi_buf);\
bi_buf = val;\
bi_valid = len;\
} else {\
bi_buf |= val << bi_valid;\
- put_uint32(s, bi_buf);\
+ put_uint64(s, bi_buf);\
bi_buf = val >> (BIT_BUF_SIZE - bi_valid);\
bi_valid = total_bits - BIT_BUF_SIZE;\
}\
* Flush the bit buffer, keeping at most 7 bits in it.
*/
static void bi_flush(deflate_state *s) {
- if (s->bi_valid == 32) {
- put_uint32(s, s->bi_buf);
+ if (s->bi_valid == 64) {
+ put_uint64(s, s->bi_buf);
s->bi_buf = 0;
s->bi_valid = 0;
- } else {
+ }
+ else {
+ if (s->bi_valid >= 32) {
+ put_uint32(s, (uint32_t)s->bi_buf);
+ s->bi_buf >>= 32;
+ s->bi_valid -= 32;
+ }
if (s->bi_valid >= 16) {
- put_short(s, s->bi_buf);
+ put_short(s, (uint16_t)s->bi_buf);
s->bi_buf >>= 16;
s->bi_valid -= 16;
}
* Flush the bit buffer and align the output on a byte boundary
*/
static void bi_windup(deflate_state *s) {
- if (s->bi_valid > 24) {
- put_uint32(s, s->bi_buf);
+ if (s->bi_valid > 56) {
+ put_uint64(s, s->bi_buf);
} else {
+ if (s->bi_valid > 24) {
+ put_uint32(s, (uint32_t)s->bi_buf);
+ s->bi_buf >>= 32;
+ s->bi_valid -= 32;
+ }
if (s->bi_valid > 8) {
- put_short(s, s->bi_buf);
+ put_short(s, (uint16_t)s->bi_buf);
s->bi_buf >>= 16;
s->bi_valid -= 16;
}
*/
static inline uint32_t zng_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) {
uint32_t bi_valid = s->bi_valid;
- uint32_t bi_buf = s->bi_buf;
+ uint64_t bi_buf = s->bi_buf;
send_code(s, c, ltree, bi_buf, bi_valid);
uint32_t lc, uint32_t dist) {
uint32_t c, extra;
uint8_t code;
- uint32_t dist_bits, dist_bits_len;
- uint32_t lc_bits, lc_bits_len;
+ uint64_t match_bits;
+ uint32_t match_bits_len;
uint32_t bi_valid = s->bi_valid;
- uint32_t bi_buf = s->bi_buf;
+ uint64_t bi_buf = s->bi_buf;
/* Send the length code, len is the match length - MIN_MATCH */
code = zng_length_code[lc];
Assert(c < L_CODES, "bad l_code");
send_code_trace(s, c);
- lc_bits = ltree[c].Code;
- lc_bits_len = ltree[c].Len;
+ match_bits = ltree[c].Code;
+ match_bits_len = ltree[c].Len;
extra = extra_lbits[code];
if (extra != 0) {
lc -= base_length[code];
- lc_bits |= (lc << lc_bits_len);
- lc_bits_len += extra;
+ match_bits |= ((uint64_t)lc << match_bits_len);
+ match_bits_len += extra;
}
- send_bits(s, lc_bits, lc_bits_len, bi_buf, bi_valid);
dist--; /* dist is now the match distance - 1 */
code = d_code(dist);
send_code_trace(s, code);
/* Send the distance code */
- dist_bits = dtree[code].Code;
- dist_bits_len = dtree[code].Len;
+ match_bits |= (dtree[code].Code << match_bits_len);
+ match_bits_len += dtree[code].Len;
extra = extra_dbits[code];
if (extra != 0) {
dist -= base_dist[code];
- dist_bits |= (dist << dist_bits_len);
- dist_bits_len += extra;
+ match_bits |= ((uint64_t)dist << match_bits_len);
+ match_bits_len += extra;
}
- send_bits(s, dist_bits, dist_bits_len, bi_buf, bi_valid);
+
+ send_bits(s, match_bits, match_bits_len, bi_buf, bi_valid);
s->bi_valid = bi_valid;
s->bi_buf = bi_buf;
- return lc_bits_len + dist_bits_len;
+ return match_bits_len;
}
/* ===========================================================================
*/
static inline void zng_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) {
uint32_t bi_valid = s->bi_valid;
- uint32_t bi_buf = s->bi_buf;
+ uint64_t bi_buf = s->bi_buf;
send_code(s, END_BLOCK, ltree, bi_buf, bi_valid);
s->bi_valid = bi_valid;
s->bi_buf = bi_buf;
*/
static inline void zng_tr_emit_tree(deflate_state *s, int type, const int last) {
uint32_t bi_valid = s->bi_valid;
- uint32_t bi_buf = s->bi_buf;
+ uint64_t bi_buf = s->bi_buf;
send_bits(s, (type << 1) + last, 3, bi_buf, bi_valid);
cmpr_bits_add(s, 3);
s->bi_valid = bi_valid;