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.

187 lines
3.5 KiB

  1. //
  2. // maketbl.c
  3. //
  4. // Creates Huffman decoding tables
  5. //
  6. #include <windows.h>
  7. #include <crtdbg.h>
  8. #include "common.h"
  9. #include "maketbl.h"
  10. //
  11. // Reverse the bits, len > 0
  12. //
  13. static unsigned int bitReverse(unsigned int code, int len)
  14. {
  15. unsigned int new_code = 0;
  16. _ASSERT(len > 0);
  17. do
  18. {
  19. new_code |= (code & 1);
  20. new_code <<= 1;
  21. code >>= 1;
  22. } while (--len > 0);
  23. return new_code >> 1;
  24. }
  25. BOOL makeTable(
  26. int num_elements,
  27. int table_bits,
  28. const byte * code_length,
  29. short * table,
  30. short * left,
  31. short * right
  32. )
  33. {
  34. int bl_count[17];
  35. unsigned int next_code[17];
  36. unsigned int code[MAX_LITERAL_TREE_ELEMENTS];
  37. int temp_code;
  38. int avail;
  39. int i, bits, ch;
  40. int table_size, table_mask;
  41. table_size = 1 << table_bits;
  42. table_mask = table_size - 1;
  43. for (i = 0; i <= 16; i++)
  44. bl_count[i] = 0;
  45. for (i = 0; i < num_elements; i++)
  46. bl_count[ code_length[i] ]++;
  47. //
  48. // If there are any codes larger than table_bits in length, then
  49. // we will have to clear the table for our left/right spillover
  50. // code to work correctly.
  51. //
  52. // If there aren't any codes that large, then all table entries
  53. // will be written over without being read, so we don't need to
  54. // initialise them
  55. //
  56. for (i = table_bits; i <= 16; i++)
  57. {
  58. if (bl_count[i] > 0)
  59. {
  60. int j;
  61. // found a code larger than table_bits
  62. for (j = 0; j < table_size; j++)
  63. table[j] = 0;
  64. break;
  65. }
  66. }
  67. temp_code = 0;
  68. bl_count[0] = 0;
  69. for (bits = 1; bits <= 16; bits++)
  70. {
  71. temp_code = (temp_code + bl_count[bits-1]) << 1;
  72. next_code[bits] = temp_code;
  73. }
  74. for (i = 0; i < num_elements; i++)
  75. {
  76. int len = code_length[i];
  77. if (len > 0)
  78. {
  79. code[i] = bitReverse(next_code[len], len);
  80. next_code[len]++;
  81. }
  82. }
  83. avail = num_elements;
  84. for (ch = 0; ch < num_elements; ch++)
  85. {
  86. int start_at, len;
  87. // length of this code
  88. len = code_length[ch];
  89. // start value (bit reversed)
  90. start_at = code[ch];
  91. if (len > 0)
  92. {
  93. if (len <= table_bits)
  94. {
  95. int locs = 1 << (table_bits - len);
  96. int increment = 1 << len;
  97. int j;
  98. //
  99. // Make sure that in the loop below, start_at is always
  100. // less than table_size.
  101. //
  102. // On last iteration we store at array index:
  103. // initial_start_at + (locs-1)*increment
  104. // = initial_start_at + locs*increment - increment
  105. // = initial_start_at + (1 << table_bits) - increment
  106. // = initial_start_at + table_size - increment
  107. //
  108. // Therefore we must ensure:
  109. // initial_start_at + table_size - increment < table_size
  110. // or: initial_start_at < increment
  111. //
  112. if (start_at >= increment)
  113. return FALSE; // invalid table!
  114. for (j = 0; j < locs; j++)
  115. {
  116. table[start_at] = (short) ch;
  117. start_at += increment;
  118. }
  119. }
  120. else
  121. {
  122. int overflow_bits;
  123. int code_bit_mask;
  124. short * p;
  125. overflow_bits = len - table_bits;
  126. code_bit_mask = 1 << table_bits;
  127. p = &table[start_at & table_mask];
  128. do
  129. {
  130. short value;
  131. value = *p;
  132. if (value == 0)
  133. {
  134. left[avail] = 0;
  135. right[avail] = 0;
  136. *p = -avail;
  137. value = -avail;
  138. avail++;
  139. }
  140. if ((start_at & code_bit_mask) == 0)
  141. p = &left[-value];
  142. else
  143. p = &right[-value];
  144. code_bit_mask <<= 1;
  145. overflow_bits--;
  146. } while (overflow_bits != 0);
  147. *p = (short) ch;
  148. }
  149. }
  150. }
  151. return TRUE;
  152. }