258 lines
8.2 KiB
C
258 lines
8.2 KiB
C
/*
|
|
* init.c
|
|
*
|
|
* Initialise encoder
|
|
*/
|
|
#include "encoder.h"
|
|
|
|
|
|
#define MEM_WINDOW_ALLOC_SIZE \
|
|
(context->enc_window_size+(MAX_MATCH+EXTRA_SIZE)+context->enc_encoder_second_partition_size)
|
|
|
|
/*
|
|
* Initialise encoder
|
|
*/
|
|
void init_compression_memory(t_encoder_context *context)
|
|
{
|
|
/* set all root pointers to NULL */
|
|
#ifdef MULTIPLE_SEARCH_TREES
|
|
memset(
|
|
context->enc_tree_root,
|
|
0,
|
|
NUM_SEARCH_TREES * sizeof(context->enc_tree_root[0])
|
|
);
|
|
#else
|
|
context->enc_single_tree_root = 0;
|
|
#endif
|
|
|
|
context->enc_MemWindow = context->enc_RealMemWindow - context->enc_window_size;
|
|
context->enc_Left = context->enc_RealLeft - context->enc_window_size;
|
|
context->enc_Right = context->enc_RealRight - context->enc_window_size;
|
|
context->enc_BufPos = context->enc_window_size;
|
|
|
|
/*
|
|
* Set initial state of repeated match offsets
|
|
*/
|
|
context->enc_last_matchpos_offset[0] = 1;
|
|
context->enc_last_matchpos_offset[1] = 1;
|
|
context->enc_last_matchpos_offset[2] = 1;
|
|
|
|
/*
|
|
* repeated offset states the last time we output a block
|
|
* see block.c/encdata.c
|
|
*/
|
|
context->enc_repeated_offset_at_literal_zero[0] = 1;
|
|
context->enc_repeated_offset_at_literal_zero[1] = 1;
|
|
context->enc_repeated_offset_at_literal_zero[2] = 1;
|
|
|
|
/* this is the first compressed block in the file */
|
|
context->enc_first_block = true;
|
|
|
|
/* we don't have any cumulative stats yet */
|
|
context->enc_need_to_recalc_stats = true;
|
|
|
|
/* bufpos @ last time we output a block */
|
|
context->enc_bufpos_last_output_block = context->enc_BufPos;
|
|
|
|
/* initialise bit buffer */
|
|
context->enc_bitcount = 32;
|
|
context->enc_bitbuf = 0;
|
|
context->enc_output_overflow = false;
|
|
|
|
/*
|
|
* The last lengths are zeroed in both the encoder and decoder,
|
|
* since our tree representation is delta format.
|
|
*/
|
|
memset(context->enc_main_tree_prev_len, 0, MAIN_TREE_ELEMENTS);
|
|
memset(context->enc_secondary_tree_prev_len, 0, NUM_SECONDARY_LENGTHS);
|
|
|
|
/*
|
|
* Set the default last tree lengths for cost estimation
|
|
*/
|
|
memset(context->enc_main_tree_len, 8, NUM_CHARS);
|
|
memset(&context->enc_main_tree_len[NUM_CHARS], 9, MAIN_TREE_ELEMENTS-NUM_CHARS);
|
|
memset(context->enc_secondary_tree_len, 6, NUM_SECONDARY_LENGTHS);
|
|
memset(context->enc_aligned_tree_len, 3, ALIGNED_NUM_ELEMENTS);
|
|
prevent_far_matches(context); /* prevent far match 2's from being taken */
|
|
|
|
context->enc_bufpos_at_last_block = context->enc_BufPos;
|
|
context->enc_earliest_window_data_remaining = context->enc_BufPos;
|
|
context->enc_input_running_total = 0;
|
|
context->enc_first_time_this_group = true;
|
|
|
|
/* Clear the literal types array */
|
|
memset(context->enc_ItemType, 0, MAX_LITERAL_ITEMS/8);
|
|
|
|
/* No literals or distances encoded yet */
|
|
context->enc_literals = 0;
|
|
context->enc_distances = 0;
|
|
|
|
/* No block splits yet */
|
|
context->enc_num_block_splits = 0;
|
|
|
|
context->enc_repeated_offset_at_literal_zero[0] = 1;
|
|
context->enc_repeated_offset_at_literal_zero[1] = 1;
|
|
context->enc_repeated_offset_at_literal_zero[2] = 1;
|
|
|
|
/* reset instruction pointer (for translation) to zero */
|
|
reset_translation(context);
|
|
|
|
context->enc_num_cfdata_frames = 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* Allocate memory for the compressor
|
|
*
|
|
* Returns true if successful, false otherwise
|
|
*/
|
|
bool comp_alloc_compress_memory(t_encoder_context *context)
|
|
{
|
|
ulong pos_start;
|
|
|
|
#ifdef MULTIPLE_SEARCH_TREES
|
|
context->enc_tree_root = NULL;
|
|
#endif
|
|
context->enc_RealLeft = NULL;
|
|
context->enc_RealRight = NULL;
|
|
context->enc_MemWindow = NULL;
|
|
context->enc_decision_node = NULL;
|
|
context->enc_LitData = NULL;
|
|
#ifdef EXTRALONGMATCHES
|
|
context->enc_ExtraLength = NULL;
|
|
#endif
|
|
context->enc_DistData = NULL;
|
|
context->enc_ItemType = NULL;
|
|
context->enc_output_buffer_start = NULL;
|
|
|
|
/* ALSO NULLIFY BUFFERS! */
|
|
|
|
/*
|
|
* Determine the number of position slots in the main tree
|
|
*/
|
|
context->enc_num_position_slots = 4;
|
|
pos_start = 4;
|
|
|
|
while (1)
|
|
{
|
|
pos_start += 1 << enc_extra_bits[context->enc_num_position_slots];
|
|
|
|
context->enc_num_position_slots++;
|
|
|
|
if (pos_start >= context->enc_window_size)
|
|
break;
|
|
}
|
|
|
|
#ifdef MULTIPLE_SEARCH_TREES
|
|
context->enc_tree_root = (ulong *) context->enc_malloc(
|
|
context->enc_mallochandle,
|
|
sizeof(context->enc_tree_root[0]) * NUM_SEARCH_TREES
|
|
);
|
|
|
|
if (context->enc_tree_root == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
context->enc_RealLeft = (ulong *) context->enc_malloc(
|
|
context->enc_mallochandle,
|
|
sizeof(ulong) * MEM_WINDOW_ALLOC_SIZE
|
|
);
|
|
|
|
if (context->enc_RealLeft == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
context->enc_RealRight = (ulong *) context->enc_malloc(
|
|
context->enc_mallochandle,
|
|
sizeof(ulong) * MEM_WINDOW_ALLOC_SIZE
|
|
);
|
|
|
|
if (context->enc_RealRight == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
context->enc_RealMemWindow = (byte *) context->enc_malloc(
|
|
context->enc_mallochandle,
|
|
MEM_WINDOW_ALLOC_SIZE
|
|
);
|
|
|
|
if (context->enc_RealMemWindow == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
context->enc_MemWindow = context->enc_RealMemWindow;
|
|
|
|
context->enc_LitData = (byte *) context->enc_malloc(
|
|
context->enc_mallochandle,
|
|
MAX_LITERAL_ITEMS * sizeof(*context->enc_LitData)
|
|
);
|
|
|
|
if (context->enc_LitData == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#ifdef EXTRALONGMATCHES
|
|
|
|
context->enc_ExtraLength = (ushort *) context->enc_malloc(
|
|
context->enc_mallochandle,
|
|
MAX_LITERAL_ITEMS * sizeof(*context->enc_ExtraLength)
|
|
);
|
|
|
|
if (context->enc_ExtraLength == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
context->enc_DistData = (ulong *) context->enc_malloc(
|
|
context->enc_mallochandle,
|
|
MAX_DIST_ITEMS * sizeof(*context->enc_DistData)
|
|
);
|
|
|
|
if (context->enc_DistData == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
context->enc_ItemType = (byte *) context->enc_malloc(
|
|
context->enc_mallochandle,
|
|
MAX_LITERAL_ITEMS/8
|
|
);
|
|
|
|
if (context->enc_ItemType == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
create_slot_lookup_table(context);
|
|
create_ones_table(context);
|
|
|
|
if (init_compressed_output_buffer(context) == false)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
context->enc_decision_node = context->enc_malloc(
|
|
context->enc_mallochandle,
|
|
sizeof(decision_node) * (LOOK+MAX_MATCH+16)
|
|
);
|
|
|
|
if (context->enc_decision_node == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/* success */
|
|
return true;
|
|
}
|
|
|
|
|
|
|