Source code of Windows XP (NT5)
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.

655 lines
21 KiB

  1. /* ------------------------------------------------------------------------ */
  2. /* */
  3. /* Copyright (c) Microsoft Corporation, 2000-2001. All rights reserved. */
  4. /* Copyright (c) Andrew Kadatch, 1991-2001. All rights reserved. */
  5. /* */
  6. /* Microsoft Confidential -- do not redistribute. */
  7. /* */
  8. /* ------------------------------------------------------------------------ */
  9. #if CHAIN >= 2
  10. INLINE void find_match (prs *p)
  11. {
  12. const uchar *p1;
  13. xint k, n, m;
  14. #if CHAIN >= 3
  15. xint chain = v.chain;
  16. #endif
  17. p->x.z_next[0] = (z_index_t) (k = n = v.orig.pos);
  18. do
  19. {
  20. m = p->x.z_next[k];
  21. #ifdef i386
  22. {
  23. uint16 c = *(__unaligned uint16 *)((p1 = v.orig.ptr + v.match.len - 1) + n);
  24. #if CHAIN >= 3
  25. do
  26. {
  27. if (--chain < 0)
  28. return;
  29. #endif /* CHAIN >= 3 */
  30. k = p->x.z_next[m]; if (*(__unaligned uint16 *) (p1 + m) == c) goto same_m;
  31. m = p->x.z_next[k]; if (*(__unaligned uint16 *) (p1 + k) == c) goto same_k;
  32. k = p->x.z_next[m]; if (*(__unaligned uint16 *) (p1 + m) == c) goto same_m;
  33. m = p->x.z_next[k]; if (*(__unaligned uint16 *) (p1 + k) == c) goto same_k;
  34. k = p->x.z_next[m]; if (*(__unaligned uint16 *) (p1 + m) == c) goto same_m;
  35. m = p->x.z_next[k]; if (*(__unaligned uint16 *) (p1 + k) == c) goto same_k;
  36. k = p->x.z_next[m]; if (*(__unaligned uint16 *) (p1 + m) == c) goto same_m;
  37. m = p->x.z_next[k]; if (*(__unaligned uint16 *) (p1 + k) == c) goto same_k;
  38. #if CHAIN < 3
  39. if (*(__unaligned uint16 *) (p1 + m) == c) goto same_m;
  40. return;
  41. #else
  42. }
  43. while (1);
  44. #endif /* CHAIN < 3 */
  45. #else /* !i386 */
  46. {
  47. const uchar *p0 = v.orig.ptr + v.match.len;
  48. const uchar c0 = p0[n];
  49. const uchar c1 = (p1 = p0 - 1)[n];
  50. #if CHAIN >= 3
  51. do
  52. {
  53. if (--chain < 0)
  54. return;
  55. #endif /* CHAIN >= 3 */
  56. k = p->x.z_next[m]; if (p0[m] == c0 && p1[m] == c1) goto same_m;
  57. m = p->x.z_next[k]; if (p0[k] == c0 && p1[k] == c1) goto same_k;
  58. k = p->x.z_next[m]; if (p0[m] == c0 && p1[m] == c1) goto same_m;
  59. m = p->x.z_next[k]; if (p0[k] == c0 && p1[k] == c1) goto same_k;
  60. k = p->x.z_next[m]; if (p0[m] == c0 && p1[m] == c1) goto same_m;
  61. m = p->x.z_next[k]; if (p0[k] == c0 && p1[k] == c1) goto same_k;
  62. k = p->x.z_next[m]; if (p0[m] == c0 && p1[m] == c1) goto same_m;
  63. m = p->x.z_next[k]; if (p0[k] == c0 && p1[k] == c1) goto same_k;
  64. #if CHAIN < 3
  65. if (p0[m] == c0 && p1[m] == c1) goto same_m;
  66. return;
  67. #else
  68. }
  69. while (1);
  70. #endif /* CHAIN < 3 */
  71. #endif /* i386 */
  72. same_m:
  73. k = m;
  74. same_k:
  75. if (k == n)
  76. return;
  77. #if MAX_OFFSET < BUFF_SIZE_LOG
  78. if (n - k >= (1 << MAX_OFFSET))
  79. return;
  80. #endif
  81. }
  82. {
  83. const uchar *p2;
  84. p1 = v.orig.ptr;
  85. p2 = p1 + k;
  86. p1 += n;
  87. #ifdef i386
  88. if ((m = *(__unaligned uint32 *)p2 ^ *(__unaligned uint32 *)p1) != 0)
  89. {
  90. #if MIN_MATCH <= 3
  91. if ((m & 0xffffff) == 0 && v.match.len <= 2 && p1 + 3 <= v.orig.end)
  92. {
  93. v.match.len = 3;
  94. v.match.pos = k;
  95. }
  96. #endif /* MIN_MATCH <= 3 */
  97. goto cont;
  98. }
  99. #else /* !i386 */
  100. if (p1[0] != p2[0] || p1[1] != p2[1] || p1[2] != p2[2])
  101. goto cont;
  102. if (p1[3] != p2[3])
  103. {
  104. #if MIN_MATCH <= 3
  105. if (v.match.len <= 2 && p1 + 3 <= v.orig.end)
  106. {
  107. v.match.len = 3;
  108. v.match.pos = k;
  109. }
  110. #endif /* MIN_MATCH <= 3 */
  111. goto cont;
  112. }
  113. #endif /* i386 */
  114. if (p1 <= v.orig.end_16)
  115. {
  116. goto entry4;
  117. do
  118. {
  119. #define X(i) if (p1[i] != p2[i]) {p1 += i; goto chk;}
  120. X(0); X(1); X(2); X(3);
  121. entry4:
  122. X(4); X(5); X(6); X(7); X(8);
  123. X(9); X(10); X(11); X(12); X(13); X(14); X(15);
  124. #undef X
  125. p1 += 16; p2 += 16;
  126. }
  127. while (p1 <= v.orig.end_16);
  128. }
  129. while (p1 != v.orig.end)
  130. {
  131. if (*p1 != *p2)
  132. goto chk;
  133. ++p1;
  134. ++p2;
  135. }
  136. #define SET_LENGTH() \
  137. n = -n; \
  138. n += (xint) (p1 - v.orig.ptr); \
  139. if (n > v.match.len) \
  140. { \
  141. v.match.len = n; \
  142. v.match.pos = k; \
  143. }
  144. SET_LENGTH ();
  145. return;
  146. }
  147. chk:
  148. SET_LENGTH ();
  149. cont:
  150. n = v.orig.pos;
  151. }
  152. while (CHAIN >= 3);
  153. }
  154. static void encode_pass1 (prs *p)
  155. {
  156. uchar *ptr = v.temp.ptr;
  157. do
  158. {
  159. if (p->x.z_next[v.orig.pos] == 0)
  160. goto literal;
  161. v.match.len = MIN_MATCH-1;
  162. find_match (p);
  163. if (v.match.len <= MIN_MATCH-1)
  164. {
  165. literal:
  166. write_lit (p, ptr, v.orig.ptr[v.orig.pos]);
  167. v.orig.pos += 1;
  168. }
  169. else
  170. {
  171. ptr = write_ptr (p, ptr, v.orig.pos - v.match.pos, v.match.len);
  172. v.orig.pos += v.match.len;
  173. }
  174. }
  175. while (v.orig.pos < v.orig.stop);
  176. v.temp.ptr = ptr;
  177. }
  178. #endif /* CHAIN >= 2 */
  179. #if CHAIN < 2
  180. #if CODING != CODING_DIRECT2 || !defined (i386)
  181. static void encode_pass1 (prs *p)
  182. {
  183. const uchar *b, *b1, *stop;
  184. uchar *ptr;
  185. #if CHAIN > 0
  186. xint pos = v.orig.pos;
  187. #endif
  188. b = v.orig.ptr;
  189. v.orig.ptr_stop = stop = b + v.orig.stop;
  190. b += v.orig.pos;
  191. ptr = v.temp.ptr;
  192. if (b != v.orig.ptr)
  193. goto literal_entry;
  194. for (;;)
  195. {
  196. do
  197. {
  198. #if MAX_OFFSET < BUFF_SIZE_LOG
  199. next:
  200. #endif
  201. write_lit (p, ptr, *b);
  202. ++b;
  203. #if CHAIN > 0
  204. ++pos;
  205. #endif
  206. literal_entry:
  207. if (b >= stop)
  208. goto ret;
  209. {
  210. uxint h;
  211. #if CHAIN <= 0
  212. h = Q_HASH_SUM (b);
  213. b1 = p->x.q_last[h];
  214. p->x.q_last[h] = b;
  215. #else
  216. assert (pos == (xint) (b - v.orig.ptr));
  217. h = Z_HASH_SUM (b);
  218. b1 = v.orig.ptr + p->x.z_next[h];
  219. p->x.z_next[h] = (z_index_t) pos;
  220. #endif
  221. }
  222. #if MAX_OFFSET < BUFF_SIZE_LOG
  223. if (b1 <= b - (1 << MAX_OFFSET))
  224. goto next;
  225. #endif
  226. }
  227. while (b1 == 0 || b1[0] != b[0] || b1[1] != b[1] || b1[2] != b[2]);
  228. assert ((xint) (v.orig.ptr + v.orig.size - b) > 7);
  229. {
  230. const uchar *b0 = b;
  231. if (b <= v.orig.end_16)
  232. goto match_entry_3;
  233. goto match_careful;
  234. do
  235. {
  236. #define X(i) if (b1[i] != b[i]) {b += i; b1 += i; goto eval_len;}
  237. X(0); X(1); X(2);
  238. match_entry_3:
  239. X(3); X(4); X(5); X(6); X(7);
  240. X(8); X(9); X(10); X(11);
  241. X(12); X(13); X(14); X(15);
  242. #undef X
  243. b += 16; b1 += 16;
  244. }
  245. while (b <= v.orig.end_16);
  246. match_careful:
  247. while (b != v.orig.end && *b1 == *b)
  248. {
  249. ++b;
  250. ++b1;
  251. }
  252. eval_len:
  253. #if BUFF_SIZE_LOG > 16
  254. #error
  255. #endif
  256. ptr = write_ptr (p, ptr, (xint) (b - b1), (xint) (b - b0));
  257. b1 = b0;
  258. }
  259. ++b1;
  260. #if CHAIN > 0
  261. ++pos;
  262. #endif
  263. if (b > v.orig.end_3)
  264. {
  265. while (b1 < v.orig.end_3)
  266. {
  267. #if CHAIN <= 0
  268. p->x.q_last[Q_HASH_SUM (b1)] = b1;
  269. #else
  270. assert (pos == (xint) (b1 - v.orig.ptr));
  271. p->x.z_next[Z_HASH_SUM (b1)] = (z_index_t) pos;
  272. ++pos;
  273. #endif
  274. ++b1;
  275. }
  276. goto literal_entry;
  277. }
  278. do
  279. {
  280. #if CHAIN <= 0
  281. p->x.q_last[Q_HASH_SUM (b1)] = b1;
  282. #else
  283. assert (pos == (xint) (b1 - v.orig.ptr));
  284. p->x.z_next[Z_HASH_SUM (b1)] = (z_index_t) pos;
  285. ++pos;
  286. #endif
  287. ++b1;
  288. }
  289. while (b1 != b);
  290. goto literal_entry;
  291. }
  292. ret:
  293. v.orig.pos = (xint) (b - v.orig.ptr);
  294. v.temp.ptr = ptr;
  295. }
  296. #else /* CODING != CODING_DIRECT2 */
  297. static void encode_pass1 (prs *PrsPtr)
  298. {
  299. #define PRS edx
  300. #define TAG ebp
  301. #define TAGW bp
  302. // access to prs structure fields
  303. #define V [PRS - SIZE prs] prs.c
  304. // TAG = tag_mask; adjusts TAG (tag_mask), V.temp.tag_ptr, and ebx (output pointer)
  305. #define WRITE_TAG_MASK() \
  306. __asm mov ecx, V.temp.tag_ptr \
  307. __asm mov V.temp.tag_ptr, ebx \
  308. __asm add ebx, 4 \
  309. __asm mov [ecx], TAG \
  310. __asm mov TAG, 1
  311. #if CHAIN <= 0
  312. // access to respective hash table entry
  313. #define Q_HTABLE(idx) dword ptr [PRS + idx*4] prs.x.q_last
  314. // evaluate hash sum of [esi] on eax; spoils eax, ecx, TAG
  315. #define Q_HASH_SUM_ASM() \
  316. __asm movzx eax, byte ptr [esi] \
  317. __asm movzx ecx, byte ptr [esi+1] \
  318. __asm movzx edi, byte ptr [esi+2] \
  319. __asm lea ecx, [ecx + eax * (1 << (Q_HASH_SH1 - Q_HASH_SH2))] \
  320. __asm lea eax, [edi + ecx * (1 << Q_HASH_SH2)]
  321. #else
  322. // access to respective hash table entry
  323. #define Z_HTABLE(idx) word ptr [PRS + idx*2] prs.x.z_next
  324. // evaluate hash sum of [esi] on eax; spoils eax, ecx, edi
  325. #define Z_HASH_SUM_ASM() \
  326. __asm movzx eax, byte ptr [esi] \
  327. __asm movzx ecx, byte ptr [esi+1] \
  328. __asm movzx edi, byte ptr [esi+2] \
  329. __asm movzx eax, word ptr z_hash_map[eax*2] \
  330. __asm movzx ecx, word ptr z_hash_map[ecx*2][512] \
  331. __asm movzx edi, word ptr z_hash_map[edi*2][1024] \
  332. __asm xor eax, ecx \
  333. __asm xor eax, edi
  334. #endif /* CHAIN <= 0 */
  335. __asm
  336. {
  337. push ebp // save ebp
  338. mov PRS, PrsPtr // PRS = PrsPtr (globally)
  339. // esi = b
  340. // edi = b1
  341. // ebx = V.prs.temp.ptr
  342. // TAG = V.temp.tag_mask
  343. mov esi, V.orig.ptr // obtain b, b1, temp.ptr, and temp.mask
  344. mov eax, V.orig.stop
  345. add eax, esi
  346. mov V.orig.ptr_stop, eax // and set orig.ptr_stop by orig.stop
  347. add esi, V.orig.pos
  348. mov ebx, V.temp.ptr
  349. mov TAG, V.temp.tag_mask
  350. cmp esi, V.orig.ptr // if beginning of buffer
  351. jne write_literal_entry // then write literal immediately
  352. write_literal:
  353. mov al, [esi] // read the literal
  354. inc ebx // shift dst ptr in advance
  355. inc esi // shift src ptr to next character
  356. mov [ebx-1], al // emit literal
  357. add TAG, TAG // write tag bit 0
  358. jc write_literal_tag_new // save tag word if it is full
  359. write_literal_tag_done:
  360. write_literal_entry:
  361. cmp esi, V.orig.ptr_stop // processed everything?
  362. jae pass1_stop // yes, stop
  363. #if CHAIN <= 0
  364. Q_HASH_SUM_ASM () // evaluate hash sum
  365. #if MAX_OFFSET < BUFF_SIZE_LOG
  366. lea ecx, [esi - (1 << MAX_OFFSET) + 1] // min. allowed left bound
  367. #endif
  368. mov edi, Q_HTABLE (eax) // edi = candidate ptr
  369. mov Q_HTABLE (eax), esi // save current ptr
  370. #else
  371. Z_HASH_SUM_ASM () // evaluate hash sum
  372. mov ecx,V.orig.ptr
  373. movzx di, Z_HTABLE (eax) // edi = offset to candidate ptr
  374. sub esi, ecx // esi = offset to current ptr
  375. add edi, ecx // edi = candidate ptr
  376. mov Z_HTABLE (eax), si // store current ptr offset
  377. add esi, ecx // restore current ptr
  378. #if MAX_OFFSET < BUFF_SIZE_LOG
  379. lea ecx, [esi - (1 << MAX_OFFSET) + 1] // min. allowed left bound
  380. #endif
  381. #endif /* CHAIN <= 0 */
  382. #if MAX_OFFSET < BUFF_SIZE_LOG
  383. cmp edi, ecx // canidate is in window?
  384. js write_literal // no, then emit literal
  385. #endif
  386. test edi, edi // is it NULL?
  387. jz write_literal // emit literal if so
  388. mov eax, [esi] // get first 4 src bytes
  389. sub eax, [edi] // diff them with first 4 candidate bytes
  390. je length_4 // if no diff then match is at least 4 bytes
  391. test eax, 0xffffff // is there any difference in first 3 bytes?
  392. jne write_literal // if yes emit literal
  393. mov ecx, 3 // save match ptr of length ECX
  394. sub edi, esi // edi = -offset
  395. write_small_ptr:
  396. lea eax, [esi+ecx] // eax = end of src match
  397. not edi // edi = offset-1
  398. add ebx, 2 // adjust output ptr in advance
  399. shl edi, DIRECT2_LEN_LOG // make room for length
  400. inc esi // esi = next substring (current already inserted)
  401. lea edi, [edi + ecx - MIN_MATCH] // combine offset and shoft length
  402. stc // set carry bit
  403. mov [ebx-2], di // save packed pointer
  404. adc TAG, TAG // write tag bit 1
  405. jc write_pointer_tag_new // write tag word when it is full
  406. write_pointer_tag_done:
  407. cmp eax, V.orig.end_3 // is it too close to end of buffer?
  408. ja insert_tail // if yes process is specially avoiding read overrun
  409. #if CHAIN <= 0
  410. push TAG // save tag_mask
  411. mov TAG, eax // eax = end-of-match
  412. insert_all:
  413. Q_HASH_SUM_ASM () // evaluate hash sum
  414. mov Q_HTABLE (eax), esi // save current ptr
  415. inc esi // shift to next position
  416. cmp esi, TAG // inserted all substrings in the match?
  417. jne insert_all // continue until finished
  418. pop TAG // restore tag_mask value
  419. jmp write_literal_entry // process next substring
  420. #else
  421. push TAG // save tag_mask
  422. push eax // save end-of-match
  423. mov TAG, esi // TAG = current ptr
  424. sub TAG, V.orig.ptr // TAG = current ptr offset
  425. insert_all:
  426. Z_HASH_SUM_ASM () // evaluate hash sum
  427. mov Z_HTABLE (eax), TAGW // save current offset
  428. inc esi // shift to next position
  429. inc TAG // increase offset
  430. cmp esi, [esp] // inserted all substrings in the match?
  431. jne insert_all // continue until finished
  432. pop eax // remove end-of-match ptr from the stack
  433. pop TAG // restore tag_mask
  434. jmp write_literal_entry // process next substring
  435. #endif /* CHAIN <= 0 */
  436. length_4:
  437. #define KNOWN_LENGTH 4 // we know that first 4 bytes match
  438. #if DIRECT2_MAX_LEN + MIN_MATCH >= 8
  439. mov eax, [esi+4] // fetch next 4 bytes
  440. sub eax, [edi+4] // get the diff between src and candidate
  441. jz length_8 // do long compare if 8+ bytes match
  442. bsf ecx, eax // ecx = # of first non-zero bit
  443. sub edi, esi // edi = -offset
  444. shr ecx, 3 // ecx = # of first non-zero byte
  445. not edi // edi = offset-1
  446. add ecx, 4 // plus previous 4 matching bytes = match length
  447. add ebx, 2 // adjust output ptr in advance
  448. lea eax, [esi+ecx] // eax = end of src match
  449. shl edi, DIRECT2_LEN_LOG // make room for length
  450. inc esi // esi = next substring (current already inserted)
  451. lea edi,[edi+ecx-MIN_MATCH] // combine offset and shoft length
  452. stc // set carry bit
  453. mov [ebx-2], di // save packed pointer
  454. adc TAG, TAG // write tag bit 1
  455. jnc write_pointer_tag_done // write tag word when it is full
  456. WRITE_TAG_MASK ()
  457. jmp write_pointer_tag_done
  458. length_8:
  459. #undef KNOWN_LENGTH
  460. #define KNOWN_LENGTH 8 // we know that first 8 bytes match
  461. #endif /* DIRECT2_MAX_LEN + MIN_MATCH >= 8 */
  462. mov eax, esi // eax = beginning of the string
  463. mov ecx, V.orig.end // ecx = end of buffer
  464. add esi, KNOWN_LENGTH // shift to first untested src byte
  465. add edi, KNOWN_LENGTH // shift to first untested candidate
  466. sub ecx, esi // ecx = max compare length
  467. rep cmpsb // compare src and candidate
  468. je match_complete // if eq then match till end of buffer
  469. match_complete_done:
  470. lea ecx, [esi-1] // ecx = end of match
  471. sub edi, esi // edi = -offset
  472. sub ecx, eax // ecx = match length
  473. mov esi, eax // esi = src ptr
  474. cmp ecx, DIRECT2_MAX_LEN+MIN_MATCH // small length?
  475. jb write_small_ptr // write ptr if so
  476. not edi // edi = offset-1
  477. lea eax, [esi+ecx] // eax = end of match
  478. shl edi, DIRECT2_LEN_LOG // make room for length
  479. sub ecx, DIRECT2_MAX_LEN+MIN_MATCH // decrease the length
  480. add edi, DIRECT2_MAX_LEN // mark length as long
  481. push eax // save end of match
  482. mov [ebx], di // write packed pointer
  483. mov al, cl // al = (ecx <= 15 ? cl : 15)
  484. cmp ecx, 15
  485. jbe match_less_15
  486. mov al, 15
  487. match_less_15:
  488. mov edi, V.stat.ptr // edi = quad_ptr
  489. add ebx, 2 // wrote 2 bytes, move output ptr
  490. test edi, edi // if quad_ptr != NULL write upper 4 bits
  491. jne match_have_ptr
  492. mov V.stat.ptr, ebx // make new tag_ptr
  493. mov [ebx], al // write lower 4 bits
  494. inc ebx // wrote 1 byte, move output ptr
  495. jmp match_done_ptr // continue execution
  496. match_have_ptr:
  497. shl al, 4 // will write into upper 4 bits
  498. mov dword ptr V.stat.ptr, 0 // no more space in this quad_bit[0]
  499. or [edi], al // write upper 4 bits
  500. match_done_ptr:
  501. sub ecx, 15 // adjusted length < 15?
  502. jae match_long_long_length // if not continue encoding
  503. match_finish_2:
  504. inc esi // shift to next output position
  505. pop eax // restore eax = end-of-match
  506. stc // set carry flag
  507. adc TAG, TAG // write tag bit 1
  508. jnc write_pointer_tag_done // continue execution if do not need to flush
  509. write_pointer_tag_new: // write tag word and return to pointers
  510. WRITE_TAG_MASK ()
  511. jmp write_pointer_tag_done
  512. match_long_long_length:
  513. mov [ebx], cl // write the length as a byte
  514. inc ebx // move output ptr
  515. cmp ecx, 255 // adjusted length fits in byte?
  516. jb match_finish_2 // if so ptr is written
  517. add ecx, DIRECT2_MAX_LEN+15 // restore full length - MIN_MATCH
  518. mov byte ptr [ebx-1], 255 // mark byte length as "to be continued"
  519. mov [ebx], cx // write full length
  520. add ebx, 2 // move output ptr
  521. jmp match_finish_2
  522. write_literal_tag_new: // write tag word and return to literals
  523. WRITE_TAG_MASK ()
  524. jmp write_literal_tag_done
  525. match_complete: // cmpsb compared till end of buffer
  526. inc esi // increase esi
  527. inc edi // increase edi
  528. jmp match_complete_done // resume execution
  529. insert_tail:
  530. push eax // save end-of-match
  531. jmp insert_tail_1
  532. insert_tail_next:
  533. #if CHAIN <= 0
  534. Q_HASH_SUM_ASM () // evaluate hash sum
  535. mov Q_HTABLE (eax), esi // insert current src pointer
  536. #else
  537. Z_HASH_SUM_ASM () // evaluate hash sum
  538. mov ecx, esi
  539. sub ecx, V.orig.ptr // ecx = current ptr offset
  540. mov Z_HTABLE (eax), cx // save offset in hash table
  541. #endif /* CHAIN <= 0 */
  542. inc esi // and move it to next substring
  543. insert_tail_1: // end of match exceeds end_3 -- be careful
  544. cmp esi, V.orig.end_3 // inserted up to end_3?
  545. jb insert_tail_next // if not continue
  546. pop esi // esi = end of match
  547. jmp write_literal_entry
  548. pass1_stop:
  549. mov V.temp.ptr, ebx // save register variables
  550. mov V.temp.tag_mask, TAG
  551. sub esi, V.orig.ptr
  552. mov V.orig.pos, esi
  553. pop ebp // restore ebp
  554. } /* __asm */
  555. }
  556. #undef V
  557. #undef PRS
  558. #undef TAG
  559. #undef TAGW
  560. #undef Q_HTABLE
  561. #undef Q_HASH_SUM_ASM
  562. #undef Z_HTABLE
  563. #undef Z_HASH_SUM_ASM
  564. #undef KNOWN_LENGTH
  565. #endif /* CODING != CODING_DIRECT2 */
  566. #endif /* CHAIN < 2 */
  567. #undef CHAIN
  568. #undef find_match
  569. #undef encode_pass1