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.

291 lines
7.0 KiB

  1. /*
  2. * init.c
  3. *
  4. * Initialise encoder
  5. */
  6. #include "encoder.h"
  7. #define MEM_WINDOW_ALLOC_SIZE \
  8. (context->enc_window_size+(MAX_MATCH+EXTRA_SIZE)+context->enc_encoder_second_partition_size)
  9. /*
  10. * Initialise encoder
  11. */
  12. void init_compression_memory(t_encoder_context *context)
  13. {
  14. /* set all root pointers to NULL */
  15. #ifdef MULTIPLE_SEARCH_TREES
  16. memset(
  17. context->enc_tree_root,
  18. 0,
  19. NUM_SEARCH_TREES * sizeof(context->enc_tree_root[0])
  20. );
  21. #else
  22. context->enc_single_tree_root = 0;
  23. #endif
  24. context->enc_MemWindow = context->enc_RealMemWindow - context->enc_window_size;
  25. context->enc_Left = context->enc_RealLeft - context->enc_window_size;
  26. context->enc_Right = context->enc_RealRight - context->enc_window_size;
  27. context->enc_BufPos = context->enc_window_size;
  28. /*
  29. * Set initial state of repeated match offsets
  30. */
  31. context->enc_last_matchpos_offset[0] = 1;
  32. context->enc_last_matchpos_offset[1] = 1;
  33. context->enc_last_matchpos_offset[2] = 1;
  34. /*
  35. * repeated offset states the last time we output a block
  36. * see block.c/encdata.c
  37. */
  38. context->enc_repeated_offset_at_literal_zero[0] = 1;
  39. context->enc_repeated_offset_at_literal_zero[1] = 1;
  40. context->enc_repeated_offset_at_literal_zero[2] = 1;
  41. /* this is the first compressed block in the file */
  42. context->enc_first_block = true;
  43. /* we don't have any cumulative stats yet */
  44. context->enc_need_to_recalc_stats = true;
  45. /* bufpos @ last time we output a block */
  46. context->enc_bufpos_last_output_block = context->enc_BufPos;
  47. /* initialise bit buffer */
  48. context->enc_bitcount = 32;
  49. context->enc_bitbuf = 0;
  50. context->enc_output_overflow = false;
  51. /*
  52. * The last lengths are zeroed in both the encoder and decoder,
  53. * since our tree representation is delta format.
  54. */
  55. memset(context->enc_main_tree_prev_len, 0, MAIN_TREE_ELEMENTS);
  56. memset(context->enc_secondary_tree_prev_len, 0, NUM_SECONDARY_LENGTHS);
  57. /*
  58. * Set the default last tree lengths for cost estimation
  59. */
  60. memset(context->enc_main_tree_len, 8, NUM_CHARS);
  61. memset(&context->enc_main_tree_len[NUM_CHARS], 9, MAIN_TREE_ELEMENTS-NUM_CHARS);
  62. memset(context->enc_secondary_tree_len, 6, NUM_SECONDARY_LENGTHS);
  63. memset(context->enc_aligned_tree_len, 3, ALIGNED_NUM_ELEMENTS);
  64. prevent_far_matches(context); /* prevent far match 2's from being taken */
  65. context->enc_bufpos_at_last_block = context->enc_BufPos;
  66. context->enc_earliest_window_data_remaining = context->enc_BufPos;
  67. context->enc_input_running_total = 0;
  68. context->enc_first_time_this_group = true;
  69. /* Clear the literal types array */
  70. memset(context->enc_ItemType, 0, MAX_LITERAL_ITEMS/8);
  71. /* No literals or distances encoded yet */
  72. context->enc_literals = 0;
  73. context->enc_distances = 0;
  74. /* No block splits yet */
  75. context->enc_num_block_splits = 0;
  76. context->enc_repeated_offset_at_literal_zero[0] = 1;
  77. context->enc_repeated_offset_at_literal_zero[1] = 1;
  78. context->enc_repeated_offset_at_literal_zero[2] = 1;
  79. /* reset instruction pointer (for translation) to zero */
  80. reset_translation(context);
  81. context->enc_num_cfdata_frames = 0;
  82. }
  83. /*
  84. * Allocate memory for the compressor
  85. *
  86. * Returns true if successful, false otherwise
  87. */
  88. bool comp_alloc_compress_memory(t_encoder_context *context)
  89. {
  90. ulong pos_start;
  91. #ifdef MULTIPLE_SEARCH_TREES
  92. context->enc_tree_root = NULL;
  93. #endif
  94. context->enc_RealLeft = NULL;
  95. context->enc_RealRight = NULL;
  96. context->enc_MemWindow = NULL;
  97. context->enc_decision_node = NULL;
  98. context->enc_LitData = NULL;
  99. context->enc_DistData = NULL;
  100. context->enc_ItemType = NULL;
  101. context->enc_output_buffer_start = NULL;
  102. /* ALSO NULLIFY BUFFERS! */
  103. /*
  104. * Determine the number of position slots in the main tree
  105. */
  106. context->enc_num_position_slots = 4;
  107. pos_start = 4;
  108. while (1)
  109. {
  110. pos_start += 1 << enc_extra_bits[context->enc_num_position_slots];
  111. context->enc_num_position_slots++;
  112. if (pos_start >= context->enc_window_size)
  113. break;
  114. }
  115. #ifdef MULTIPLE_SEARCH_TREES
  116. context->enc_tree_root = (ulong *) context->enc_malloc(
  117. sizeof(context->enc_tree_root[0]) * NUM_SEARCH_TREES
  118. );
  119. if (context->enc_tree_root == NULL)
  120. {
  121. comp_free_compress_memory(context);
  122. return false;
  123. }
  124. #endif
  125. context->enc_RealLeft = (ulong *) context->enc_malloc(
  126. sizeof(ulong) * MEM_WINDOW_ALLOC_SIZE
  127. );
  128. if (context->enc_RealLeft == NULL)
  129. {
  130. comp_free_compress_memory(context);
  131. return false;
  132. }
  133. context->enc_RealRight = (ulong *) context->enc_malloc(
  134. sizeof(ulong) * MEM_WINDOW_ALLOC_SIZE
  135. );
  136. if (context->enc_RealRight == NULL)
  137. {
  138. comp_free_compress_memory(context);
  139. return false;
  140. }
  141. context->enc_RealMemWindow = (byte *) context->enc_malloc(MEM_WINDOW_ALLOC_SIZE);
  142. if (context->enc_RealMemWindow == NULL)
  143. {
  144. comp_free_compress_memory(context);
  145. return false;
  146. }
  147. context->enc_MemWindow = context->enc_RealMemWindow;
  148. context->enc_LitData = (byte *) context->enc_malloc(MAX_LITERAL_ITEMS * sizeof(*context->enc_LitData));
  149. if (context->enc_LitData == NULL)
  150. {
  151. comp_free_compress_memory(context);
  152. return false;
  153. }
  154. context->enc_DistData = (ulong *) context->enc_malloc(MAX_DIST_ITEMS * sizeof(*context->enc_DistData));
  155. if (context->enc_DistData == NULL)
  156. {
  157. comp_free_compress_memory(context);
  158. return false;
  159. }
  160. context->enc_ItemType = (byte *) context->enc_malloc(MAX_LITERAL_ITEMS/8);
  161. if (context->enc_ItemType == NULL)
  162. {
  163. comp_free_compress_memory(context);
  164. return false;
  165. }
  166. create_slot_lookup_table(context);
  167. create_ones_table(context);
  168. if (init_compressed_output_buffer(context) == false)
  169. {
  170. comp_free_compress_memory(context);
  171. return false;
  172. }
  173. context->enc_decision_node = context->enc_malloc(
  174. sizeof(decision_node) * (LOOK+MAX_MATCH+16)
  175. );
  176. if (context->enc_decision_node == NULL)
  177. {
  178. comp_free_compress_memory(context);
  179. return false;
  180. }
  181. context->enc_allocated_compression_memory = true;
  182. /* success */
  183. return true;
  184. }
  185. void comp_free_compress_memory(t_encoder_context *context)
  186. {
  187. #ifdef MULTIPLE_SEARCH_TREES
  188. if (context->enc_tree_root)
  189. {
  190. context->enc_free((byte *) context->enc_tree_root);
  191. context->enc_tree_root = NULL;
  192. }
  193. #endif
  194. if (context->enc_RealLeft)
  195. {
  196. context->enc_free((byte *) context->enc_RealLeft);
  197. context->enc_RealLeft = NULL;
  198. }
  199. if (context->enc_RealRight)
  200. {
  201. context->enc_free((byte *) context->enc_RealRight);
  202. context->enc_RealRight = NULL;
  203. }
  204. if (context->enc_RealMemWindow)
  205. {
  206. context->enc_free((byte *) context->enc_RealMemWindow);
  207. context->enc_RealMemWindow = NULL;
  208. context->enc_MemWindow = NULL;
  209. }
  210. if (context->enc_LitData)
  211. {
  212. context->enc_free(context->enc_LitData);
  213. context->enc_LitData = NULL;
  214. }
  215. if (context->enc_DistData)
  216. {
  217. context->enc_free((byte *) context->enc_DistData);
  218. context->enc_DistData = NULL;
  219. }
  220. if (context->enc_ItemType)
  221. {
  222. context->enc_free(context->enc_ItemType);
  223. context->enc_ItemType = NULL;
  224. }
  225. if (context->enc_decision_node)
  226. {
  227. context->enc_free((byte *) context->enc_decision_node);
  228. context->enc_decision_node = NULL;
  229. }
  230. free_compressed_output_buffer(context);
  231. context->enc_allocated_compression_memory = false;
  232. }