269 lines
7.4 KiB
C
269 lines
7.4 KiB
C
|
/*
|
||
|
* LCI.C
|
||
|
*/
|
||
|
|
||
|
/* --- preprocessor ------------------------------------------------------- */
|
||
|
|
||
|
#include <stdio.h> /* for NULL */
|
||
|
#include <string.h> /* for memcpy() */
|
||
|
|
||
|
#include "encoder.h"
|
||
|
#include "lci.h" /* types, prototype verification, error codes */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Default file size for E8 translation
|
||
|
*/
|
||
|
#define DEFAULT_FILE_XLAT_SIZE 12000000
|
||
|
|
||
|
|
||
|
/* MAKE_SIGNATURE - Construct a structure signature
|
||
|
*
|
||
|
* Entry:
|
||
|
* a,b,c,d - four characters
|
||
|
*
|
||
|
* Exit:
|
||
|
* Returns constructed SIGNATURE
|
||
|
*
|
||
|
* Example:
|
||
|
* strct->signature = MAKE_SIGNATURE('b','e','n','s')
|
||
|
*/
|
||
|
|
||
|
#define MAKE_SIGNATURE(a,b,c,d) (a + (b<<8) + (c<<16) + (d<<24))
|
||
|
#define BAD_SIGNATURE (0L)
|
||
|
#define LCI_SIGNATURE MAKE_SIGNATURE('L','C','I','C')
|
||
|
|
||
|
/* --- LCI context structure ---------------------------------------------- */
|
||
|
|
||
|
typedef ULONG SIGNATURE; /* structure signature */
|
||
|
|
||
|
struct LCI_CONTEXT /* private structure */
|
||
|
{
|
||
|
SIGNATURE signature; /* for validation */
|
||
|
PFNALLOC pfnAlloc; /* memory alloc function */
|
||
|
PFNFREE pfnFree; /* memory free function */
|
||
|
UINT cbDataBlockMax; /* promised max data size */
|
||
|
unsigned long file_translation_size;
|
||
|
t_encoder_context *encoder_context;
|
||
|
};
|
||
|
|
||
|
typedef struct LCI_CONTEXT FAR *PMCC_CONTEXT; /* a pointer to one */
|
||
|
|
||
|
#define PMCCfromHMC(h) ((PMCC_CONTEXT)(h)) /* handle to pointer */
|
||
|
#define HMCfromPMCC(p) ((LCI_CONTEXT_HANDLE)(p)) /* pointer to handle */
|
||
|
|
||
|
|
||
|
/* --- local variables ---------------------------------------------------- */
|
||
|
|
||
|
int DIAMONDAPI LCICreateCompression(
|
||
|
UINT * pcbDataBlockMax, /* max uncompressed data block */
|
||
|
void FAR * pvConfiguration, /* implementation-defined */
|
||
|
PFNALLOC pfnma, /* Memory allocation function */
|
||
|
PFNFREE pfnmf, /* Memory free function */
|
||
|
UINT * pcbDstBufferMin, /* gets required output buffer */
|
||
|
LCI_CONTEXT_HANDLE * pmchHandle, /* gets newly-created handle */
|
||
|
int FAR (DIAMONDAPI *pfnlzx_output_callback)(
|
||
|
void * pfol,
|
||
|
unsigned char * compressed_data,
|
||
|
long compressed_size,
|
||
|
long uncompressed_size
|
||
|
),
|
||
|
void FAR * fci_data
|
||
|
)
|
||
|
|
||
|
{
|
||
|
PMCC_CONTEXT context; /* new context */
|
||
|
FAR PLZXCONFIGURATION plConfiguration;
|
||
|
|
||
|
*pmchHandle = (LCI_CONTEXT_HANDLE) 0; /* wait until it's valid */
|
||
|
|
||
|
plConfiguration = (PLZXCONFIGURATION) pvConfiguration;
|
||
|
|
||
|
context = pfnma(sizeof(struct LCI_CONTEXT));
|
||
|
|
||
|
if (context == NULL)
|
||
|
return(MCI_ERROR_NOT_ENOUGH_MEMORY); /* if can't allocate */
|
||
|
|
||
|
context->file_translation_size = DEFAULT_FILE_XLAT_SIZE;
|
||
|
|
||
|
context->encoder_context = pfnma(sizeof(*context->encoder_context));
|
||
|
|
||
|
if (context->encoder_context == NULL)
|
||
|
{
|
||
|
pfnmf(context);
|
||
|
return(MCI_ERROR_NOT_ENOUGH_MEMORY); /* if can't allocate */
|
||
|
}
|
||
|
|
||
|
if (LZX_EncodeInit(
|
||
|
context->encoder_context,
|
||
|
plConfiguration->WindowSize,
|
||
|
plConfiguration->SecondPartitionSize,
|
||
|
pfnma,
|
||
|
pfnmf,
|
||
|
pfnlzx_output_callback,
|
||
|
fci_data
|
||
|
) == false)
|
||
|
{
|
||
|
pfnmf(context->encoder_context);
|
||
|
pfnmf(context);
|
||
|
return MCI_ERROR_NOT_ENOUGH_MEMORY;
|
||
|
}
|
||
|
|
||
|
context->pfnAlloc = pfnma;
|
||
|
context->pfnFree = pfnmf;
|
||
|
context->cbDataBlockMax = *pcbDataBlockMax; /* remember agreement */
|
||
|
context->signature = LCI_SIGNATURE;
|
||
|
|
||
|
*pcbDstBufferMin = /* we'll expand sometimes */
|
||
|
*pcbDataBlockMax + MAX_GROWTH;
|
||
|
|
||
|
/* pass context back to caller */
|
||
|
*pmchHandle = HMCfromPMCC(context);
|
||
|
|
||
|
return(MCI_ERROR_NO_ERROR); /* tell caller all is well */
|
||
|
}
|
||
|
|
||
|
|
||
|
int DIAMONDAPI LCICompress(
|
||
|
LCI_CONTEXT_HANDLE hmc, /* compression context */
|
||
|
void FAR * pbSrc, /* source buffer */
|
||
|
UINT cbSrc, /* source actual size */
|
||
|
void FAR * pbDst, /* target buffer */
|
||
|
UINT cbDst, /* size of target buffer */
|
||
|
ULONG * pcbResult) /* gets target actual size */
|
||
|
{
|
||
|
PMCC_CONTEXT context; /* pointer to the context */
|
||
|
long estimated_leftover_bytes;
|
||
|
|
||
|
context = PMCCfromHMC(hmc); /* get pointer from handle */
|
||
|
|
||
|
if (context->signature != LCI_SIGNATURE)
|
||
|
{
|
||
|
return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
|
||
|
}
|
||
|
|
||
|
if (cbSrc > context->cbDataBlockMax)
|
||
|
{
|
||
|
return(MCI_ERROR_BAD_PARAMETERS); /* violated max block promise */
|
||
|
}
|
||
|
|
||
|
if (cbDst < (context->cbDataBlockMax + MAX_GROWTH))
|
||
|
{
|
||
|
return(MCI_ERROR_BAD_PARAMETERS); /* violated min buffer request */
|
||
|
}
|
||
|
|
||
|
if (ENCODER_SUCCESS == LZX_Encode(
|
||
|
context->encoder_context,
|
||
|
pbSrc,
|
||
|
cbSrc,
|
||
|
&estimated_leftover_bytes,
|
||
|
context->file_translation_size))
|
||
|
{
|
||
|
*pcbResult = estimated_leftover_bytes;
|
||
|
return MCI_ERROR_NO_ERROR;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*pcbResult = 0;
|
||
|
return MCI_ERROR_FAILED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
int DIAMONDAPI LCIFlushCompressorOutput(LCI_CONTEXT_HANDLE hmc)
|
||
|
{
|
||
|
PMCC_CONTEXT context; /* pointer to context */
|
||
|
|
||
|
context = PMCCfromHMC(hmc); /* get pointer from handle */
|
||
|
|
||
|
if (context->signature != LCI_SIGNATURE)
|
||
|
{
|
||
|
return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
|
||
|
}
|
||
|
|
||
|
(void) LZX_EncodeFlush(context->encoder_context);
|
||
|
|
||
|
return MCI_ERROR_NO_ERROR;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* --- LCIResetCompression() ---------------------------------------------- */
|
||
|
|
||
|
int DIAMONDAPI LCIResetCompression(LCI_CONTEXT_HANDLE hmc)
|
||
|
{
|
||
|
PMCC_CONTEXT context; /* pointer to the context */
|
||
|
|
||
|
context = PMCCfromHMC(hmc); /* get pointer from handle */
|
||
|
|
||
|
if (context->signature != LCI_SIGNATURE)
|
||
|
{
|
||
|
return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
|
||
|
}
|
||
|
|
||
|
LZX_EncodeNewGroup(context->encoder_context);
|
||
|
|
||
|
return(MCI_ERROR_NO_ERROR); /* if tag is OK */
|
||
|
}
|
||
|
|
||
|
|
||
|
/* --- LCIDestroyCompression() -------------------------------------------- */
|
||
|
|
||
|
int DIAMONDAPI LCIDestroyCompression(LCI_CONTEXT_HANDLE hmc)
|
||
|
{
|
||
|
PMCC_CONTEXT context; /* pointer to context */
|
||
|
|
||
|
context = PMCCfromHMC(hmc); /* get pointer from handle */
|
||
|
|
||
|
if (context->signature != LCI_SIGNATURE)
|
||
|
{
|
||
|
return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
|
||
|
}
|
||
|
|
||
|
LZX_EncodeFree(context->encoder_context);
|
||
|
context->pfnFree(context->encoder_context);
|
||
|
|
||
|
context->signature = BAD_SIGNATURE; /* destroy signature */
|
||
|
|
||
|
context->pfnFree(context); /* self-destruct */
|
||
|
|
||
|
return(MCI_ERROR_NO_ERROR); /* success */
|
||
|
}
|
||
|
|
||
|
|
||
|
int DIAMONDAPI LCISetTranslationSize(LCI_CONTEXT_HANDLE hmc, unsigned long size)
|
||
|
{
|
||
|
PMCC_CONTEXT context; /* pointer to context */
|
||
|
|
||
|
context = PMCCfromHMC(hmc); /* get pointer from handle */
|
||
|
|
||
|
if (context->signature != LCI_SIGNATURE)
|
||
|
{
|
||
|
return(MCI_ERROR_BAD_PARAMETERS); /* missing signature */
|
||
|
}
|
||
|
|
||
|
context->file_translation_size = size;
|
||
|
return(MCI_ERROR_NO_ERROR); /* success */
|
||
|
}
|
||
|
|
||
|
|
||
|
unsigned char * FAR DIAMONDAPI LCIGetInputData(
|
||
|
LCI_CONTEXT_HANDLE hmc,
|
||
|
unsigned long *input_position,
|
||
|
unsigned long *bytes_available
|
||
|
)
|
||
|
{
|
||
|
PMCC_CONTEXT context; /* pointer to context */
|
||
|
|
||
|
context = PMCCfromHMC(hmc); /* get pointer from handle */
|
||
|
|
||
|
if (context->signature != LCI_SIGNATURE)
|
||
|
{
|
||
|
*bytes_available = 0;
|
||
|
return (unsigned char *) NULL;
|
||
|
}
|
||
|
|
||
|
return LZX_GetInputData(context->encoder_context, input_position, bytes_available);
|
||
|
}
|
||
|
|