166 lines
3.5 KiB
C
166 lines
3.5 KiB
C
|
/*
|
||
|
* encapi.c
|
||
|
*
|
||
|
* Encoder API entrypoints.
|
||
|
*/
|
||
|
|
||
|
#define ALLOC_VARS
|
||
|
#include "encoder.h"
|
||
|
|
||
|
|
||
|
bool LZX_EncodeInit(
|
||
|
|
||
|
t_encoder_context *context,
|
||
|
|
||
|
long compression_window_size,
|
||
|
long second_partition_size,
|
||
|
|
||
|
PFNALLOC pfnma,
|
||
|
PFNFREE pfnmf,
|
||
|
|
||
|
int FAR (DIAMONDAPI *pfnlzx_output_callback)(
|
||
|
void * pfol,
|
||
|
unsigned char * compressed_data,
|
||
|
long compressed_size,
|
||
|
long uncompressed_size
|
||
|
),
|
||
|
|
||
|
void *fci_data
|
||
|
)
|
||
|
{
|
||
|
#ifdef _DEBUG
|
||
|
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
||
|
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
|
||
|
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
|
||
|
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
|
||
|
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
|
||
|
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
|
||
|
#endif
|
||
|
|
||
|
/* to pass back in lzx_output_callback() */
|
||
|
context->enc_fci_data = fci_data;
|
||
|
|
||
|
context->enc_window_size = compression_window_size;
|
||
|
|
||
|
/*
|
||
|
* The second partition size must be a multiple of 32K
|
||
|
*/
|
||
|
if (second_partition_size & (CHUNK_SIZE-1))
|
||
|
second_partition_size &= (~(CHUNK_SIZE-1));
|
||
|
|
||
|
/*
|
||
|
* The minimum allowed is 32K because of the way that
|
||
|
* our translation works.
|
||
|
*/
|
||
|
if (second_partition_size < CHUNK_SIZE)
|
||
|
second_partition_size = CHUNK_SIZE;
|
||
|
|
||
|
/*
|
||
|
* Our window size must be at least 32K
|
||
|
*/
|
||
|
if (compression_window_size < CHUNK_SIZE)
|
||
|
return false;
|
||
|
|
||
|
context->enc_encoder_second_partition_size = second_partition_size;
|
||
|
context->enc_output_callback_function = pfnlzx_output_callback;
|
||
|
|
||
|
context->enc_malloc = pfnma;
|
||
|
context->enc_free = pfnmf;
|
||
|
|
||
|
/* Error allocating memory? */
|
||
|
if (comp_alloc_compress_memory(context) == false)
|
||
|
return false;
|
||
|
|
||
|
LZX_EncodeNewGroup(context);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Cleanup (frees memory)
|
||
|
*/
|
||
|
void LZX_EncodeFree(t_encoder_context *context)
|
||
|
{
|
||
|
comp_free_compress_memory(context);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Sets up the encoder for a new group of files.
|
||
|
*
|
||
|
* All this does is reset the lookup table, re-initialise to the
|
||
|
* default match estimation tables for the optimal parser, and
|
||
|
* reset a few variables.
|
||
|
*/
|
||
|
void LZX_EncodeNewGroup(t_encoder_context *context)
|
||
|
{
|
||
|
init_compression_memory(context);
|
||
|
}
|
||
|
|
||
|
|
||
|
long LZX_Encode(
|
||
|
t_encoder_context *context,
|
||
|
byte *input_data,
|
||
|
long input_size,
|
||
|
long *estimated_bytes_compressed,
|
||
|
long file_size_for_translation
|
||
|
)
|
||
|
{
|
||
|
context->enc_input_ptr = input_data;
|
||
|
context->enc_input_left = input_size;
|
||
|
|
||
|
context->enc_file_size_for_translation = file_size_for_translation;
|
||
|
|
||
|
/* perform the encoding */
|
||
|
encoder_start(context);
|
||
|
|
||
|
if (context->enc_output_overflow)
|
||
|
{
|
||
|
*estimated_bytes_compressed = 0;
|
||
|
return ENCODER_WRITE_FAILURE;
|
||
|
}
|
||
|
|
||
|
*estimated_bytes_compressed = estimate_buffer_contents(context);
|
||
|
|
||
|
return ENCODER_SUCCESS;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool LZX_EncodeFlush(t_encoder_context *context)
|
||
|
{
|
||
|
flush_all_pending_blocks(context);
|
||
|
|
||
|
if (context->enc_output_overflow)
|
||
|
return false;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
unsigned char *LZX_GetInputData(
|
||
|
t_encoder_context *context,
|
||
|
unsigned long *input_position,
|
||
|
unsigned long *bytes_available
|
||
|
)
|
||
|
{
|
||
|
unsigned long filepos;
|
||
|
|
||
|
// note that BufPos-window_size is the real position in the file
|
||
|
filepos = context->enc_BufPos - context->enc_window_size;
|
||
|
|
||
|
if (filepos < context->enc_window_size)
|
||
|
{
|
||
|
*input_position = 0;
|
||
|
*bytes_available = filepos;
|
||
|
return &context->enc_MemWindow[context->enc_window_size];
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*input_position = filepos - context->enc_window_size;
|
||
|
*bytes_available = context->enc_window_size;
|
||
|
return &context->enc_MemWindow[context->enc_BufPos - context->enc_window_size];
|
||
|
}
|
||
|
}
|
||
|
|