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.

559 lines
21 KiB

  1. //************************************************************************
  2. // compress.c
  3. //
  4. // Code for MPPC compression. Decompression code is on the client,
  5. // \nt\private\tsext\client\core\compress.c.
  6. //
  7. // Copyright(c) Microsoft Corp., 1990-1999
  8. //
  9. // Revision history:
  10. // 5/5/94 Created gurdeep
  11. // 4/21/1999 Optimize for TS jparsons, erikma
  12. //************************************************************************
  13. #include "adcg.h"
  14. #pragma hdrstop
  15. #define DLL_WD
  16. #include <compress.h>
  17. /*
  18. The key for the multiplicative hash function consists of 3 unsigned
  19. characters. They are composed (logically) by concatenating them i.e.
  20. the composed key = 2^16*c2 + 2^8*c2 + c3 and fits in 24 bits. The
  21. composed key is not actually computed here as we use the components
  22. to directly compute the hash function.
  23. The multiplicative hash function consists of taking the higher order
  24. N bits (corresponding to the log2 of the hash table size) above the
  25. low-order 12 bits of the product key * Multiplier where:
  26. Multiplier = floor(A * pow(2.0, (double) w));
  27. double A = 0.6125423371; (chosen according to Knuth vol 3 p. 512)
  28. w = 24 (the key's width in bits)
  29. The algorithm for this is in Cormen/Leiserson/Rivest.
  30. To do the multplication efficiently, the product c * Multiplier is
  31. precomputed and stored in lookup_array1 (for all 256 possible c's).
  32. */
  33. #define MULTHASH1(c1,c2,c3) \
  34. ((lookup_array1[c1] + \
  35. (lookup_array1[c2] << 8) + \
  36. (lookup_array1[c3] << 16)) & 0x07fff000) >> 12
  37. const unsigned long lookup_array1[256] = {
  38. 0, 10276755, 20553510, 30830265,
  39. 41107020, 51383775, 61660530, 71937285,
  40. 82214040, 92490795, 102767550, 113044305,
  41. 123321060, 133597815, 143874570, 154151325,
  42. 164428080, 174704835, 184981590, 195258345,
  43. 205535100, 215811855, 226088610, 236365365,
  44. 246642120, 256918875, 267195630, 277472385,
  45. 287749140, 298025895, 308302650, 318579405,
  46. 328856160, 339132915, 349409670, 359686425,
  47. 369963180, 380239935, 390516690, 400793445,
  48. 411070200, 421346955, 431623710, 441900465,
  49. 452177220, 462453975, 472730730, 483007485,
  50. 493284240, 503560995, 513837750, 524114505,
  51. 534391260, 544668015, 554944770, 565221525,
  52. 575498280, 585775035, 596051790, 606328545,
  53. 616605300, 626882055, 637158810, 647435565,
  54. 657712320, 667989075, 678265830, 688542585,
  55. 698819340, 709096095, 719372850, 729649605,
  56. 739926360, 750203115, 760479870, 770756625,
  57. 781033380, 791310135, 801586890, 811863645,
  58. 822140400, 832417155, 842693910, 852970665,
  59. 863247420, 873524175, 883800930, 894077685,
  60. 904354440, 914631195, 924907950, 935184705,
  61. 945461460, 955738215, 966014970, 976291725,
  62. 986568480, 996845235, 1007121990, 1017398745,
  63. 1027675500, 1037952255, 1048229010, 1058505765,
  64. 1068782520, 1079059275, 1089336030, 1099612785,
  65. 1109889540, 1120166295, 1130443050, 1140719805,
  66. 1150996560, 1161273315, 1171550070, 1181826825,
  67. 1192103580, 1202380335, 1212657090, 1222933845,
  68. 1233210600, 1243487355, 1253764110, 1264040865,
  69. 1274317620, 1284594375, 1294871130, 1305147885,
  70. 1315424640, 1325701395, 1335978150, 1346254905,
  71. 1356531660, 1366808415, 1377085170, 1387361925,
  72. 1397638680, 1407915435, 1418192190, 1428468945,
  73. 1438745700, 1449022455, 1459299210, 1469575965,
  74. 1479852720, 1490129475, 1500406230, 1510682985,
  75. 1520959740, 1531236495, 1541513250, 1551790005,
  76. 1562066760, 1572343515, 1582620270, 1592897025,
  77. 1603173780, 1613450535, 1623727290, 1634004045,
  78. 1644280800, 1654557555, 1664834310, 1675111065,
  79. 1685387820, 1695664575, 1705941330, 1716218085,
  80. 1726494840, 1736771595, 1747048350, 1757325105,
  81. 1767601860, 1777878615, 1788155370, 1798432125,
  82. 1808708880, 1818985635, 1829262390, 1839539145,
  83. 1849815900, 1860092655, 1870369410, 1880646165,
  84. 1890922920, 1901199675, 1911476430, 1921753185,
  85. 1932029940, 1942306695, 1952583450, 1962860205,
  86. 1973136960, 1983413715, 1993690470, 2003967225,
  87. 2014243980, 2024520735, 2034797490, 2045074245,
  88. 2055351000, 2065627755, 2075904510, 2086181265,
  89. 2096458020, 2106734775, 2117011530, 2127288285,
  90. 2137565040, 2147841795, 2158118550, 2168395305,
  91. 2178672060, 2188948815, 2199225570, 2209502325,
  92. 2219779080, 2230055835, 2240332590, 2250609345,
  93. 2260886100, 2271162855, 2281439610, 2291716365,
  94. 2301993120, 2312269875, 2322546630, 2332823385,
  95. 2343100140, 2353376895, 2363653650, 2373930405,
  96. 2384207160, 2394483915, 2404760670, 2415037425,
  97. 2425314180, 2435590935, 2445867690, 2456144445,
  98. 2466421200, 2476697955, 2486974710, 2497251465,
  99. 2507528220, 2517804975, 2528081730, 2538358485,
  100. 2548635240, 2558911995, 2569188750, 2579465505,
  101. 2589742260, 2600019015, 2610295770, 2620572525
  102. };
  103. // Bitstream output functions
  104. //
  105. // We keep a sequence of 16 bits in the variable "byte". The current bit
  106. // pointer is kept in the "bit" variable, numbered from 1..16. We add bits
  107. // from 16 towards 1; whenever we cross the boundary from bit 9 to bit 8
  108. // we output the top 8 bits to the output stream (at *pbyte), shift the low
  109. // 8 bits to the high location, and reset the "bit" variable to match the
  110. // new insert location.
  111. //
  112. //
  113. /* Bitptrs point to the current byte. The current bit (i.e. next bit to be
  114. * stored) is masked off by the bit entry. When this reaches zero, it is
  115. * reset to 0x80 and the next byte is set up. The bytes are filled MSBit
  116. * first. */
  117. /* Starts and sets the first byte to zero for the bitptr. */
  118. #define bitptr_init(s) pbyte = s; byte=0; bit = 16;
  119. /* Sets up the byte part of the bitptr so that it is pointing to the byte after
  120. * the byte which had the last bit put into it. */
  121. #define bitptr_end() if (bit != 16) *pbyte++ = (UCHAR)(byte >> 8);
  122. /* Goes to the next bit, and byte if necessary. */
  123. #define bitptr_next() \
  124. if (bit < 10) { \
  125. *pbyte++ = (UCHAR)(byte >> 8); \
  126. byte <<= 8; \
  127. bit = 16; \
  128. } else \
  129. bit-- ;
  130. /* Advances to the next bit, and byte if necessary, readjusting the bit. */
  131. #define bitptr_advance() \
  132. if (bit < 9) { \
  133. *pbyte++ = (UCHAR)(byte >> 8); \
  134. bit+=8; \
  135. byte <<= 8; \
  136. }
  137. /* BIT I/O FUNCTIONS *********************************************************/
  138. /* These routines output most-significant-bit-first and the input will return
  139. * them MSB first, too. */
  140. /* Outputs a one bit in the bit stream. */
  141. #define out_bit_1() bit--; byte |= (1 << bit); bitptr_advance();
  142. #define out_bit_0() bitptr_next();
  143. #define out_bits_2(w) bit-=2; byte|=((w) << bit); bitptr_advance();
  144. #define out_bits_3(w) bit-=3; byte|=((w) << bit); bitptr_advance();
  145. #define out_bits_4(w) bit-=4; byte|=((w) << bit); bitptr_advance();
  146. #define out_bits_5(w) bit-=5; byte|=((w) << bit); bitptr_advance();
  147. #define out_bits_6(w) bit-=6; byte|=((w) << bit); bitptr_advance();
  148. #define out_bits_7(w) bit-=7; byte|=((w) << bit); bitptr_advance();
  149. #define out_bits_8(w) byte|=((w) << (bit-8)); *pbyte++=(UCHAR)(byte >> 8); byte <<= 8;
  150. #define out_bits_9(w) \
  151. if (bit > 9) { \
  152. byte |= ((w) << (bit - 9)); \
  153. *pbyte++ = (UCHAR)(byte >> 8); \
  154. bit--; \
  155. byte <<= 8; \
  156. } else { \
  157. bit=16; byte |= (w); \
  158. *pbyte++ = (UCHAR)(byte >> 8); \
  159. *pbyte++=(UCHAR)(byte); byte=0; \
  160. }
  161. #define out_bits_10(w) \
  162. if (bit > 10) { \
  163. bit-=10; byte |= ((w) << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
  164. } else { \
  165. out_bits_2(((w) >> 8)); \
  166. out_bits_8(((w) & 0xFF)); \
  167. }
  168. //
  169. // Weird effect - if out_bits_9 used instead of out_bits_8,
  170. // it's faster! if (bit == 11) is faster than if (bit != 11).
  171. //
  172. #define out_bits_11(w) \
  173. if (bit > 11) { \
  174. bit-=11; byte |= ((w) << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
  175. } else { \
  176. if (bit == 11) { \
  177. bit=16; byte |= (w); \
  178. *pbyte++=(UCHAR)(byte >> 8); *pbyte++=(UCHAR)(byte); byte=0; \
  179. } else { \
  180. bit=11-bit; \
  181. byte|=((w) >> bit); \
  182. *pbyte++=(UCHAR)(byte >> 8); *pbyte++=(UCHAR)(byte); \
  183. bit = 16-bit; \
  184. byte=((w) << bit); \
  185. } \
  186. }
  187. #define out_bits_12(w) \
  188. if (bit > 12) { \
  189. bit-=12; byte |= ((w) << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
  190. } else { \
  191. out_bits_4(((w) >> 8)); \
  192. out_bits_8(((w) & 0xFF)); \
  193. }
  194. #define out_bits_13(w) \
  195. if (bit > 13) { \
  196. bit-=13; byte |= ((w) << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
  197. } else { \
  198. out_bits_5(((w) >> 8)); \
  199. out_bits_8(((w) & 0xFF)); \
  200. }
  201. #define out_bits_14(w) \
  202. if (bit > 14) { \
  203. bit-=14; byte |= ((w) << bit); *pbyte++ = (UCHAR)(byte >> 8); bit+=8; byte <<=8; \
  204. } else { \
  205. out_bits_6(((w) >> 8)); \
  206. out_bits_8(((w) & 0xFF)); \
  207. }
  208. // For N in range 1..15
  209. #define out_bits_N(N, w) \
  210. if (bit > (N)) { \
  211. bit -= (N); \
  212. byte |= ((w) << bit); \
  213. if (bit < 9) { \
  214. *pbyte++ = (UCHAR)(byte >> 8); \
  215. bit += 8; \
  216. byte <<= 8; \
  217. } \
  218. } \
  219. else if (bit < (N)) { \
  220. bit = (N) - bit; \
  221. byte |= ((w) >> bit); \
  222. *pbyte++ = (UCHAR)(byte >> 8); \
  223. *pbyte++ = (UCHAR)(byte); \
  224. bit = 16 - bit; \
  225. byte = ((w) << bit); \
  226. } \
  227. else { \
  228. bit = 16; byte |= (w); \
  229. *pbyte++ = (UCHAR)(byte >> 8); \
  230. if ((N) > 8) { \
  231. *pbyte++ = (UCHAR)(byte); \
  232. byte <<= 8; \
  233. } \
  234. byte = 0; \
  235. }
  236. // compress()
  237. //
  238. // Function: Main compression function.
  239. //
  240. // Parameters:
  241. // IN CurrentBuffer -> points to data to compress
  242. // OUT CompOutBuffer -> points to buffer into which to compress data
  243. // IN CurrentLength -> points to Length of data to compress
  244. // IN context -> connection compress context
  245. //
  246. // Returns: Nothing
  247. //
  248. // WARNING: CODE IS HIGHLY OPTIMIZED FOR TIME.
  249. //
  250. UCHAR compress(
  251. UCHAR *CurrentBuffer,
  252. UCHAR *CompOutBuffer,
  253. ULONG *CurrentLength,
  254. SendContext *context)
  255. {
  256. int bit;
  257. int byte;
  258. int backptr;
  259. int cbMatch;
  260. int hashvalue;
  261. UCHAR *matchptr;
  262. UCHAR *pbyte;
  263. UCHAR *historyptr;
  264. UCHAR *currentptr;
  265. UCHAR *endptr;
  266. UCHAR hashchar1;
  267. UCHAR hashchar2;
  268. UCHAR hashchar3;
  269. int literal;
  270. UCHAR status; // return flags
  271. unsigned ComprType;
  272. ULONG HistorySize;
  273. UCHAR *pEndOutBuf;
  274. // Will this packet fit at the end of the history buffer?
  275. // Note that for compatibility with Win16 client, we deliberately do not
  276. // use a few bytes at the end of the buffer. The Win16 client requires
  277. // using GlobalAlloc() to allocate more than 65535 bytes; rather than
  278. // endure the pain, we use 64K minus a bit, then use LocalAlloc to create
  279. // the block.
  280. if ((context->CurrentIndex + *CurrentLength) < (context->HistorySize - 3) &&
  281. (context->CurrentIndex != 0)) {
  282. status = 0;
  283. }
  284. else {
  285. context->CurrentIndex = 0; // Index into the history
  286. status = PACKET_AT_FRONT;
  287. }
  288. // Start out the bit pointing output
  289. bitptr_init(CompOutBuffer);
  290. historyptr = context->History + context->CurrentIndex;
  291. currentptr = CurrentBuffer;
  292. endptr = currentptr + *CurrentLength - 1;
  293. pEndOutBuf = CompOutBuffer + *CurrentLength - 1;
  294. ComprType = context->ClientComprType;
  295. HistorySize = context->HistorySize;
  296. while (currentptr < (endptr - 2)) {
  297. *historyptr++ = hashchar1 = *currentptr++;
  298. hashchar2 = *currentptr;
  299. hashchar3 = *(currentptr + 1);
  300. hashvalue = MULTHASH1(hashchar1, hashchar2, hashchar3);
  301. matchptr = context->History + context->HashTable[hashvalue];
  302. if (matchptr != (historyptr - 1))
  303. context->HashTable[hashvalue] = (USHORT)
  304. (historyptr - context->History);
  305. if (context->ValidHistory < historyptr)
  306. context->ValidHistory = historyptr;
  307. if (matchptr != context->History &&
  308. *(matchptr - 1) == hashchar1 && *matchptr == hashchar2 &&
  309. *(matchptr + 1) == hashchar3 && matchptr != (historyptr - 1) &&
  310. matchptr != historyptr &&
  311. (matchptr + 1) <= context->ValidHistory) {
  312. backptr = (int)((historyptr - matchptr) & (HistorySize - 1));
  313. *historyptr++ = hashchar2; // copy the other 2 chars
  314. *historyptr++ = hashchar3; // copy the other 2 chars
  315. currentptr += 2;
  316. cbMatch = 3; // length of match
  317. matchptr += 2; // we have already matched 3
  318. while ((*matchptr == *currentptr) &&
  319. (currentptr < endptr) &&
  320. (matchptr <= context->ValidHistory)) {
  321. matchptr++ ;
  322. *historyptr++ = *currentptr++ ;
  323. cbMatch++ ;
  324. }
  325. // Make sure we're not going to overshoot the end of the output
  326. // buffer. At most we require 3 bytes for the backptr and
  327. // 4 bytes for the length.
  328. if ((pbyte + 7) <= pEndOutBuf) {
  329. // First output the backpointer
  330. if (ComprType == PACKET_COMPR_TYPE_64K) {
  331. // 64K needs special processing here because the leading bit
  332. // codes are different to correspond with the measured backptr
  333. // distributions and to add an 11-bit optimization that cuts
  334. // another couple of percentage points off the total
  335. // compression.
  336. if (backptr >= (64 + 256 + 2048)) { // Most common (2.1E6)
  337. backptr -= 64 + 256 + 2048;
  338. out_bits_7((0x60000 + backptr) >> 12); // 110 + 16 bits
  339. out_bits_12(backptr);
  340. }
  341. else if (backptr >= (64 + 256)) { // Less common (9.8E5)
  342. backptr -= 64 + 256;
  343. out_bits_7((0x7000 + backptr) >> 8); // 1110 + 11 bits
  344. out_bits_8(backptr);
  345. }
  346. else if (backptr >= 64) { // Even less common (6.5E5)
  347. backptr += (0x1E00 - 64); // 11110 + 8 bits
  348. out_bits_13(backptr);
  349. } else { // Least common (5.8E5)
  350. backptr += 0x7c0; // 11111 + 6 bits
  351. out_bits_11(backptr);
  352. }
  353. }
  354. else {
  355. // Original handling for PACKET_COMPR_TYPE_8K.
  356. if (backptr >= (64 + 256)) {
  357. backptr -= 64 + 256;
  358. out_bits_8((0xc000 + backptr) >> 8); // 110 + 13 bits
  359. out_bits_8(backptr);
  360. }
  361. else if (backptr >= 64) {
  362. backptr += (0xE00 - 64); // 1110 + 8 bits
  363. out_bits_12(backptr);
  364. }
  365. else {
  366. // 1111 + 6 bits
  367. backptr += 0x3c0;
  368. out_bits_10(backptr);
  369. }
  370. }
  371. // Output the length of the match encoding.
  372. if (cbMatch == 3) { // Most common by far.
  373. out_bit_0();
  374. }
  375. else if (cbMatch < 8) {
  376. out_bits_4(0x08 + cbMatch - 4);
  377. }
  378. else if (cbMatch < 16) {
  379. out_bits_6(0x30 + cbMatch - 8);
  380. }
  381. else if (cbMatch < 32) {
  382. out_bits_8(0xE0 + cbMatch - 16);
  383. }
  384. else if (cbMatch < 64) {
  385. out_bits_4(0x0F);
  386. out_bits_6(cbMatch - 32);
  387. }
  388. else if (cbMatch < 128) {
  389. out_bits_5(0x1F);
  390. out_bits_7(cbMatch - 64);
  391. }
  392. else if (cbMatch < 256) {
  393. out_bits_6(0x3F);
  394. out_bits_8(cbMatch - 128);
  395. }
  396. else if (cbMatch < 512) {
  397. out_bits_7(0x7F);
  398. out_bits_9(cbMatch - 256);
  399. }
  400. else if (cbMatch < 1024) {
  401. out_bits_8(0xFF);
  402. out_bits_10(cbMatch - 512);
  403. }
  404. else if (cbMatch < 2048) {
  405. out_bits_9(0x1FF);
  406. out_bits_11(cbMatch - 1024);
  407. }
  408. else if (cbMatch < 4096) {
  409. out_bits_10(0x3FF);
  410. out_bits_12(cbMatch - 2048);
  411. }
  412. else if (cbMatch < 8192) {
  413. out_bits_11(0x7FF) ;
  414. out_bits_13(cbMatch - 4096);
  415. }
  416. else if (cbMatch < 16384) {
  417. out_bits_12(0xFFF);
  418. out_bits_14(cbMatch - 8192);
  419. }
  420. else if (cbMatch < 32768) {
  421. out_bits_13(0x1FFF);
  422. out_bits_14(cbMatch - 16384);
  423. }
  424. else { // 32768..65535
  425. out_bits_14(0x3FFF);
  426. out_bits_N(15, cbMatch - 32768);
  427. }
  428. }
  429. else {
  430. // We might overshoot the buffer. Fail the encoding.
  431. goto Expansion;
  432. }
  433. }
  434. else { // encode a literal
  435. // Max literal output is 2 bytes, make sure we don't overrun the
  436. // output.
  437. if ((pbyte + 2) <= pEndOutBuf) {
  438. literal = hashchar1;
  439. if (literal & 0x80) {
  440. literal += 0x80;
  441. out_bits_9(literal);
  442. } else {
  443. out_bits_8(literal);
  444. }
  445. }
  446. else {
  447. // Potential overrun, failure.
  448. goto Expansion;
  449. }
  450. }
  451. } // while
  452. // Output any remaining chars as literals.
  453. while (currentptr <= endptr) {
  454. // Max literal output is 2 bytes, make sure we don't overrun the
  455. // output.
  456. if ((pbyte + 2) <= pEndOutBuf) {
  457. literal=*currentptr;
  458. if (literal & 0x80) {
  459. literal += 0x80;
  460. out_bits_9(literal);
  461. } else {
  462. out_bits_8(literal);
  463. }
  464. *historyptr++ = *currentptr++ ;
  465. }
  466. else {
  467. // Potential overrun, failure.
  468. goto Expansion;
  469. }
  470. }
  471. // Done. Finish out the last byte and output the compressed length and
  472. // flags.
  473. bitptr_end();
  474. *CurrentLength = (ULONG)(pbyte - CompOutBuffer);
  475. status |= PACKET_COMPRESSED | (UCHAR)ComprType;
  476. context->CurrentIndex = (int)(historyptr - context->History);
  477. return status;
  478. Expansion:
  479. memset(context->History, 0, sizeof(context->History)) ;
  480. memset(context->HashTable, 0, sizeof(context->HashTable)) ;
  481. context->CurrentIndex = HistorySize + 1 ; // this forces a start over next time
  482. return PACKET_FLUSHED;
  483. }
  484. // initsendcontext()
  485. //
  486. // Function: Initialize SendContext block
  487. //
  488. // Parameters: IN context -> connection compress context
  489. //
  490. // Returns: Nothing
  491. void initsendcontext(SendContext *context, unsigned ComprType)
  492. {
  493. context->CurrentIndex = 0; // Index into the history
  494. context->ValidHistory = 0 ; // reset valid history
  495. context->ClientComprType = ComprType;
  496. if (ComprType >= PACKET_COMPR_TYPE_64K) {
  497. context->ClientComprType = PACKET_COMPR_TYPE_64K;
  498. context->HistorySize = HISTORY_SIZE_64K;
  499. }
  500. else {
  501. context->ClientComprType = PACKET_COMPR_TYPE_8K;
  502. context->HistorySize = HISTORY_SIZE_8K;
  503. }
  504. memset(context->HashTable, 0, sizeof(context->HashTable));
  505. memset(context->History, 0, sizeof(context->History));
  506. }