windows-nt/Source/XPSP1/NT/enduser/stuff/itss/lzx/encoder/lci.c

269 lines
7.4 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*
* 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);
}