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.

228 lines
5.7 KiB

  1. /*
  2. * decblk.c
  3. *
  4. * main decoder module
  5. */
  6. #include "decoder.h"
  7. /* local function prototypes */
  8. static int decode_block(
  9. t_decoder_context *context,
  10. lzx_block_type block_type,
  11. long bufpos,
  12. long amount_to_decode
  13. );
  14. /*
  15. * Decode a block type
  16. */
  17. static int decode_block(
  18. t_decoder_context *context,
  19. lzx_block_type block_type,
  20. long bufpos,
  21. long amount_to_decode
  22. )
  23. {
  24. int result;
  25. if (block_type == BLOCKTYPE_ALIGNED)
  26. result = decode_aligned_offset_block(context, bufpos, (int) amount_to_decode);
  27. else if (block_type == BLOCKTYPE_VERBATIM)
  28. result = decode_verbatim_block(context, bufpos, (int) amount_to_decode);
  29. else if (block_type == BLOCKTYPE_UNCOMPRESSED)
  30. result = decode_uncompressed_block(context, bufpos, (int) amount_to_decode);
  31. else /* no other block types exist */
  32. result = -1;
  33. return result;
  34. }
  35. /*
  36. * Main decode entrypoint
  37. */
  38. long NEAR decode_data(t_decoder_context *context, long bytes_to_decode)
  39. {
  40. ulong amount_can_decode;
  41. long total_decoded;
  42. total_decoded = 0;
  43. while (bytes_to_decode > 0)
  44. {
  45. if (context->dec_decoder_state == DEC_STATE_START_NEW_BLOCK)
  46. {
  47. ulong temp1;
  48. ulong temp2;
  49. ulong temp3;
  50. bool do_translation;
  51. /*
  52. * If this is the first time this group, then get the
  53. * file size for translation.
  54. */
  55. if (context->dec_first_time_this_group)
  56. {
  57. context->dec_first_time_this_group = false;
  58. do_translation = (bool) getbits(context, 1);
  59. if (do_translation)
  60. {
  61. ulong high, low;
  62. high = getbits(context, 16);
  63. low = getbits(context, 16);
  64. context->dec_current_file_size = (high<<16)|low;
  65. }
  66. else
  67. {
  68. context->dec_current_file_size = 0;
  69. }
  70. }
  71. /*
  72. * If the last block we decoded was uncompressed, then
  73. * we need to skip the pad byte (if it exists), and
  74. * initialise the decoder's bit buffer
  75. */
  76. if (context->dec_block_type == BLOCKTYPE_UNCOMPRESSED)
  77. {
  78. /*
  79. * If block size was odd, a pad byte is required
  80. */
  81. if (context->dec_original_block_size & 1)
  82. {
  83. if (context->dec_input_curpos < context->dec_end_input_pos)
  84. context->dec_input_curpos++;
  85. }
  86. /* so that initialise_decoder_bitbuf() will succeed */
  87. context->dec_block_type = BLOCKTYPE_INVALID;
  88. initialise_decoder_bitbuf(context);
  89. }
  90. /* get the block type */
  91. context->dec_block_type = (lzx_block_type) getbits(context, 3);
  92. /* get size of block (in uncompressed bytes) to decode */
  93. temp1 = getbits(context, 8);
  94. temp2 = getbits(context, 8);
  95. temp3 = getbits(context, 8);
  96. /*
  97. * How large is the block we're going to decode?
  98. * It can be from 0...16777215 bytes (16MB)
  99. */
  100. context->dec_block_size =
  101. context->dec_original_block_size = (temp1<<16) + (temp2<<8) + (temp3);
  102. /* if block is an aligned type, read the aligned offset tree */
  103. if (context->dec_block_type == BLOCKTYPE_ALIGNED)
  104. read_aligned_offset_tree(context);
  105. /* read trees */
  106. if (context->dec_block_type == BLOCKTYPE_VERBATIM ||
  107. context->dec_block_type == BLOCKTYPE_ALIGNED)
  108. {
  109. /* backup old trees */
  110. memcpy(
  111. context->dec_main_tree_prev_len,
  112. context->dec_main_tree_len,
  113. MAIN_TREE_ELEMENTS
  114. );
  115. memcpy(
  116. context->dec_secondary_length_tree_prev_len,
  117. context->dec_secondary_length_tree_len,
  118. NUM_SECONDARY_LENGTHS
  119. );
  120. read_main_and_secondary_trees(context);
  121. }
  122. else if (context->dec_block_type == BLOCKTYPE_UNCOMPRESSED)
  123. {
  124. if (handle_beginning_of_uncompressed_block(context) == false)
  125. return -1;
  126. }
  127. else
  128. {
  129. /* no other block types are supported at this time */
  130. return -1;
  131. }
  132. context->dec_decoder_state = DEC_STATE_DECODING_DATA;
  133. }
  134. /*
  135. * Keep decoding until the whole block has been decoded
  136. */
  137. while ((context->dec_block_size > 0) && (bytes_to_decode > 0))
  138. {
  139. int decode_residue;
  140. amount_can_decode = (((context->dec_block_size) < (bytes_to_decode)) ? (context->dec_block_size) : (bytes_to_decode));
  141. /* shouldn't happen */
  142. if (amount_can_decode == 0)
  143. return -1;
  144. decode_residue = decode_block(
  145. context,
  146. context->dec_block_type,
  147. context->dec_bufpos,
  148. amount_can_decode
  149. );
  150. /*
  151. * We should have decoded exactly the amount we wanted,
  152. * since the encoder makes sure that no matches span 32K
  153. * boundaries.
  154. *
  155. * If the data was corrupted, it's possible that we decoded
  156. * up to MAX_MATCH bytes more than we wanted to.
  157. */
  158. if (decode_residue != 0)
  159. {
  160. /* error, we didn't decode what we wanted! */
  161. return -1;
  162. }
  163. context->dec_block_size -= amount_can_decode;
  164. bytes_to_decode -= amount_can_decode;
  165. total_decoded += amount_can_decode;
  166. }
  167. if (context->dec_block_size == 0)
  168. {
  169. context->dec_decoder_state = DEC_STATE_START_NEW_BLOCK;
  170. }
  171. if (bytes_to_decode == 0)
  172. {
  173. initialise_decoder_bitbuf(context);
  174. }
  175. }
  176. #ifdef BIT16
  177. copy_data_to_output(
  178. context,
  179. total_decoded,
  180. context->dec_output_buffer
  181. );
  182. #else
  183. copy_data_to_output(
  184. context,
  185. total_decoded,
  186. context->dec_bufpos ?
  187. &context->dec_mem_window[context->dec_bufpos - total_decoded] :
  188. &context->dec_mem_window[context->dec_window_size - total_decoded]
  189. );
  190. #endif
  191. return total_decoded;
  192. }