trees_emit.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #ifndef TREES_EMIT_H_
  2. #define TREES_EMIT_H_
  3. #include "zbuild.h"
  4. #include "trees.h"
  5. #ifdef ZLIB_DEBUG
  6. # include <ctype.h>
  7. # include <inttypes.h>
  8. #endif
  9. /* trees.h */
  10. extern Z_INTERNAL const ct_data static_ltree[L_CODES+2];
  11. extern Z_INTERNAL const ct_data static_dtree[D_CODES];
  12. extern const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN];
  13. extern const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1];
  14. extern Z_INTERNAL const int base_length[LENGTH_CODES];
  15. extern Z_INTERNAL const int base_dist[D_CODES];
  16. /* Bit buffer and deflate code stderr tracing */
  17. #ifdef ZLIB_DEBUG
  18. # define send_bits_trace(s, value, length) { \
  19. Tracevv((stderr, " l %2d v %4llx ", (int)(length), (long long)(value))); \
  20. Assert(length > 0 && length <= BIT_BUF_SIZE, "invalid length"); \
  21. }
  22. # define send_code_trace(s, c) \
  23. if (z_verbose > 2) { \
  24. fprintf(stderr, "\ncd %3d ", (c)); \
  25. }
  26. #else
  27. # define send_bits_trace(s, value, length)
  28. # define send_code_trace(s, c)
  29. #endif
  30. /* If not enough room in bi_buf, use (valid) bits from bi_buf and
  31. * (64 - bi_valid) bits from value, leaving (width - (64-bi_valid))
  32. * unused bits in value.
  33. */
  34. #define send_bits(s, t_val, t_len, bi_buf, bi_valid) {\
  35. uint64_t val = (uint64_t)t_val;\
  36. uint32_t len = (uint32_t)t_len;\
  37. uint32_t total_bits = bi_valid + len;\
  38. send_bits_trace(s, val, len);\
  39. sent_bits_add(s, len);\
  40. if (total_bits < BIT_BUF_SIZE) {\
  41. bi_buf |= val << bi_valid;\
  42. bi_valid = total_bits;\
  43. } else if (bi_valid == BIT_BUF_SIZE) {\
  44. put_uint64(s, bi_buf);\
  45. bi_buf = val;\
  46. bi_valid = len;\
  47. } else {\
  48. bi_buf |= val << bi_valid;\
  49. put_uint64(s, bi_buf);\
  50. bi_buf = val >> (BIT_BUF_SIZE - bi_valid);\
  51. bi_valid = total_bits - BIT_BUF_SIZE;\
  52. }\
  53. }
  54. /* Send a code of the given tree. c and tree must not have side effects */
  55. #ifdef ZLIB_DEBUG
  56. # define send_code(s, c, tree, bi_buf, bi_valid) { \
  57. send_code_trace(s, c); \
  58. send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid); \
  59. }
  60. #else
  61. # define send_code(s, c, tree, bi_buf, bi_valid) \
  62. send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid)
  63. #endif
  64. /* ===========================================================================
  65. * Flush the bit buffer and align the output on a byte boundary
  66. */
  67. static void bi_windup(deflate_state *s) {
  68. if (s->bi_valid > 56) {
  69. put_uint64(s, s->bi_buf);
  70. } else {
  71. if (s->bi_valid > 24) {
  72. put_uint32(s, (uint32_t)s->bi_buf);
  73. s->bi_buf >>= 32;
  74. s->bi_valid -= 32;
  75. }
  76. if (s->bi_valid > 8) {
  77. put_short(s, (uint16_t)s->bi_buf);
  78. s->bi_buf >>= 16;
  79. s->bi_valid -= 16;
  80. }
  81. if (s->bi_valid > 0) {
  82. put_byte(s, s->bi_buf);
  83. }
  84. }
  85. s->bi_buf = 0;
  86. s->bi_valid = 0;
  87. }
  88. /* ===========================================================================
  89. * Emit literal code
  90. */
  91. static inline uint32_t zng_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) {
  92. uint32_t bi_valid = s->bi_valid;
  93. uint64_t bi_buf = s->bi_buf;
  94. send_code(s, c, ltree, bi_buf, bi_valid);
  95. s->bi_valid = bi_valid;
  96. s->bi_buf = bi_buf;
  97. Tracecv(isgraph(c & 0xff), (stderr, " '%c' ", c));
  98. return ltree[c].Len;
  99. }
  100. /* ===========================================================================
  101. * Emit match distance/length code
  102. */
  103. static inline uint32_t zng_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree,
  104. uint32_t lc, uint32_t dist) {
  105. uint32_t c, extra;
  106. uint8_t code;
  107. uint64_t match_bits;
  108. uint32_t match_bits_len;
  109. uint32_t bi_valid = s->bi_valid;
  110. uint64_t bi_buf = s->bi_buf;
  111. /* Send the length code, len is the match length - STD_MIN_MATCH */
  112. code = zng_length_code[lc];
  113. c = code+LITERALS+1;
  114. Assert(c < L_CODES, "bad l_code");
  115. send_code_trace(s, c);
  116. match_bits = ltree[c].Code;
  117. match_bits_len = ltree[c].Len;
  118. extra = extra_lbits[code];
  119. if (extra != 0) {
  120. lc -= base_length[code];
  121. match_bits |= ((uint64_t)lc << match_bits_len);
  122. match_bits_len += extra;
  123. }
  124. dist--; /* dist is now the match distance - 1 */
  125. code = d_code(dist);
  126. Assert(code < D_CODES, "bad d_code");
  127. send_code_trace(s, code);
  128. /* Send the distance code */
  129. match_bits |= ((uint64_t)dtree[code].Code << match_bits_len);
  130. match_bits_len += dtree[code].Len;
  131. extra = extra_dbits[code];
  132. if (extra != 0) {
  133. dist -= base_dist[code];
  134. match_bits |= ((uint64_t)dist << match_bits_len);
  135. match_bits_len += extra;
  136. }
  137. send_bits(s, match_bits, match_bits_len, bi_buf, bi_valid);
  138. s->bi_valid = bi_valid;
  139. s->bi_buf = bi_buf;
  140. return match_bits_len;
  141. }
  142. /* ===========================================================================
  143. * Emit end block
  144. */
  145. static inline void zng_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) {
  146. uint32_t bi_valid = s->bi_valid;
  147. uint64_t bi_buf = s->bi_buf;
  148. send_code(s, END_BLOCK, ltree, bi_buf, bi_valid);
  149. s->bi_valid = bi_valid;
  150. s->bi_buf = bi_buf;
  151. Tracev((stderr, "\n+++ Emit End Block: Last: %u Pending: %u Total Out: %" PRIu64 "\n",
  152. last, s->pending, (uint64_t)s->strm->total_out));
  153. Z_UNUSED(last);
  154. }
  155. /* ===========================================================================
  156. * Emit literal and count bits
  157. */
  158. static inline void zng_tr_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) {
  159. cmpr_bits_add(s, zng_emit_lit(s, ltree, c));
  160. }
  161. /* ===========================================================================
  162. * Emit match and count bits
  163. */
  164. static inline void zng_tr_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree,
  165. uint32_t lc, uint32_t dist) {
  166. cmpr_bits_add(s, zng_emit_dist(s, ltree, dtree, lc, dist));
  167. }
  168. /* ===========================================================================
  169. * Emit start of block
  170. */
  171. static inline void zng_tr_emit_tree(deflate_state *s, int type, const int last) {
  172. uint32_t bi_valid = s->bi_valid;
  173. uint64_t bi_buf = s->bi_buf;
  174. uint32_t header_bits = (type << 1) + last;
  175. send_bits(s, header_bits, 3, bi_buf, bi_valid);
  176. cmpr_bits_add(s, 3);
  177. s->bi_valid = bi_valid;
  178. s->bi_buf = bi_buf;
  179. Tracev((stderr, "\n--- Emit Tree: Last: %u\n", last));
  180. }
  181. /* ===========================================================================
  182. * Align bit buffer on a byte boundary and count bits
  183. */
  184. static inline void zng_tr_emit_align(deflate_state *s) {
  185. bi_windup(s); /* align on byte boundary */
  186. sent_bits_align(s);
  187. }
  188. /* ===========================================================================
  189. * Emit an end block and align bit buffer if last block
  190. */
  191. static inline void zng_tr_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) {
  192. zng_emit_end_block(s, ltree, last);
  193. cmpr_bits_add(s, 7);
  194. if (last)
  195. zng_tr_emit_align(s);
  196. }
  197. #endif