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.

356 lines
10 KiB

  1. //
  2. // stdblock.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 StdEncoderOutputDynamicBlock(t_encoder_context *context)
  83. {
  84. unsigned long read_bitbuf;
  85. int read_bitcount;
  86. byte * read_bufptr;
  87. t_std_encoder *encoder = context->std_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 StdEncoderOutputBlock(t_encoder_context *context)
  201. {
  202. t_std_encoder *encoder = context->std_encoder;
  203. //
  204. // The tree creation routines cannot handle this overflow
  205. //
  206. _ASSERT(context->outputting_block_num_literals < 65536);
  207. if (context->state == STATE_NORMAL)
  208. {
  209. //
  210. // Start outputting literals and distances from the beginning
  211. //
  212. context->outputting_block_current_literal = 0;
  213. //
  214. // Nothing to output? Then return
  215. //
  216. if (context->outputting_block_num_literals == 0)
  217. return TRUE;
  218. // make decoding table so that we can decode recorded items
  219. makeTable(
  220. MAX_LITERAL_TREE_ELEMENTS,
  221. REC_LITERALS_DECODING_TABLE_BITS,
  222. encoder->recording_literal_tree_len,
  223. encoder->recording_literal_tree_table,
  224. encoder->recording_literal_tree_left,
  225. encoder->recording_literal_tree_right
  226. );
  227. makeTable(
  228. MAX_DIST_TREE_ELEMENTS,
  229. REC_DISTANCES_DECODING_TABLE_BITS,
  230. encoder->recording_dist_tree_len,
  231. encoder->recording_dist_tree_table,
  232. encoder->recording_dist_tree_left,
  233. encoder->recording_dist_tree_right
  234. );
  235. // NormaliseFrequencies(context->literal_tree_freq, context->dist_tree_freq);
  236. //context->dist_tree_freq[30] = 0;
  237. //context->dist_tree_freq[31] = 0;
  238. // now make the trees used for encoding
  239. makeTree(
  240. MAX_LITERAL_TREE_ELEMENTS,
  241. 15,
  242. encoder->literal_tree_freq,
  243. encoder->literal_tree_code,
  244. encoder->literal_tree_len
  245. );
  246. makeTree(
  247. MAX_DIST_TREE_ELEMENTS,
  248. 15,
  249. encoder->dist_tree_freq,
  250. encoder->dist_tree_code,
  251. encoder->dist_tree_len
  252. );
  253. //GenerateTable("g_FastEncoderLiteralTree", MAX_LITERAL_TREE_ELEMENTS, context->literal_tree_len, context->literal_tree_code);
  254. //GenerateTable("g_FastEncoderDistanceTree", MAX_DIST_TREE_ELEMENTS, context->dist_tree_len, context->dist_tree_code);
  255. }
  256. //
  257. // Try outputting as a dynamic block
  258. //
  259. if (StdEncoderOutputDynamicBlock(context) == FALSE)
  260. {
  261. return FALSE;
  262. }
  263. if (context->state == STATE_NORMAL)
  264. {
  265. encoder->recording_bufptr = context->std_encoder->lit_dist_buffer;
  266. encoder->recording_bitbuf = 0;
  267. encoder->recording_bitcount = 0;
  268. context->outputting_block_num_literals = 0;
  269. // make sure there are no zero frequency items
  270. NormaliseFrequencies(encoder->literal_tree_freq, encoder->dist_tree_freq);
  271. // make tree for recording new items
  272. makeTree(
  273. MAX_DIST_TREE_ELEMENTS,
  274. RECORDING_DIST_MAX_CODE_LEN,
  275. encoder->dist_tree_freq,
  276. encoder->recording_dist_tree_code,
  277. encoder->recording_dist_tree_len
  278. );
  279. makeTree(
  280. MAX_LITERAL_TREE_ELEMENTS,
  281. RECORDING_LIT_MAX_CODE_LEN,
  282. encoder->literal_tree_freq,
  283. encoder->recording_literal_tree_code,
  284. encoder->recording_literal_tree_len
  285. );
  286. StdEncoderZeroFrequencyCounts(encoder);
  287. }
  288. return TRUE;
  289. }