/* * LCI.C */ /* --- preprocessor ------------------------------------------------------- */ #include /* for NULL */ #include /* 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); }