/* DEC/CMS REPLACEMENT HISTORY, Element UTIL.C */ /* *1 14-NOV-1996 10:27:03 ANIGBOGU "[113914]Utility functions to support the compression/decompression library" */ /* DEC/CMS REPLACEMENT HISTORY, Element UTIL.C */ /* PRIVATE FILE ****************************************************************************** ** ** (c) Copyright Schlumberger Technology Corp., unpublished work, created 1996. ** ** This computer program includes Confidential, Proprietary Information and is ** a Trade Secret of Schlumberger Technology Corp. All use, disclosure, and/or ** reproduction is prohibited unless authorized in writing by Schlumberger. ** All Rights Reserved. ** ****************************************************************************** ** ** compress/util.c ** ** PURPOSE ** ** Utility functions for compress/decompression support ** ** SPECIAL REQUIREMENTS & NOTES ** ** AUTHOR ** ** J. C. Anigbogu ** Austin Systems Center ** Nov 1996 ** ****************************************************************************** */ #include "comppriv.h" /* =========================================================================== * Clear input and output buffers */ void ClearBuffers( CompParam_t *Comp ) { Comp->OutBytes = 0; Comp->InputSize = Comp->Index = 0; Comp->BytesIn = Comp->BytesOut = 0L; } /* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty. */ int FillInputBuffer( int EOF_OK, /* set if EOF acceptable as a result */ CompParam_t *Comp ) { unsigned long Length; /* Read as much as possible */ Comp->InputSize = 0; Length = MIN(Comp->GlobalSize - Comp->BytesIn, (unsigned long)INBUFSIZ); Comp->Input = Comp->GlobalInput + Comp->BytesIn; Comp->InputSize += Length; if ((Comp->InputSize == 0) && (EOF_OK == 1)) return EOF; Comp->BytesIn += Comp->InputSize; Comp->Index = 1; return (int)Comp->Input[0]; } /* =========================================================================== * Write the output buffer Output[0..OutBytes-1] and update BytesOut. * (used for the compressed data only) */ CompressStatus_t FlushOutputBuffer( CompParam_t *Comp ) { CompressStatus_t Status = COMPRESS_OK; if (Comp->OutBytes == 0) return Status; Status = WriteBuffer(Comp, (char *)Comp->Output, Comp->OutBytes); if (COMPRESS_OK != Status) return Status; Comp->BytesOut += (unsigned long)Comp->OutBytes; Comp->OutBytes = 0; return Status; } /* =========================================================================== * Write the output window Window[0..OutBytes-1] and update crc and BytesOut. * (Used for the decompressed data only.) */ CompressStatus_t FlushWindow( CompParam_t *Comp ) { CompressStatus_t Status = COMPRESS_OK; if (Comp->OutBytes == 0) return Status; Comp->pCRC->Compute(Comp->Window, Comp->OutBytes); Status = WriteBuffer(Comp, (char *)Comp->Window, Comp->OutBytes); if (COMPRESS_OK != Status) return Status; Comp->BytesOut += (unsigned long)Comp->OutBytes; Comp->OutBytes = 0; return Status; } /* =========================================================================== * Flushes output buffer */ CompressStatus_t WriteBuffer( CompParam_t *Comp, void *Buffer, unsigned int Size ) { CompressStatus_t Status; unsigned char *temp = (unsigned char *)CompressMalloc(Size, &Status); if (COMPRESS_OK != Status) return Status; if (Comp->PtrOutput == NULL) { Comp->CompressedOutput = (CompData_t *)CompressMalloc(sizeof(CompData_t), &Status); if (COMPRESS_OK == Status) Comp->PtrOutput = Comp->CompressedOutput; } else { Comp->CompressedOutput->next = (CompData_t *)CompressMalloc(sizeof(CompData_t), &Status); if (COMPRESS_OK == Status) Comp->CompressedOutput = Comp->CompressedOutput->next; } if (COMPRESS_OK != Status) { CompressFree(temp); return Status; } Comp->CompressedOutput->Data = temp; Comp->CompressedOutput->next = NULL; memcpy((char *)Comp->CompressedOutput->Data, Buffer, (int)Size); Comp->CompressedOutput->Size = (int)Size; return COMPRESS_OK; } /* ======================================================================== * Error translator. */ void TranslateErrorMsg( char *Message, CompressStatus_t ErrorCode ) { switch(ErrorCode) { case COMPRESS_OK: strcpy(Message, "This is not an error message."); break; case BAD_COMPRESSION_LEVEL: strcpy(Message, "Invalid compression level--valid values are 0-9."); break; case BAD_MAGIC_HEADER: strcpy(Message, "Bad magic header."); break; case BAD_COMPRESSED_DATA: strcpy(Message, "Bad compressed data."); break; case BAD_BLOCK_TYPE: strcpy(Message, "Invalid block type."); break; case BAD_CODE_LENGTHS: strcpy(Message, "Bad code lengths."); break; case BAD_INPUT: strcpy(Message, "Bad input--more codes than bits."); break; case EXTRA_BITS: strcpy(Message, "Too many bits."); break; case UNKNOWN_COMPRESSION_METHOD: strcpy(Message, "Unknown compression method."); break; case INCOMPLETE_CODE_SET: strcpy(Message, "Incomplete code set."); break; case END_OF_BLOCK: strcpy(Message, "End of block."); break; case BLOCK_VANISHED: strcpy(Message, "Block to compress disappeared--memory trashed."); break; case FORMAT_VIOLATED: strcpy(Message, "Invalid compressed data--format violated."); break; case CRC_ERROR: strcpy(Message, "Invalid compressed data--crc error."); break; case LENGTH_ERROR: strcpy(Message, "Invalid compressed data--length error."); break; case INSUFFICIENT_MEMORY: strcpy(Message, "Insufficient memory--ould not allocate space requested."); break; default: sprintf(Message, "Unknown error code %d", ErrorCode); } } /* ======================================================================== * Semi-safe malloc -- never returns NULL. */ void * CompressMalloc( unsigned int Size, CompressStatus_t *Status ) { void *DynamicSpace = malloc ((int)Size); if (DynamicSpace == NULL) *Status = INSUFFICIENT_MEMORY; else *Status = COMPRESS_OK; return DynamicSpace; } void CompressFree(void *Address) { free(Address); }