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.

148 lines
3.2 KiB

  1. //
  2. // infuncmp.c
  3. //
  4. // Decodes uncompressed blocks
  5. //
  6. #include "inflate.h"
  7. #include "infmacro.h"
  8. //
  9. // Returns whether there are >= n valid bits in the bit buffer
  10. //
  11. #define ASSERT_BITS_IN_BIT_BUFFER(n) (context->bitcount + 16 >= (n))
  12. static int twoBytesToInt(byte a, byte b)
  13. {
  14. return (((int) a) & 255) | ((((int) b) & 255) << 8);
  15. }
  16. static void dumpBits(t_decoder_context *context, int n)
  17. {
  18. context->bitbuf >>= n;
  19. context->bitcount -= n;
  20. }
  21. // retrieve n bits from the bit buffer, and dump them when done
  22. // n can be up to 16
  23. static int getBits(t_decoder_context *context, int n)
  24. {
  25. int result;
  26. context->bitcount -= n;
  27. result = (context->bitbuf & g_BitMask[n]);
  28. context->bitbuf >>= n;
  29. return result;
  30. }
  31. BOOL decodeUncompressedBlock(t_decoder_context *context, BOOL *end_of_block)
  32. {
  33. unsigned int unc_len, complement;
  34. *end_of_block = FALSE;
  35. if (context->state == STATE_DECODING_UNCOMPRESSED)
  36. {
  37. unc_len = context->state_loop_counter;
  38. }
  39. else
  40. {
  41. int i;
  42. if (context->state == STATE_UNCOMPRESSED_ALIGNING)
  43. {
  44. //
  45. // Right now we have between 0 and 32 bits in bitbuf
  46. //
  47. // However, we must flush to a byte boundary
  48. //
  49. if ((context->bitcount & 7) != 0)
  50. {
  51. int result;
  52. result = getBits(context, (context->bitcount & 7));
  53. //
  54. // Since this is supposed to be padding, we should read all zeroes,
  55. // however, it's not really specified in the spec that they have to
  56. // be zeroes, so don't count this as an error
  57. //
  58. }
  59. //
  60. // Now we have exactly 0, 8, 16, 24, or 32 bits in the bit buffer
  61. //
  62. context->state = STATE_UNCOMPRESSED_1;
  63. }
  64. //
  65. // Now we need to read 4 bytes from the input - however, some of these bytes may
  66. // be inside our bit buffer, so take them from there first
  67. //
  68. for (i = 0; i < 4; i++)
  69. {
  70. if (context->state == STATE_UNCOMPRESSED_1 + i)
  71. {
  72. if (ASSERT_BITS_IN_BIT_BUFFER(8))
  73. {
  74. context->unc_buffer[i] = (byte) ((context->bitbuf) & 255);
  75. context->bitbuf >>= 8;
  76. context->bitcount -= 8;
  77. }
  78. else
  79. {
  80. if (INPUT_EOF())
  81. return TRUE;
  82. context->unc_buffer[i] = *context->input_curpos++;
  83. }
  84. context->state++;
  85. }
  86. }
  87. unc_len = twoBytesToInt(
  88. context->unc_buffer[0], context->unc_buffer[1]
  89. );
  90. complement = twoBytesToInt(
  91. context->unc_buffer[2], context->unc_buffer[3]
  92. );
  93. // make sure complement matches
  94. if ((unsigned short) unc_len != (unsigned short) (~complement))
  95. return FALSE; // error!
  96. }
  97. // BUGBUG Make this into a memory copy loop for speed!
  98. while (unc_len > 0 && context->input_curpos < context->end_input_buffer && context->output_curpos < context->end_output_buffer)
  99. {
  100. unc_len--;
  101. *context->output_curpos++ = context->window[context->bufpos++] = *context->input_curpos++;
  102. context->bufpos &= WINDOW_MASK;
  103. }
  104. //
  105. // More bytes left to compress in this block?
  106. //
  107. if (unc_len != 0)
  108. {
  109. context->state = STATE_DECODING_UNCOMPRESSED;
  110. context->state_loop_counter = unc_len;
  111. }
  112. else
  113. {
  114. //
  115. // Done with this block, need to re-init bit buffer for next block
  116. //
  117. context->state = STATE_READING_BFINAL_NEED_TO_INIT_BITBUF;
  118. *end_of_block = TRUE;
  119. }
  120. return TRUE;
  121. }