Recently studied the next LZW algorithm, but also read a lot of this information. LZW is suitable for text files, and for a slightly larger stream file, the compressed file is larger than the source file. LZW has many well-known implementation procedures, the following program to dynamically increase the number of digits as the starting point, using a hash table to achieve LZW compression. The hash algorithm has two, one is commented out by me, two can be used. Specifically which is good, I have not tested myself.
/**********************************************************************
***********************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define HASHSIZE 4096
#define CLEAR 256/* Clearance FLAG bit * *
#define TEMINATE 257
#define Not_used-1
#define MAXVAL (N) (1 << (n))-1
#define MAX_BITS 12
FILE *in;
FILE *out;
int bitsize = 9;
int Maxcode;
/* Dictionary Data structure * *
typedef struct prex_cha{
int value; /* Value * *
unsigned int prefix; /* String * *
unsigned int character; /* Append Letter * *
}hash_table;
Hash_table Hash_table[hashsize];
void initial_hashtable ()/* Dictionary initialization * *
{
int i;
for (i=0; i{
Hash_table[i].value = not_used;
}
}
/* Rewrite the data into bit stream output/*
void output (unsigned int code)
{
static int count = 0;
static unsigned long buffer = 0L; /*buffer for the defined storage byte buffer * *
buffer |= (unsigned Long) code << (32-bitsize-count);
count + = bitsize;
while (Count >= 8) /* If the buffer is greater than 8 then the top 8 */
{
fputc in the output (buffer > > 24,out);
buffer <<= 8;
count-= 8;
}
}
/*
int find_match (int prefix,unsigned int character)
{
int index;
int offset; /*offset for bias shift */
/* index = (character << 4) ^ prefix; /* Uses XOR to decide index*/
/* if (index = = 0)
{
offset = 1;
&NBSP}
else
{
offset = 5021-index;
.}
while (1)
{
if (hash_table[index].value = = not_used)
{
return (index);
}
if (hash_table[index].prefix = = Prefix && hash_table[index].character = = character)
{
return (index);
&NBSP;&NBSP
index = offset;
if (Index < 0)
{
index + = 5021;
&NBSP;&NBSP}
}
*/
int find_match (int prefix,unsigned int character)
{
int index;
index = prefix% 4096;
while (1)
{
if (Hash_table[index].value = = not_used)
{
return (index);
}
if (hash_table[index].prefix = = Prefix && hash_table[index].character = = character)
{
return (index);
}
index = index + 1;
if (index >= 4096)
{
index = index-4096;
}
}
}
void Lzwcompression ()
{
unsigned int prefix;
unsigned int character;
unsigned int index;
unsigned int next_code = 258; /* The label of the current dictionary * *
Initial_hashtable ();
prefix = fgetc (in);
while ((character = Fgetc (in))!= (unsigned) EOF)
{
index = Find_match (Prefix,character);
if (hash_table[index].value!= not_used)/* can find * *
{
prefix = hash_table[index].value;
}
Else
{
if (Next_code <= maxcode)/* cannot be found, is a new string, added to the table * *
{
Hash_table[index].value = next_code++;
Hash_table[index].character = character;
Hash_table[index].prefix = prefix;
}
Output (prefix);
prefix = character; /* suffix to prefix, ready for next input * *
/* Special sign, when the number of digits must be increased * *
if (Next_code > Maxcode)
{
if (Bitsize < 12)
{
Maxcode = Maxval (++bitsize);
}
else//* To reach 4096, you must clear the hash table, start again * *
{
Output (256); /* Output Clear flag to file * *
Initial_hashtable ();
Next_code = 258;
Bitsize = 9;
Maxcode = Maxval (bitsize);/*maxcode into 511*/
}
}
}/*if-else End *
}/*while End *
Output (prefix); /* Output the last one * *
if (Next_code = = Maxcode)
{/* If the last table of Maxcode is just right, you must add a bit to the number of digits.
++bitsize;
}
Output (257); /* Output END Mark * *
Output (0); /* To decode the use of * *
Output (0);
Output (0);
}
int main (int argc,char* argv[])
{
Char filename[255];
if (ARGC < 2)
{
printf ("usage:the command format is:lzw_compression <filename>!");
return (1);
}
if (in = fopen (Argv[1], "rb") = = NULL)
{
printf ("Cannot open input file-%s/n", argv[1]);
Exit (1);
}
strcpy (filename, argv[1]);
/* plus suffix. zzz, indicating a compressed file * * *
Strncat (FileName, ". zzz", 4);
if (out = fopen (filename, "wb") = = NULL)
{
printf ("Cannot open output file-%s/n", filename);
Fclose (in);
Exit (1);
}
Maxcode = Maxval (bitsize);
Lzwcompression ();
Fclose (in);
Fclose (out);
return 0;
}