Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

352 lines
8.7 KiB

  1. //
  2. // optblock.c
  3. //
  4. // Outputting blocks
  5. //
  6. #include "deflate.h"
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <crtdbg.h>
  10. #include "maketbl.h"
  11. //
  12. // Decode a recorded literal
  13. //
  14. #define DECODE_LITERAL(slot) \
  15. slot = encoder->recording_literal_tree_table[read_bitbuf & REC_LITERALS_DECODING_TABLE_MASK]; \
  16. while (slot < 0) \
  17. { \
  18. unsigned long mask = 1 << REC_LITERALS_DECODING_TABLE_BITS; \
  19. do \
  20. { \
  21. slot = -slot; \
  22. if ((read_bitbuf & mask) == 0) \
  23. slot = encoder->recording_literal_tree_left[slot]; \
  24. else \
  25. slot = encoder->recording_literal_tree_right[slot]; \
  26. mask <<= 1; \
  27. } while (slot < 0); \
  28. }
  29. //
  30. // Decode a recorded distance slot
  31. //
  32. #define DECODE_POS_SLOT(slot) \
  33. slot = encoder->recording_dist_tree_table[read_bitbuf & REC_DISTANCES_DECODING_TABLE_MASK]; \
  34. while (slot < 0) \
  35. { \
  36. unsigned long mask = 1 << REC_DISTANCES_DECODING_TABLE_BITS; \
  37. do \
  38. { \
  39. slot = -slot; \
  40. if ((read_bitbuf & mask) == 0) \
  41. slot = encoder->recording_dist_tree_left[slot]; \
  42. else \
  43. slot = encoder->recording_dist_tree_right[slot]; \
  44. mask <<= 1; \
  45. } while (slot < 0); \
  46. }
  47. //
  48. // Remove count bits from the bit buffer
  49. //
  50. #define DUMP_READBUF_BITS(count) \
  51. read_bitbuf >>= count; \
  52. read_bitcount -= count;
  53. //
  54. // Read more bits into the read buffer if our bit buffer if we need to
  55. //
  56. #define CHECK_MORE_READBUF() \
  57. if (read_bitcount <= 0) \
  58. { \
  59. read_bitbuf |= ((*read_bufptr++) << (read_bitcount+16)); \
  60. read_bitcount += 8; \
  61. if (read_bitcount <= 0) \
  62. { \
  63. read_bitbuf |= ((*read_bufptr++) << (read_bitcount+16)); \
  64. read_bitcount += 8; \
  65. } \
  66. }
  67. // output an element from the literal tree
  68. #define OUTPUT_LITERAL(element) \
  69. { \
  70. _ASSERT(encoder->literal_tree_len[element] != 0); \
  71. outputBits(context, encoder->literal_tree_len[element], encoder->literal_tree_code[element]); \
  72. }
  73. // output an element from the distance tree
  74. #define OUTPUT_DIST_SLOT(element) \
  75. { \
  76. _ASSERT(encoder->dist_tree_len[element] != 0); \
  77. outputBits(context, encoder->dist_tree_len[element], encoder->dist_tree_code[element]); \
  78. }
  79. //
  80. // Output a dynamic block
  81. //
  82. static BOOL OptimalEncoderOutputDynamicBlock(t_encoder_context *context)
  83. {
  84. unsigned long read_bitbuf;
  85. int read_bitcount;
  86. byte * read_bufptr;
  87. t_optimal_encoder *encoder = context->optimal_encoder;
  88. if (context->state == STATE_NORMAL)
  89. {
  90. //
  91. // If we haven't started to output a block yet
  92. //
  93. read_bufptr = encoder->lit_dist_buffer;
  94. read_bitbuf = 0;
  95. read_bitcount = -16;
  96. read_bitbuf |= ((*read_bufptr++) << (read_bitcount+16));
  97. read_bitcount += 8;
  98. read_bitbuf |= ((*read_bufptr++) << (read_bitcount+16));
  99. read_bitcount += 8;
  100. context->outputting_block_bitbuf = read_bitbuf;
  101. context->outputting_block_bitcount = read_bitcount;
  102. context->outputting_block_bufptr = read_bufptr;
  103. outputBits(context, 1, 0); // "final" block flag
  104. outputBits(context, 2, BLOCKTYPE_DYNAMIC);
  105. context->state = STATE_OUTPUTTING_TREE_STRUCTURE;
  106. }
  107. if (context->state == STATE_OUTPUTTING_TREE_STRUCTURE)
  108. {
  109. //
  110. // Make sure there is enough room to output the entire tree structure at once
  111. //
  112. if (context->output_curpos > context->output_endpos - MAX_TREE_DATA_SIZE)
  113. {
  114. _ASSERT(0); // not enough room to output tree structure, fatal error!
  115. return FALSE;
  116. }
  117. outputTreeStructure(context, encoder->literal_tree_len, encoder->dist_tree_len);
  118. context->state = STATE_OUTPUTTING_BLOCK;
  119. }
  120. _ASSERT(context->state == STATE_OUTPUTTING_BLOCK);
  121. // load state into local variables
  122. read_bufptr = context->outputting_block_bufptr;
  123. read_bitbuf = context->outputting_block_bitbuf;
  124. read_bitcount = context->outputting_block_bitcount;
  125. // output literals
  126. while (context->outputting_block_current_literal < context->outputting_block_num_literals)
  127. {
  128. int literal;
  129. // break when we get near the end of our output buffer
  130. if (context->output_curpos >= context->output_near_end_threshold)
  131. break;
  132. DECODE_LITERAL(literal);
  133. DUMP_READBUF_BITS(encoder->recording_literal_tree_len[literal]);
  134. CHECK_MORE_READBUF();
  135. if (literal < NUM_CHARS)
  136. {
  137. // it's a char
  138. OUTPUT_LITERAL(literal);
  139. }
  140. else
  141. {
  142. // it's a match
  143. int len_slot, pos_slot, extra_pos_bits;
  144. // literal == len_slot + (NUM_CHARS+1)
  145. _ASSERT(literal != END_OF_BLOCK_CODE);
  146. OUTPUT_LITERAL(literal);
  147. len_slot = literal - (NUM_CHARS+1);
  148. //
  149. // extra_length_bits[len_slot] > 0 when len_slot >= 8
  150. // (except when length is MAX_MATCH).
  151. //
  152. if (len_slot >= 8)
  153. {
  154. int extra_bits = g_ExtraLengthBits[len_slot];
  155. if (extra_bits > 0)
  156. {
  157. unsigned int extra_data = read_bitbuf & ((1 << extra_bits)-1);
  158. outputBits(context, extra_bits, extra_data);
  159. DUMP_READBUF_BITS(extra_bits);
  160. CHECK_MORE_READBUF();
  161. }
  162. }
  163. DECODE_POS_SLOT(pos_slot);
  164. DUMP_READBUF_BITS(encoder->recording_dist_tree_len[pos_slot]);
  165. CHECK_MORE_READBUF();
  166. _ASSERT(pos_slot < 30);
  167. OUTPUT_DIST_SLOT(pos_slot);
  168. extra_pos_bits = g_ExtraDistanceBits[pos_slot];
  169. if (extra_pos_bits > 0)
  170. {
  171. unsigned int extra_data = read_bitbuf & ((1 << extra_pos_bits)-1);
  172. outputBits(context, extra_pos_bits, extra_data);
  173. DUMP_READBUF_BITS(extra_pos_bits);
  174. CHECK_MORE_READBUF();
  175. }
  176. }
  177. context->outputting_block_current_literal++;
  178. }
  179. // did we output all of our literals without running out of output space?
  180. if (context->outputting_block_current_literal >= context->outputting_block_num_literals)
  181. {
  182. // output the code signifying end-of-block
  183. OUTPUT_LITERAL(END_OF_BLOCK_CODE);
  184. // reset state
  185. context->state = STATE_NORMAL;
  186. }
  187. else
  188. {
  189. context->outputting_block_bitbuf = read_bitbuf;
  190. context->outputting_block_bitcount = read_bitcount;
  191. context->outputting_block_bufptr = read_bufptr;
  192. context->state = STATE_OUTPUTTING_BLOCK;
  193. }
  194. return TRUE;
  195. }
  196. //
  197. // Output a block. This routine will resume outputting a block that was already being
  198. // output if state != STATE_NORMAL.
  199. //
  200. BOOL OptimalEncoderOutputBlock(t_encoder_context *context)
  201. {
  202. t_optimal_encoder *encoder = context->optimal_encoder;
  203. _ASSERT(encoder != NULL);
  204. //
  205. // The tree creation routines cannot >= 65536 literals.
  206. //
  207. _ASSERT(context->outputting_block_num_literals < 65536);
  208. if (context->state == STATE_NORMAL)
  209. {
  210. //
  211. // Start outputting literals and distances from the beginning
  212. //
  213. context->outputting_block_current_literal = 0;
  214. //
  215. // Nothing to output? Then return
  216. //
  217. if (context->outputting_block_num_literals == 0)
  218. return TRUE;
  219. // make decoding table so that we can decode recorded items
  220. makeTable(
  221. MAX_LITERAL_TREE_ELEMENTS,
  222. REC_LITERALS_DECODING_TABLE_BITS,
  223. encoder->recording_literal_tree_len,
  224. encoder->recording_literal_tree_table,
  225. encoder->recording_literal_tree_left,
  226. encoder->recording_literal_tree_right
  227. );
  228. makeTable(
  229. MAX_DIST_TREE_ELEMENTS,
  230. REC_DISTANCES_DECODING_TABLE_BITS,
  231. encoder->recording_dist_tree_len,
  232. encoder->recording_dist_tree_table,
  233. encoder->recording_dist_tree_left,
  234. encoder->recording_dist_tree_right
  235. );
  236. // now make the trees used for encoding
  237. makeTree(
  238. MAX_LITERAL_TREE_ELEMENTS,
  239. 15,
  240. encoder->literal_tree_freq,
  241. encoder->literal_tree_code,
  242. encoder->literal_tree_len
  243. );
  244. makeTree(
  245. MAX_DIST_TREE_ELEMENTS,
  246. 15,
  247. encoder->dist_tree_freq,
  248. encoder->dist_tree_code,
  249. encoder->dist_tree_len
  250. );
  251. }
  252. //
  253. // Try outputting as a dynamic block
  254. //
  255. if (OptimalEncoderOutputDynamicBlock(context) == FALSE)
  256. {
  257. return FALSE;
  258. }
  259. if (context->state == STATE_NORMAL)
  260. {
  261. encoder->recording_bufptr = context->optimal_encoder->lit_dist_buffer;
  262. encoder->recording_bitbuf = 0;
  263. encoder->recording_bitcount = 0;
  264. context->outputting_block_num_literals = 0;
  265. // make sure there are no zero frequency items
  266. NormaliseFrequencies(encoder->literal_tree_freq, encoder->dist_tree_freq);
  267. // make tree for recording new items
  268. makeTree(
  269. MAX_DIST_TREE_ELEMENTS,
  270. RECORDING_DIST_MAX_CODE_LEN,
  271. encoder->dist_tree_freq,
  272. encoder->recording_dist_tree_code,
  273. encoder->recording_dist_tree_len
  274. );
  275. makeTree(
  276. MAX_LITERAL_TREE_ELEMENTS,
  277. RECORDING_LIT_MAX_CODE_LEN,
  278. encoder->literal_tree_freq,
  279. encoder->recording_literal_tree_code,
  280. encoder->recording_literal_tree_len
  281. );
  282. OptimalEncoderZeroFrequencyCounts(encoder);
  283. }
  284. return TRUE;
  285. }