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.

298 lines
6.8 KiB

  1. //
  2. // inftree.c
  3. //
  4. // Reads the tree for a dynamic block
  5. //
  6. #include <crtdbg.h>
  7. #include "inflate.h"
  8. #include "infmacro.h"
  9. #include "maketbl.h"
  10. //
  11. // Decode an element from the pre-tree
  12. //
  13. static int decodePretreeElement(t_decoder_context *context)
  14. {
  15. int element;
  16. retry:
  17. element = context->pretree_table[context->bitbuf & PRETREE_TABLE_MASK];
  18. while (element < 0)
  19. {
  20. unsigned long mask = 1 << PRETREE_TABLE_BITS;
  21. do
  22. {
  23. element = -element;
  24. if ((context->bitbuf & mask) == 0)
  25. element = context->pretree_left[element];
  26. else
  27. element = context->pretree_right[element];
  28. mask <<= 1;
  29. } while (element < 0);
  30. }
  31. //
  32. // If this code is longer than the # bits we had in the bit buffer (i.e.
  33. // we read only part of the code - but enough to know that it's too long),
  34. // return -1.
  35. //
  36. if (context->pretree_code_length[element] > (context->bitcount+16))
  37. {
  38. // if we run out of bits, return -1
  39. if (context->input_curpos >= context->end_input_buffer)
  40. return -1;
  41. context->bitbuf |= ((*context->input_curpos++) << (context->bitcount+16));
  42. context->bitcount += 8;
  43. goto retry;
  44. }
  45. dumpBits(context, context->pretree_code_length[element]);
  46. return element;
  47. }
  48. //
  49. // Dilemma:
  50. //
  51. // This code runs slowly because bitcount and bitbuf are accessed through the context,
  52. // not as local variables. However, if they were made into local variables, the code
  53. // size would be massively increased. Luckily the speed of this code isn't so important
  54. // compared to that of decodeCompressedBlock().
  55. //
  56. BOOL readDynamicBlockHeader(t_decoder_context *context)
  57. {
  58. int i;
  59. int code;
  60. #define NUM_CODE_LENGTH_ORDER_CODES (sizeof(g_CodeOrder)/sizeof(g_CodeOrder[0]))
  61. // make sure extern g_CodeOrder[] declared with array size!
  62. switch (context->state)
  63. {
  64. case STATE_READING_NUM_LIT_CODES:
  65. goto reenter_state_reading_num_lit_codes;
  66. case STATE_READING_NUM_DIST_CODES:
  67. goto reenter_state_reading_num_dist_codes;
  68. case STATE_READING_NUM_CODE_LENGTH_CODES:
  69. goto reenter_state_reading_num_code_length_codes;
  70. case STATE_READING_CODE_LENGTH_CODES:
  71. {
  72. i = context->state_loop_counter;
  73. goto reenter_state_reading_code_length_codes;
  74. }
  75. case STATE_READING_TREE_CODES_BEFORE:
  76. {
  77. i = context->state_loop_counter;
  78. goto reenter_state_reading_tree_codes_before;
  79. }
  80. case STATE_READING_TREE_CODES_AFTER:
  81. {
  82. i = context->state_loop_counter;
  83. code = context->state_code;
  84. goto reenter_state_reading_tree_codes_after;
  85. }
  86. default:
  87. return TRUE;
  88. }
  89. reenter_state_reading_num_lit_codes:
  90. if (ensureBitsContext(context, 5) == FALSE)
  91. {
  92. context->state = STATE_READING_NUM_LIT_CODES;
  93. return TRUE;
  94. }
  95. context->num_literal_codes = getBits(context, 5) + 257;
  96. reenter_state_reading_num_dist_codes:
  97. if (ensureBitsContext(context, 5) == FALSE)
  98. {
  99. context->state = STATE_READING_NUM_DIST_CODES;
  100. return TRUE;
  101. }
  102. context->num_dist_codes = getBits(context, 5) + 1;
  103. reenter_state_reading_num_code_length_codes:
  104. if (ensureBitsContext(context, 4) == FALSE)
  105. {
  106. context->state = STATE_READING_NUM_CODE_LENGTH_CODES;
  107. return TRUE;
  108. }
  109. context->num_code_length_codes = getBits(context, 4) + 4;
  110. for (i = 0; i < context->num_code_length_codes; i++)
  111. {
  112. reenter_state_reading_code_length_codes:
  113. if (ensureBitsContext(context, 3) == FALSE)
  114. {
  115. context->state = STATE_READING_CODE_LENGTH_CODES;
  116. context->state_loop_counter = i;
  117. return TRUE;
  118. }
  119. context->pretree_code_length[ g_CodeOrder[i] ] = (byte) getBits(context, 3);
  120. }
  121. for (i = context->num_code_length_codes; i < NUM_CODE_LENGTH_ORDER_CODES; i++)
  122. context->pretree_code_length[ g_CodeOrder[i] ] = 0;
  123. if (makeTable(
  124. NUM_PRETREE_ELEMENTS,
  125. PRETREE_TABLE_BITS,
  126. context->pretree_code_length,
  127. context->pretree_table,
  128. context->pretree_left,
  129. context->pretree_right
  130. ) == FALSE)
  131. {
  132. return FALSE;
  133. }
  134. context->temp_code_array_size = context->num_literal_codes + context->num_dist_codes;
  135. for (i = 0; i < context->temp_code_array_size; )
  136. {
  137. reenter_state_reading_tree_codes_before:
  138. _ASSERT(context->bitcount >= -16);
  139. if (context->bitcount == -16)
  140. {
  141. if (context->input_curpos >= context->end_input_buffer)
  142. {
  143. context->state = STATE_READING_TREE_CODES_BEFORE;
  144. context->state_loop_counter = i;
  145. return TRUE;
  146. }
  147. context->bitbuf |= ((*context->input_curpos++) << (context->bitcount+16));
  148. context->bitcount += 8;
  149. }
  150. code = decodePretreeElement(context);
  151. if (code < 0)
  152. {
  153. context->state = STATE_READING_TREE_CODES_BEFORE;
  154. context->state_loop_counter = i;
  155. return TRUE;
  156. }
  157. reenter_state_reading_tree_codes_after:
  158. if (code <= 15)
  159. {
  160. context->temp_code_list[i++] = (unsigned char) code;
  161. }
  162. else
  163. {
  164. int repeat_count, j;
  165. //
  166. // If the code is > 15 it means there is a repeat count of 2, 3, or 7 bits
  167. //
  168. if (ensureBitsContext(context, 7) == FALSE)
  169. {
  170. context->state = STATE_READING_TREE_CODES_AFTER;
  171. context->state_code = (unsigned char) code;
  172. context->state_loop_counter = i;
  173. return TRUE;
  174. }
  175. if (code == 16)
  176. {
  177. byte prev_code;
  178. // can't have "prev code" on first code
  179. if (i == 0)
  180. return FALSE;
  181. prev_code = context->temp_code_list[i-1];
  182. repeat_count = getBits(context, 2) + 3;
  183. if (i + repeat_count > context->temp_code_array_size)
  184. return FALSE;
  185. for (j = 0; j < repeat_count; j++)
  186. context->temp_code_list[i++] = prev_code;
  187. }
  188. else if (code == 17)
  189. {
  190. repeat_count = getBits(context, 3) + 3;
  191. if (i + repeat_count > context->temp_code_array_size)
  192. return FALSE;
  193. for (j = 0; j < repeat_count; j++)
  194. context->temp_code_list[i++] = 0;
  195. }
  196. else // code == 18
  197. {
  198. repeat_count = getBits(context, 7) + 11;
  199. if (i + repeat_count > context->temp_code_array_size)
  200. return FALSE;
  201. for (j = 0; j < repeat_count; j++)
  202. context->temp_code_list[i++] = 0;
  203. }
  204. }
  205. }
  206. //
  207. // Create literal and distance tables
  208. //
  209. memcpy(context->literal_tree_code_length, context->temp_code_list, context->num_literal_codes);
  210. for (i = context->num_literal_codes; i < MAX_LITERAL_TREE_ELEMENTS; i++)
  211. context->literal_tree_code_length[i] = 0;
  212. for (i = 0; i < context->num_dist_codes; i++)
  213. context->distance_tree_code_length[i] = context->temp_code_list[i + context->num_literal_codes];
  214. for (i = context->num_dist_codes; i < MAX_DIST_TREE_ELEMENTS; i++)
  215. context->distance_tree_code_length[i] = 0;
  216. //
  217. // Make sure there is an end-of-block code, otherwise how could we ever end?
  218. //
  219. if (context->literal_tree_code_length[END_OF_BLOCK_CODE] == 0)
  220. return FALSE;
  221. context->state = STATE_DECODE_TOP;
  222. return TRUE;
  223. }