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.

889 lines
25 KiB

  1. /*
  2. * optenc.c
  3. *
  4. * Optimal encoder
  5. *
  6. * BUGBUG Can improve compression by using the "redo" method of LZX; after the first 32K bytes,
  7. * reset the compressor but keep the tables, and start over.
  8. */
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <crtdbg.h>
  12. #include "deflate.h"
  13. //
  14. // If we get a match this good, take it automatically
  15. //
  16. // Note: FAST_DECISION_THRESHOLD can be set to anything; it's been set to BREAK_LENGTH
  17. // arbitrarily
  18. //
  19. #define FAST_DECISION_THRESHOLD BREAK_LENGTH
  20. //
  21. // After we have this many literals, create a tree to get updated statistical estimates
  22. //
  23. #define FIRST_TREE_UPDATE 1024
  24. //
  25. // Verifies that all of the hash pointers in the hash table are correct, and that
  26. // the tree structure is valid.
  27. //
  28. #define DISABLE_VERIFY_HASHES
  29. #ifdef _DEBUG
  30. #ifndef DISABLE_VERIFY_HASHES
  31. #define VERIFY_HASHES(bufpos) verifyHashes(context, bufpos)
  32. #else
  33. #define VERIFY_HASHES(bufpos) ;
  34. #endif
  35. #else
  36. #define VERIFY_HASHES(bufpos) ;
  37. #endif
  38. #define CHECK_FLUSH_RECORDING_BUFFER() \
  39. if (recording_bitcount >= 16) \
  40. { \
  41. *recording_bufptr++ = (BYTE) recording_bitbuf; \
  42. *recording_bufptr++ = (BYTE) (recording_bitbuf >> 8); \
  43. recording_bitbuf >>= 16; \
  44. recording_bitcount -= 16; \
  45. }
  46. #define OUTPUT_RECORDING_DATA(count,data) \
  47. recording_bitbuf |= ((data) << recording_bitcount); \
  48. recording_bitcount += (count);
  49. //
  50. // Record unmatched symbol c
  51. //
  52. #define RECORD_CHAR(c) \
  53. context->outputting_block_num_literals++; \
  54. encoder->literal_tree_freq[c]++; \
  55. _ASSERT(encoder->recording_literal_tree_len[c] != 0); \
  56. OUTPUT_RECORDING_DATA(encoder->recording_literal_tree_len[c], encoder->recording_literal_tree_code[c]); \
  57. CHECK_FLUSH_RECORDING_BUFFER();
  58. //
  59. // Record a match with length match_len (>= MIN_MATCH) and displacement match_pos
  60. //
  61. #define RECORD_MATCH(match_len, match_pos) \
  62. { \
  63. int pos_slot = POS_SLOT(match_pos); \
  64. int len_slot = g_LengthLookup[match_len - MIN_MATCH]; \
  65. int item = (NUM_CHARS+1) + len_slot; \
  66. int extra_dist_bits = g_ExtraDistanceBits[pos_slot]; \
  67. int extra_len_bits = g_ExtraLengthBits[len_slot]; \
  68. _ASSERT(match_len >= MIN_MATCH && match_len <= MAX_MATCH); \
  69. _ASSERT(context->outputting_block_num_literals >= 0 && context->outputting_block_num_literals < OPT_ENCODER_MAX_ITEMS); \
  70. _ASSERT(encoder->recording_literal_tree_len[item] != 0); \
  71. _ASSERT(encoder->recording_dist_tree_len[pos_slot] != 0); \
  72. context->outputting_block_num_literals++; \
  73. encoder->literal_tree_freq[(NUM_CHARS + 1) + len_slot]++; \
  74. encoder->dist_tree_freq[pos_slot]++; \
  75. OUTPUT_RECORDING_DATA(encoder->recording_literal_tree_len[item], encoder->recording_literal_tree_code[item]); \
  76. CHECK_FLUSH_RECORDING_BUFFER(); \
  77. if (extra_len_bits > 0) \
  78. { \
  79. OUTPUT_RECORDING_DATA(extra_len_bits, (match_len-MIN_MATCH) & ((1 << extra_len_bits)-1)); \
  80. CHECK_FLUSH_RECORDING_BUFFER(); \
  81. } \
  82. OUTPUT_RECORDING_DATA(encoder->recording_dist_tree_len[pos_slot], encoder->recording_dist_tree_code[pos_slot]); \
  83. CHECK_FLUSH_RECORDING_BUFFER(); \
  84. if (extra_dist_bits > 0) \
  85. { \
  86. OUTPUT_RECORDING_DATA(extra_dist_bits, match_pos & ((1 << extra_dist_bits)-1)); \
  87. CHECK_FLUSH_RECORDING_BUFFER(); \
  88. } \
  89. }
  90. #define FLUSH_RECORDING_BITBUF() \
  91. *recording_bufptr++ = (BYTE) recording_bitbuf; \
  92. *recording_bufptr++ = (BYTE) (recording_bitbuf >> 8);
  93. static void calculateUpdatedEstimates(t_encoder_context *context);
  94. static void OptimalEncoderMoveWindows(t_encoder_context *context);
  95. static int match_est(t_optimal_encoder *encoder, int match_length, unsigned int match_pos)
  96. {
  97. int dist_slot;
  98. int len_slot;
  99. // output match position
  100. len_slot = g_LengthLookup[match_length-MIN_MATCH];
  101. dist_slot = POS_SLOT(match_pos);
  102. return encoder->literal_tree_len[NUM_CHARS + 1 + len_slot] +
  103. g_ExtraLengthBits[len_slot] +
  104. encoder->dist_tree_len[dist_slot] +
  105. g_ExtraDistanceBits[dist_slot];
  106. }
  107. //
  108. // Create initial estimations to output each element
  109. //
  110. static void initOptimalEstimates(t_encoder_context *context)
  111. {
  112. int i, p;
  113. t_optimal_encoder *encoder = context->optimal_encoder;
  114. for (i = 0; i < NUM_CHARS; i++)
  115. encoder->literal_tree_len[i] = 8;
  116. p = NUM_CHARS+1;
  117. encoder->literal_tree_len[p] = 3;
  118. encoder->literal_tree_len[p+1] = 4;
  119. encoder->literal_tree_len[p+2] = 5;
  120. for (; p < MAX_LITERAL_TREE_ELEMENTS; p++)
  121. encoder->literal_tree_len[p] = 6;
  122. for (i = 0; i < MAX_DIST_TREE_ELEMENTS; i++)
  123. encoder->dist_tree_len[i] = (i/2)+1;
  124. }
  125. //
  126. // Fix optimal estimates; if bitlen == 0 it doesn't mean that the element takes 0
  127. // bits to output, it means that the element didn't occur, so come up with some estimate.
  128. //
  129. static void fixOptimalEstimates(t_encoder_context *context)
  130. {
  131. int i;
  132. t_optimal_encoder *encoder = context->optimal_encoder;
  133. for (i = 0; i < NUM_CHARS; i++)
  134. {
  135. if (encoder->literal_tree_len[i] == 0)
  136. encoder->literal_tree_len[i] = 13;
  137. }
  138. for (i = NUM_CHARS+1; i < MAX_LITERAL_TREE_ELEMENTS; i++)
  139. {
  140. if (encoder->literal_tree_len[i] == 0)
  141. encoder->literal_tree_len[i] = 12;
  142. }
  143. for (i = 0; i < MAX_DIST_TREE_ELEMENTS; i++)
  144. {
  145. if (encoder->dist_tree_len[i] == 0)
  146. encoder->dist_tree_len[i] = 10;
  147. }
  148. }
  149. /*
  150. * Returns an estimation of how many bits it would take to output
  151. * a given character
  152. */
  153. #define CHAR_EST(c) (numbits_t) (encoder->literal_tree_len[(c)])
  154. /*
  155. * Returns an estimation of how many bits it would take to output
  156. * a given match.
  157. */
  158. #define MATCH_EST(ml,mp,result) result = match_est(encoder, ml,mp);
  159. //
  160. // Returns whether the literal buffers are just about full
  161. //
  162. // Since we could output a large number of matches/chars in between these checks, we
  163. // have to be careful.
  164. //
  165. // BUGBUG should check after each item output, so we don't have to be so careful; this
  166. // means we will utilise more of the recording buffer
  167. //
  168. #define LITERAL_BUFFERS_FULL() \
  169. (context->outputting_block_num_literals >= OPT_ENCODER_MAX_ITEMS-4-LOOK-MAX_MATCH || \
  170. recording_bufptr + 3*(MAX_MATCH + LOOK) >= end_recording_bufptr)
  171. void OptimalEncoderDeflate(t_encoder_context *context)
  172. {
  173. unsigned long bufpos_end;
  174. unsigned long MatchPos;
  175. unsigned long i;
  176. int EncMatchLength; /* must be a signed number */
  177. unsigned long bufpos;
  178. unsigned long recording_bitbuf;
  179. int recording_bitcount;
  180. byte * recording_bufptr;
  181. byte * end_recording_bufptr;
  182. t_optimal_encoder *encoder = context->optimal_encoder;
  183. _ASSERT(encoder != NULL);
  184. _ASSERT(context->state == STATE_NORMAL);
  185. // reinsert the up to BREAK_LENGTH nodes we removed the last time we exit this function
  186. VERIFY_HASHES(context->bufpos);
  187. reinsertRemovedNodes(context);
  188. VERIFY_HASHES(context->bufpos);
  189. // restore literal/match bitmap variables
  190. end_recording_bufptr = &encoder->lit_dist_buffer[OPT_ENCODER_LIT_DIST_BUFFER_SIZE-8];
  191. recording_bufptr = encoder->recording_bufptr;
  192. recording_bitbuf = encoder->recording_bitbuf;
  193. recording_bitcount = encoder->recording_bitcount;
  194. bufpos = context->bufpos;
  195. bufpos_end = context->bufpos_end;
  196. /*
  197. * While we haven't reached the end of the data
  198. */
  199. after_output_block:
  200. while (bufpos < bufpos_end)
  201. {
  202. // time to update our stats?
  203. if (context->outputting_block_num_literals >= encoder->next_tree_update)
  204. {
  205. encoder->next_tree_update += 1024;
  206. calculateUpdatedEstimates(context);
  207. fixOptimalEstimates(context);
  208. }
  209. // literal buffer or distance buffer filled up (or close to filling up)?
  210. if (LITERAL_BUFFERS_FULL())
  211. break;
  212. /*
  213. * Search for matches of all different possible lengths, at bufpos
  214. */
  215. EncMatchLength = optimal_find_match(context, bufpos);
  216. if (EncMatchLength < MIN_MATCH)
  217. {
  218. output_literal:
  219. /*
  220. * No match longer than 1 character exists in the history
  221. * window, so output the character at bufpos as a symbol.
  222. */
  223. RECORD_CHAR(encoder->window[bufpos]);
  224. bufpos++;
  225. continue;
  226. }
  227. /*
  228. * Found a match.
  229. *
  230. * Make sure it cannot exceed the end of the buffer.
  231. */
  232. if ((unsigned long) EncMatchLength + bufpos > bufpos_end)
  233. {
  234. EncMatchLength = bufpos_end - bufpos;
  235. /*
  236. * Oops, not enough for even a small match, so we
  237. * have to output a literal
  238. */
  239. if (EncMatchLength < MIN_MATCH)
  240. goto output_literal;
  241. }
  242. if (EncMatchLength < FAST_DECISION_THRESHOLD)
  243. {
  244. /*
  245. * A match has been found that is between MIN_MATCH and
  246. * FAST_DECISION_THRESHOLD bytes in length. The following
  247. * algorithm is the optimal encoder that will determine the
  248. * most efficient order of matches and unmatched characters
  249. * over a span area defined by LOOK.
  250. *
  251. * The code is essentially a shortest path determination
  252. * algorithm. A stream of data can be encoded in a vast number
  253. * of different ways depending on the match lengths and offsets
  254. * chosen. The key to good compression ratios is to chose the
  255. * least expensive path.
  256. */
  257. unsigned long span;
  258. unsigned long epos, bpos, NextPrevPos, MatchPos;
  259. t_decision_node *decision_node_ptr;
  260. t_decision_node *context_decision_node = encoder->decision_node;
  261. t_match_pos *matchpos_table = encoder->matchpos_table;
  262. long iterations;
  263. /*
  264. * Points to the end of the area covered by this match; the span
  265. * will continually be extended whenever we find more matches
  266. * later on. It will stop being extended when we reach a spot
  267. * where there are no matches, which is when we decide which
  268. * path to take to output the matches.
  269. */
  270. span = bufpos + EncMatchLength;
  271. /*
  272. * The furthest position into which we will do our lookahead parsing
  273. */
  274. epos = bufpos + LOOK;
  275. /*
  276. * Temporary bufpos variable
  277. */
  278. bpos = bufpos;
  279. /*
  280. * Calculate the path to the next character if we output
  281. * an unmatched symbol.
  282. */
  283. /* bits required to get here */
  284. context_decision_node[1].numbits = CHAR_EST(encoder->window[bufpos]);
  285. /* where we came from */
  286. context_decision_node[1].path = bufpos;
  287. /* bits required to get here */
  288. context_decision_node[2].numbits = CHAR_EST(encoder->window[bufpos+1]) + context_decision_node[1].numbits;
  289. /* where we came from */
  290. context_decision_node[2].path = bufpos+1;
  291. /*
  292. * For the match found, estimate the cost of encoding the match
  293. * for each possible match length, shortest offset combination.
  294. *
  295. * The cost, path and offset is stored at bufpos + Length.
  296. */
  297. for (i = MIN_MATCH; i <= (unsigned long) EncMatchLength; i++)
  298. {
  299. /*
  300. * Get estimation of match cost given match length = i,
  301. * match position = matchpos_table[i], and store
  302. * the result in numbits[i]
  303. */
  304. MATCH_EST(i, matchpos_table[i], context_decision_node[i].numbits);
  305. /*
  306. * Where we came from
  307. */
  308. context_decision_node[i].path = bufpos;
  309. /*
  310. * Associated match position with this path
  311. */
  312. context_decision_node[i].link = matchpos_table[i];
  313. }
  314. /*
  315. * Set bit counter to zero at the start
  316. */
  317. context_decision_node[0].numbits = 0;
  318. decision_node_ptr = &context_decision_node[-(long) bpos];
  319. while (1)
  320. {
  321. numbits_t est, cum_numbits;
  322. bufpos++;
  323. /*
  324. * Set the proper repeated offset locations depending on the
  325. * shortest path to the location prior to searching for a
  326. * match.
  327. */
  328. /*
  329. * The following is one of the two possible break points from
  330. * the inner encoding loop. This break will exit the loop if
  331. * a point is reached that no match can incorporate; i.e. a
  332. * character that does not match back to anything is a point
  333. * where all possible paths will converge and the longest one
  334. * can be chosen.
  335. */
  336. if (span == bufpos)
  337. break;
  338. /*
  339. * Search for matches at bufpos
  340. */
  341. EncMatchLength = optimal_find_match(context, bufpos);
  342. /*
  343. * Make sure that the match does not exceed the stop point
  344. */
  345. if ((unsigned long) EncMatchLength + bufpos > bufpos_end)
  346. {
  347. EncMatchLength = bufpos_end - bufpos;
  348. if (EncMatchLength < MIN_MATCH)
  349. EncMatchLength = 0;
  350. }
  351. /*
  352. * If the match is very long or it exceeds epos (either
  353. * surpassing the LOOK area, or exceeding past the end of the
  354. * input buffer), then break the loop and output the path.
  355. */
  356. if (EncMatchLength > FAST_DECISION_THRESHOLD ||
  357. bufpos + (unsigned long) EncMatchLength >= epos)
  358. {
  359. MatchPos = matchpos_table[EncMatchLength];
  360. decision_node_ptr[bufpos+EncMatchLength].link = MatchPos;
  361. decision_node_ptr[bufpos+EncMatchLength].path = bufpos;
  362. /*
  363. * Quickly insert data into the search tree without
  364. * returning match positions/lengths
  365. */
  366. #ifndef INSERT_NEAR_LONG_MATCHES
  367. if (MatchPos == 3 && EncMatchLength > 16)
  368. {
  369. /*
  370. * If we found a match 1 character away and it's
  371. * length 16 or more, it's probably a string of
  372. * zeroes, so don't insert that into the search
  373. * engine, since doing so can slow things down
  374. * significantly!
  375. */
  376. optimal_insert(
  377. context,
  378. bufpos + 1,
  379. bufpos - WINDOW_SIZE + 2
  380. );
  381. }
  382. else
  383. #endif
  384. {
  385. for (i = 1; i < (unsigned long) EncMatchLength; i++)
  386. optimal_insert(
  387. context,
  388. bufpos + i,
  389. bufpos + i - WINDOW_SIZE + 4
  390. );
  391. }
  392. bufpos += EncMatchLength;
  393. break;
  394. }
  395. /*
  396. * The following code will extend the area spanned by the
  397. * set of matches if the current match surpasses the end of
  398. * the span. A match of length two that is far is not
  399. * accepted, since it would normally be encoded as characters,
  400. * thus allowing the paths to converge.
  401. */
  402. if (EncMatchLength >= 3)
  403. {
  404. if (span < (unsigned long) (bufpos + EncMatchLength))
  405. {
  406. long end;
  407. long i;
  408. end = min(bufpos+EncMatchLength-bpos, LOOK-1);
  409. /*
  410. * These new positions are undefined for now, since we haven't
  411. * gone there yet, so put in the costliest value
  412. */
  413. for (i = span-bpos+1; i <= end; i++)
  414. context_decision_node[i].numbits = (numbits_t) -1;
  415. span = bufpos + EncMatchLength;
  416. }
  417. }
  418. /*
  419. * The following code will iterate through all combinations
  420. * of match lengths for the current match. It will estimate
  421. * the cost of the path from the beginning of LOOK to
  422. * bufpos and to every locations spanned by the current
  423. * match. If the path through bufpos with the found matches
  424. * is estimated to take fewer number of bits to encode than
  425. * the previously found match, then the path to the location
  426. * is altered.
  427. *
  428. * The code relies on accurate estimation of the cost of
  429. * encoding a character or a match. Furthermore, it requires
  430. * a search engine that will store the smallest match offset
  431. * of each possible match length.
  432. *
  433. * A match of length one is simply treated as an unmatched
  434. * character.
  435. */
  436. /*
  437. * Get the estimated number of bits required to encode the
  438. * path leading up to bufpos.
  439. */
  440. cum_numbits = decision_node_ptr[bufpos].numbits;
  441. /*
  442. * Calculate the estimated cost of outputting the path through
  443. * bufpos and outputting the next character as an unmatched byte
  444. */
  445. est = cum_numbits + CHAR_EST(encoder->window[bufpos]);
  446. /*
  447. * Check if it is more efficient to encode the next character
  448. * as an unmatched character rather than the previously found
  449. * match. If so, then update the cheapest path to bufpos + 1.
  450. *
  451. * What happens if est == numbits[bufpos-bpos+1]; i.e. it
  452. * works out as well to output a character as to output a
  453. * match? It's a tough call; however, we will push the
  454. * encoder to use matches where possible.
  455. */
  456. if (est < decision_node_ptr[bufpos+1].numbits)
  457. {
  458. decision_node_ptr[bufpos+1].numbits = est;
  459. decision_node_ptr[bufpos+1].path = bufpos;
  460. }
  461. /*
  462. * Now, iterate through the remaining match lengths and
  463. * compare the new path to the existing. Change the path
  464. * if it is found to be more cost effective to go through
  465. * bufpos.
  466. */
  467. for (i = MIN_MATCH; i <= (unsigned long) EncMatchLength; i++)
  468. {
  469. MATCH_EST(i, matchpos_table[i], est);
  470. est += cum_numbits;
  471. /*
  472. * If est == numbits[bufpos+i] we want to leave things
  473. * alone, since this will tend to force the matches
  474. * to be smaller in size, which is beneficial for most
  475. * data.
  476. */
  477. if (est < decision_node_ptr[bufpos+i].numbits)
  478. {
  479. decision_node_ptr[bufpos+i].numbits = est;
  480. decision_node_ptr[bufpos+i].path = bufpos;
  481. decision_node_ptr[bufpos+i].link = matchpos_table[i];
  482. }
  483. }
  484. } /* continue to loop through span of matches */
  485. /*
  486. * Here bufpos == span, ie. a non-matchable character found. The
  487. * following code will output the path properly.
  488. */
  489. /*
  490. * Unfortunately the path is stored in reverse; how to get from
  491. * where we are now, to get back to where it all started.
  492. *
  493. * Traverse the path back to the original starting position
  494. * of the LOOK span. Invert the path pointers in order to be
  495. * able to traverse back to the current position from the start.
  496. */
  497. /*
  498. * Count the number of iterations we did, so when we go forwards
  499. * we'll do the same amount
  500. */
  501. iterations = 0;
  502. NextPrevPos = decision_node_ptr[bufpos].path;
  503. do
  504. {
  505. unsigned long PrevPos;
  506. PrevPos = NextPrevPos;
  507. NextPrevPos = decision_node_ptr[PrevPos].path;
  508. decision_node_ptr[PrevPos].path = bufpos;
  509. bufpos = PrevPos;
  510. iterations++;
  511. } while (bufpos != bpos);
  512. /*
  513. * Traverse from the beginning of the LOOK span to the end of
  514. * the span along the stored path, outputting matches and
  515. * characters appropriately.
  516. */
  517. do
  518. {
  519. if (decision_node_ptr[bufpos].path > bufpos+1)
  520. {
  521. /*
  522. * Path skips over more than 1 character; therefore it's a match
  523. */
  524. RECORD_MATCH(
  525. decision_node_ptr[bufpos].path - bufpos,
  526. decision_node_ptr[ decision_node_ptr[bufpos].path ].link
  527. );
  528. bufpos = decision_node_ptr[bufpos].path;
  529. }
  530. else
  531. {
  532. /*
  533. * Path goes to the next character; therefore it's a symbol
  534. */
  535. RECORD_CHAR(encoder->window[bufpos]);
  536. bufpos++;
  537. }
  538. } while (--iterations != 0);
  539. }
  540. else /* EncMatchLength >= FAST_DECISION_THRESHOLD */
  541. {
  542. /*
  543. * This code reflects a speed optimization that will always take
  544. * a match of length >= FAST_DECISION_THRESHOLD characters.
  545. */
  546. /*
  547. * The position associated with the match we found
  548. */
  549. MatchPos = encoder->matchpos_table[EncMatchLength];
  550. /*
  551. * Quickly insert match substrings into search tree
  552. * (don't look for new matches; just insert the strings)
  553. */
  554. #ifndef INSERT_NEAR_LONG_MATCHES
  555. if (MatchPos == 3 && EncMatchLength > 16)
  556. {
  557. optimal_insert(
  558. context,
  559. bufpos + 1,
  560. bufpos - WINDOW_SIZE + 2
  561. );
  562. }
  563. else
  564. #endif
  565. {
  566. for (i = 1; i < (unsigned long) EncMatchLength; i++)
  567. optimal_insert(
  568. context,
  569. bufpos + i,
  570. bufpos + i - WINDOW_SIZE + 1
  571. );
  572. }
  573. /*
  574. * Advance our position in the window
  575. */
  576. bufpos += EncMatchLength;
  577. /*
  578. * Output the match
  579. */
  580. RECORD_MATCH(EncMatchLength, MatchPos);
  581. } /* EncMatchLength >= FAST_DECISION_THRESHOLD */
  582. } /* end while ... bufpos <= bufpos_end */
  583. if (LITERAL_BUFFERS_FULL())
  584. {
  585. _ASSERT(context->outputting_block_num_literals <= OPT_ENCODER_MAX_ITEMS);
  586. // flush our recording matches bit buffer
  587. FLUSH_RECORDING_BITBUF();
  588. // BUGBUG Should check for failure result. Luckily the only failure condition is
  589. // that the tree didn't fit into 500 bytes, which is basically impossible anyway.
  590. (void) OptimalEncoderOutputBlock(context);
  591. // fix estimates for optimal parser
  592. fixOptimalEstimates(context);
  593. encoder->next_tree_update = FIRST_TREE_UPDATE;
  594. // did we output the whole block?
  595. if (context->state == STATE_NORMAL)
  596. {
  597. // reset literal recording
  598. recording_bufptr = encoder->recording_bufptr;
  599. recording_bitbuf = encoder->recording_bitbuf;
  600. recording_bitcount = encoder->recording_bitcount;
  601. goto after_output_block;
  602. }
  603. }
  604. // save recording state
  605. encoder->recording_bufptr = recording_bufptr;
  606. encoder->recording_bitbuf = recording_bitbuf;
  607. encoder->recording_bitcount = recording_bitcount;
  608. context->bufpos = bufpos;
  609. VERIFY_HASHES(bufpos);
  610. removeNodes(context);
  611. VERIFY_HASHES(bufpos);
  612. if (context->bufpos == 2*WINDOW_SIZE)
  613. OptimalEncoderMoveWindows(context);
  614. }
  615. //
  616. // Move the search windows when bufpos reaches 2*WINDOW_SIZE
  617. //
  618. static void OptimalEncoderMoveWindows(t_encoder_context *context)
  619. {
  620. long delta;
  621. int i;
  622. t_optimal_encoder *encoder = context->optimal_encoder;
  623. t_search_node *search_tree_root = encoder->search_tree_root;
  624. t_search_node *left = encoder->search_left;
  625. t_search_node *right = encoder->search_right;
  626. _ASSERT(context->bufpos == 2*WINDOW_SIZE);
  627. VERIFY_HASHES(context->bufpos);
  628. delta = context->bufpos - WINDOW_SIZE;
  629. memcpy(&encoder->window[0], &encoder->window[context->bufpos - WINDOW_SIZE], WINDOW_SIZE);
  630. for (i = 0; i < NUM_DIRECT_LOOKUP_TABLE_ELEMENTS; i++)
  631. {
  632. long val = ((long) search_tree_root[i]) - delta;
  633. if (val <= 0)
  634. search_tree_root[i] = (t_search_node) 0;
  635. else
  636. search_tree_root[i] = (t_search_node) val;
  637. _ASSERT(search_tree_root[i] < WINDOW_SIZE);
  638. }
  639. memcpy(&left[0], &left[context->bufpos - WINDOW_SIZE], sizeof(t_search_node)*WINDOW_SIZE);
  640. memcpy(&right[0], &right[context->bufpos - WINDOW_SIZE], sizeof(t_search_node)*WINDOW_SIZE);
  641. for (i = 0; i < WINDOW_SIZE; i++)
  642. {
  643. long val;
  644. // left
  645. val = ((long) left[i]) - delta;
  646. if (val <= 0)
  647. left[i] = (t_search_node) 0;
  648. else
  649. left[i] = (t_search_node) val;
  650. // right
  651. val = ((long) right[i]) - delta;
  652. if (val <= 0)
  653. right[i] = (t_search_node) 0;
  654. else
  655. right[i] = (t_search_node) val;
  656. }
  657. #ifdef _DEBUG
  658. // force any search table references to be invalid
  659. memset(&encoder->window[WINDOW_SIZE], 0, WINDOW_SIZE);
  660. #endif
  661. context->bufpos = WINDOW_SIZE;
  662. context->bufpos_end = context->bufpos;
  663. VERIFY_HASHES(context->bufpos);
  664. }
  665. //
  666. // Calculate the frequencies of all literal and distance codes, for tree-making, then
  667. // make the trees
  668. //
  669. static void calculateUpdatedEstimates(t_encoder_context *context)
  670. {
  671. USHORT code[MAX_LITERAL_TREE_ELEMENTS];
  672. t_optimal_encoder *encoder = context->optimal_encoder;
  673. // create the trees, we're interested only in len[], not code[]
  674. // BUGBUG perf optimisation: make makeTree() not call MakeCode() in this situation
  675. makeTree(
  676. MAX_LITERAL_TREE_ELEMENTS,
  677. 15,
  678. encoder->literal_tree_freq,
  679. code,
  680. encoder->literal_tree_len
  681. );
  682. makeTree(
  683. MAX_DIST_TREE_ELEMENTS,
  684. 15,
  685. encoder->dist_tree_freq,
  686. code,
  687. encoder->dist_tree_len
  688. );
  689. }
  690. //
  691. // Zero the running frequency counts
  692. //
  693. // Also set freq[END_OF_BLOCK_CODE] = 1
  694. //
  695. void OptimalEncoderZeroFrequencyCounts(t_optimal_encoder *encoder)
  696. {
  697. _ASSERT(encoder != NULL);
  698. memset(encoder->literal_tree_freq, 0, sizeof(encoder->literal_tree_freq));
  699. memset(encoder->dist_tree_freq, 0, sizeof(encoder->dist_tree_freq));
  700. encoder->literal_tree_freq[END_OF_BLOCK_CODE] = 1;
  701. }
  702. void OptimalEncoderReset(t_encoder_context *context)
  703. {
  704. t_optimal_encoder *encoder = context->optimal_encoder;
  705. _ASSERT(encoder != NULL);
  706. encoder->recording_bitbuf = 0;
  707. encoder->recording_bitcount = 0;
  708. encoder->recording_bufptr = encoder->lit_dist_buffer;
  709. context->window_size = WINDOW_SIZE;
  710. context->bufpos = context->window_size;
  711. context->bufpos_end = context->bufpos;
  712. DeflateInitRecordingTables(
  713. encoder->recording_literal_tree_len,
  714. encoder->recording_literal_tree_code,
  715. encoder->recording_dist_tree_len,
  716. encoder->recording_dist_tree_code
  717. );
  718. // clear the search table
  719. memset(
  720. encoder->search_tree_root,
  721. 0,
  722. sizeof(encoder->search_tree_root)
  723. );
  724. encoder->next_tree_update = FIRST_TREE_UPDATE;
  725. initOptimalEstimates(context);
  726. OptimalEncoderZeroFrequencyCounts(encoder);
  727. }
  728. BOOL OptimalEncoderInit(t_encoder_context *context)
  729. {
  730. context->optimal_encoder = (t_optimal_encoder *) LocalAlloc(LMEM_FIXED, sizeof(t_optimal_encoder));
  731. if (context->optimal_encoder == NULL)
  732. return FALSE;
  733. OptimalEncoderReset(context);
  734. return TRUE;
  735. }