Lzw解压缩算法完整代码
/*============================================================================
Name : Exercise.cbp
Author : Haier
Version : 1.01
Copyright : Copyright (c) 2014
Description : LZE DeCompress in C, Ansi-style, Compile by Code::Block
============================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BITS (12)
#define HASHSHIFT (BITS-8)
#define MAXVALUE ((1<<BITS)-1)
#define MAXCODE (MAXVALUE-1)
#define TABLESIZE (4099)
struct Lzw
{
int *code; //已被编码
int *prefix; //编码索引
char *suffix; //对应字符
}Lzw,*lp;
char dectable[TABLESIZE];
/****************************************************************************
* Function : incode
* Description : acquire for the prefix
* Input : The File of Input
* Return : prefix
*****************************************************************************/
int incode(FILE *InputFile)
{
static int ib=0;
static unsigned long ibb=0L;
int prefix;
while(ib<=24)
{
ibb |=(unsigned)getc(InputFile)<<(24-ib);
ib +=8;
}
prefix=ibb>>(32-BITS);
ibb <<=BITS;
ib -=BITS;
return prefix;
}
/****************************************************************************
* Function : decode
* Description : decode for the index
* Input : the index,the characters buffer
* Return : the characters buffer
*****************************************************************************/
char *decode(char *buffer,int index)
{
int BoundaryFlag=0;
while(index>257)
{
*buffer++=lp->suffix[index];
index=lp->prefix[index];
if(BoundaryFlag++>TABLESIZE)
{
printf("The EMS memory spill over !");
exit(1);
}
}
*buffer=index;
return buffer;
}
/****************************************************************************
* Function : Common
* Description : handle after failing to open file
* Input : Filename
* Return : void
*****************************************************************************/
void Common(char *FileName)
{
char TempFileName[25];
strcpy(TempFileName,"Can't open ");
strcat(TempFileName,FileName);
puts(TempFileName);
exit(1);
}
/****************************************************************************
* Function : DeCompress
* Description : Lzw DeCompress Algorithm
* Input : FileName of input ,FileName of Output
* Return : void
*****************************************************************************/
void DeCompress(FILE *InputFile,FILE *OutputFile)
{
int prefix,suffix,ccode=258;
char TempChar,*CodeWord;
Lzw.code =malloc(TABLESIZE*sizeof(int));
Lzw.prefix=malloc(TABLESIZE*sizeof(int));
Lzw.suffix=malloc(TABLESIZE*sizeof(char));
if(Lzw.code==NULL || Lzw.prefix==NULL || Lzw.suffix==NULL)
{
printf("The EMS memory spill over !");
exit(1);
}
lp=&Lzw;
prefix=incode(InputFile);
TempChar=prefix;
putc(prefix,OutputFile);
while((suffix=incode(InputFile))!=MAXVALUE)
{
if(suffix>=ccode)
{
*dectable=TempChar;
CodeWord =decode(dectable+1,prefix);
}
else
{
CodeWord =decode(dectable,suffix);
TempChar =*CodeWord;
}
while(CodeWord>=dectable)
{
putc(*CodeWord--,OutputFile);
}
if(ccode<=MAXCODE)
{
lp->prefix[ccode]=prefix;
lp->suffix[ccode]=TempChar;
ccode++;
}
prefix=suffix;
}
free(lp->code);
free(lp->prefix);
free(lp->suffix);
}
/****************************************************************************
* Function : main
*****************************************************************************/
int main(int argc,char *argv[])
{
FILE *FileOfInput,*FileOfOutput;
if(argc!=3)
{
printf("Usage: DeCompress FileInput FileOutput !");
exit(1);
}
if((FileOfInput=fopen(argv[1],"rb"))==NULL)
{
Common(argv[1]);
}
if((FileOfOutput=fopen(argv[2],"wb"))==NULL)
{
Common(argv[2]);
}
DeCompress(FileOfInput,FileOfOutput);
fclose(FileOfInput);
fclose(FileOfOutput);
return 0;
}