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.

184 lines
5.2 KiB

  1. //
  2. // definit.c
  3. //
  4. // Initialisation code for deflate (compression stage)
  5. //
  6. // Includes both some one-time init routines, as well as a per context/reset init routine
  7. //
  8. #include "types.h"
  9. #include "deflate.h"
  10. #include "inflate.h"
  11. #include "defproto.h"
  12. #include <string.h>
  13. #include <stdio.h>
  14. #include <crtdbg.h>
  15. //
  16. // This function is called by the standard and optimal encoders, and creates the initial tree
  17. // used to record literals for the first block. After the first block we use the last block's
  18. // trees to record data.
  19. //
  20. // This function does not change global data, and is called one a per context creation/reset.
  21. //
  22. VOID DeflateInitRecordingTables(
  23. BYTE * recording_literal_len,
  24. USHORT *recording_literal_code,
  25. BYTE * recording_dist_len,
  26. USHORT *recording_dist_code
  27. )
  28. {
  29. // BUGBUG These frequencies were taken from running on some text file, better stats could
  30. // be obtained from using an html page. This barely affects compression though; bad estimates
  31. // will just make the recording buffer fill up a little bit sooner, making us output a block
  32. // a little sooner, which isn't always a bad thing anyway.
  33. USHORT recording_dist_tree_freq[MAX_DIST_TREE_ELEMENTS*2] =
  34. {
  35. 2,2,3,4,3,7,16,22,42,60,100,80,149,158,223,200,380,324,537,
  36. 477,831,752,1231,999,1369,1100,2034,1667,2599,2216,0,0
  37. };
  38. USHORT recording_literal_tree_freq[MAX_LITERAL_TREE_ELEMENTS*2];
  39. int i;
  40. makeTree(
  41. MAX_DIST_TREE_ELEMENTS,
  42. RECORDING_DIST_MAX_CODE_LEN,
  43. recording_dist_tree_freq,
  44. recording_dist_code,
  45. recording_dist_len
  46. );
  47. // BUGBUG Put a better estimation in here! This assumes all literals (chars and matches)
  48. // are equally likely, which they aren't (although all chars might be fairly equal for a
  49. // binary file).
  50. for (i = 0; i < MAX_LITERAL_TREE_ELEMENTS; i++)
  51. recording_literal_tree_freq[i] = 1;
  52. makeTree(
  53. MAX_LITERAL_TREE_ELEMENTS,
  54. RECORDING_LIT_MAX_CODE_LEN,
  55. recording_literal_tree_freq,
  56. recording_literal_code,
  57. recording_literal_len
  58. );
  59. }
  60. //
  61. // One-time init
  62. //
  63. // Generate the global slot tables which allow us to convert a distance
  64. // (0..32K) to a distance slot (0..29), and a length (3..258) to
  65. // a length slot (0...28)
  66. //
  67. static void GenerateSlotTables(void)
  68. {
  69. int code, length, dist, n;
  70. /* Initialize the mapping length (0..255) -> length code (0..28) */
  71. length = 0;
  72. for (code = 0; code < NUM_LENGTH_BASE_CODES-1; code++)
  73. {
  74. for (n = 0; n < (1 << g_ExtraLengthBits[code]); n++)
  75. g_LengthLookup[length++] = (byte) code;
  76. }
  77. g_LengthLookup[length-1] = (byte) code;
  78. /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
  79. dist = 0;
  80. for (code = 0 ; code < 16; code++)
  81. {
  82. for (n = 0; n < (1 << g_ExtraDistanceBits[code]); n++)
  83. g_DistLookup[dist++] = (byte) code;
  84. }
  85. dist >>= 7; /* from now on, all distances are divided by 128 */
  86. for ( ; code < NUM_DIST_BASE_CODES; code++)
  87. {
  88. for (n = 0; n < (1 << (g_ExtraDistanceBits[code]-7)); n++)
  89. g_DistLookup[256 + dist++] = (byte) code;
  90. }
  91. // ensure we didn't overflow the array
  92. _ASSERT(256 + dist <= sizeof(g_DistLookup)/sizeof(g_DistLookup[0]));
  93. }
  94. //
  95. // One-time init
  96. //
  97. // Generate tables for encoding static blocks
  98. //
  99. static void GenerateStaticEncodingTables(void)
  100. {
  101. int i;
  102. int len_cnt[17];
  103. BYTE StaticDistanceTreeLength[MAX_DIST_TREE_ELEMENTS];
  104. // ensure we have already created the StaticLiteralTreeLength array
  105. // if we haven't, then this value would be zero
  106. _ASSERT(g_StaticLiteralTreeLength[0] != 0);
  107. //
  108. // Make literal tree
  109. //
  110. for (i = 0; i < 17; i++)
  111. len_cnt[i] = 0;
  112. // length count (how many length 8's, 9's, etc. there are) - needed to call makeCode()
  113. len_cnt[8] = 144;
  114. len_cnt[9] = 255-144+1;
  115. len_cnt[7] = 279-256+1;
  116. len_cnt[8] += (287-280)+1;
  117. makeCode(
  118. MAX_LITERAL_TREE_ELEMENTS,
  119. len_cnt,
  120. g_StaticLiteralTreeLength,
  121. g_StaticLiteralTreeCode
  122. );
  123. //
  124. // Make distance tree; there are 32 5-bit codes
  125. //
  126. for (i = 0; i < 17; i++)
  127. len_cnt[i] = 0;
  128. len_cnt[5] = 32;
  129. // We don't store StaticDistanceTreeLength[] globally, since it's 5 for everything,
  130. // but we need it to call makeCode()
  131. for (i = 0; i < MAX_DIST_TREE_ELEMENTS; i++)
  132. StaticDistanceTreeLength[i] = 5;
  133. makeCode(
  134. MAX_DIST_TREE_ELEMENTS,
  135. len_cnt,
  136. StaticDistanceTreeLength,
  137. g_StaticDistanceTreeCode
  138. );
  139. }
  140. //
  141. // Initialise global deflate data in the DLL
  142. //
  143. VOID deflateInit(VOID)
  144. {
  145. GenerateSlotTables();
  146. InitStaticBlock();
  147. GenerateStaticEncodingTables();
  148. // For the fast encoder, take the hard-coded global tree we're using (which is NOT the same as
  149. // a static block's tree), generate the bitwise output for outputting the structure of that
  150. // tree, and record that globally, so that we can do a simple memcpy() to output the tree for
  151. // the fast encoder, instead of calling the tree output routine all the time. This is a nifty
  152. // performance optimisation.
  153. FastEncoderGenerateDynamicTreeEncoding();
  154. }