/* DEC/CMS REPLACEMENT HISTORY, Element COMPRESS.C */ /* *1 14-NOV-1996 10:25:46 ANIGBOGU "[113914]Entry to compression/decompression library via Compress/Decompress" */ /* DEC/CMS REPLACEMENT HISTORY, Element COMPRESS.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/compress.c ** ** PURPOSE ** ** Compress/Decompress files with zip/unzip algorithm. ** ** SPECIAL REQUIREMENTS & NOTES ** ** AUTHOR ** ** J. C. Anigbogu ** Austin Systems Center ** Nov 1996 ** ****************************************************************************** */ /* Compress files with zip algorithm and 'compress' interface. * */ #include "comppriv.h" /* ======================================================================== * Check the magic number of the input buffer. * Return the compression method, -1 for error. */ int GetMethod( CompParam_t *Comp, CompressStatus_t *Status ) { char Magic[2]; /* magic header */ int Method; /* compression method */ Magic[0] = (char)GetByte(Comp); Magic[1] = (char)GetByte(Comp); Comp->HeaderBytes = 0; if (memcmp(Magic, GZIP_MAGIC, 2) == 0) { Method = (int)GetByte(Comp); if (Method != DEFLATED && Method != STORED) { *Status = UNKNOWN_COMPRESSION_METHOD; return -1; } (void)GetByte(Comp); /* Ignore flags */ (void)GetByte(Comp); /* Ignore stamp */ (void)GetByte(Comp); /* ,, */ (void)GetByte(Comp); /* ,, */ (void)GetByte(Comp); /* ,, */ (void)GetByte(Comp); /* Ignore extra flags for the moment */ (void)GetByte(Comp); /* Ignore OS type for the moment */ Comp->HeaderBytes = Comp->Index + 2*sizeof(long); /* include crc and size */ } else { *Status = BAD_MAGIC_HEADER; return -1; } return Method; } /* ======================================================================== * Compress input */ CompressStatus_t Compress( unsigned char *Input, unsigned int InputSize, unsigned char **Output, unsigned int *OutputSize, unsigned int Level /* compression level */ ) { int Length; CompData_t *Ptr; CompParam_t *Comp; CompressStatus_t Status; Comp = (CompParam_t *)CompressMalloc(sizeof(CompParam_t), &Status); if (Status != COMPRESS_OK) return Status; Crc32 crcGenerator(0); // for backward compatibility Comp->pCRC = &crcGenerator; Length = FillBuffer(Input, InputSize, Comp); /* Do the compression */ if ((Status = Zip((int)Level, Comp)) != COMPRESS_OK) { CompressFree(Comp); return Status; } *OutputSize = Comp->BytesOut; *Output = (unsigned char *)CompressMalloc(*OutputSize, &Status); if (Status != COMPRESS_OK) { CompressFree(Comp); return Status; } Length = 0; while (Comp->PtrOutput != NULL) { Ptr = Comp->PtrOutput; memcpy((char *)*Output+Length, (char *)Comp->PtrOutput->Data, Comp->PtrOutput->Size); Length += Comp->PtrOutput->Size; Comp->PtrOutput = Comp->PtrOutput->next; CompressFree(Ptr->Data); CompressFree(Ptr); } CompressFree(Comp); return COMPRESS_OK; } /* ======================================================================== * Decompress input */ CompressStatus_t Decompress( unsigned char *Input, unsigned int InputSize, unsigned char **Output, unsigned int *OutputSize ) { int Length; int Method; CompData_t *Ptr; CompParam_t *Comp; CompressStatus_t Status; Comp = (CompParam_t *)CompressMalloc(sizeof(CompParam_t), &Status); if (Status != COMPRESS_OK) return Status; Crc32 crcGenerator(0); // for backward compatibility Comp->pCRC = &crcGenerator; Length = FillBuffer(Input, InputSize, Comp); /* Do the decompression */ Method = GetMethod(Comp, &Status); if (Status != COMPRESS_OK) { CompressFree(Comp); return Status; } if ((Status = Unzip(Method, Comp)) != COMPRESS_OK) { CompressFree(Comp); return Status; } *OutputSize = Comp->BytesOut; *Output = (unsigned char *)CompressMalloc(*OutputSize, &Status); if (Status != COMPRESS_OK) { CompressFree(Comp); return Status; } Length = 0; while (Comp->PtrOutput != NULL) { Ptr = Comp->PtrOutput; memcpy((char *)*Output+Length, (char *)Comp->PtrOutput->Data, Comp->PtrOutput->Size); Length += Comp->PtrOutput->Size; Comp->PtrOutput = Comp->PtrOutput->next; CompressFree(Ptr->Data); CompressFree(Ptr); } CompressFree(Comp); return COMPRESS_OK; }