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.

124 lines
3.2 KiB

  1. /*
  2. * d16verb.c
  3. *
  4. * Decoding verbatim-bit blocks
  5. */
  6. #include "decoder.h"
  7. int NEAR decode_verbatim_block(
  8. t_decoder_context * context,
  9. long BufPos,
  10. int amount_to_decode /* yes, it will equal 32768 */
  11. )
  12. {
  13. ulong match_pos;
  14. ulong dec_bitbuf;
  15. byte *dec_input_curpos;
  16. byte *dec_end_input_pos;
  17. int match_length;
  18. int c;
  19. char dec_bitcount;
  20. char m;
  21. MATCH match_info;
  22. /*
  23. * Store commonly used variables locally
  24. */
  25. dec_bitcount = context->dec_bitcount;
  26. dec_bitbuf = context->dec_bitbuf;
  27. dec_input_curpos = context->dec_input_curpos;
  28. dec_end_input_pos = context->dec_end_input_pos;
  29. /*
  30. * amount_to_decode must never be > 32768
  31. *
  32. * As it stands, we do the (amount_to_decode >= 0) check
  33. * at the bottom of the DO loop, rather than at the top of
  34. * a WHILE loop, so that we can used a signed int; this way,
  35. * we decrement it by at least 1 by the time we check against
  36. * zero.
  37. */
  38. do
  39. {
  40. /* decode an item from the main tree */
  41. DECODE_MAIN_TREE(c);
  42. if ((c -= NUM_CHARS) < 0)
  43. {
  44. /* it's a character */
  45. /* note: c - 256 == c if c is a byte */
  46. context->DComp_Token_Literal(context, (int) ((byte) c));
  47. amount_to_decode--;
  48. }
  49. else
  50. {
  51. /* get match length header */
  52. if ((match_length = c & NUM_PRIMARY_LENGTHS) == NUM_PRIMARY_LENGTHS)
  53. {
  54. /* get match length footer if necessary */
  55. DECODE_LEN_TREE_NOEOFCHECK(match_length);
  56. }
  57. /* get match position slot */
  58. m = c >> NL_SHIFT;
  59. /* read any extra bits for the match position */
  60. if (m > 2)
  61. {
  62. if (m > 3) /* dec_extra_bits[m] != 0 */
  63. {
  64. GET_BITS17_NOEOFCHECK(dec_extra_bits[ m ], match_pos);
  65. match_pos += MP_POS_minus2[m];
  66. }
  67. else
  68. {
  69. match_pos = MP_POS_minus2[3];
  70. }
  71. /*
  72. * Add match base to "extra bits". Our match base
  73. * table has 2 subtracted from all the elements.
  74. *
  75. * This is because encoded positions 0,1,2 denote
  76. * repeated offsets. Encoded position 3 denotes
  77. * a match 1 character away, 4 encodes 2 away, etc.
  78. * Hence the subtraction of 2, which has been
  79. * incorporated into the table.
  80. */
  81. /* update LRU repeated offset list */
  82. context->dec_last_matchpos_offset[2] = context->dec_last_matchpos_offset[1];
  83. context->dec_last_matchpos_offset[1] = context->dec_last_matchpos_offset[0];
  84. context->dec_last_matchpos_offset[0] = match_pos;
  85. }
  86. else
  87. {
  88. /* positions 0, 1, 2 denote repeated offsets */
  89. match_pos = context->dec_last_matchpos_offset[m];
  90. if (m)
  91. {
  92. context->dec_last_matchpos_offset[m] = context->dec_last_matchpos_offset[0];
  93. context->dec_last_matchpos_offset[0] = match_pos;
  94. }
  95. }
  96. /* match lengths range from 2...257 */
  97. match_length += MIN_MATCH;
  98. match_info.Len = match_length;
  99. match_info.Dist = match_pos;
  100. context->DComp_Token_Match(context, match_info);
  101. amount_to_decode -= match_length;
  102. }
  103. } while (amount_to_decode > 0);
  104. context->dec_bitcount = dec_bitcount;
  105. context->dec_bitbuf = dec_bitbuf;
  106. context->dec_input_curpos = dec_input_curpos;
  107. return 0;
  108. }