optenc.c
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 25k
Category:

Windows Develop

Development Platform:

Visual C++

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