www.pudn.com > HuffmanForFile.zip > LZW15V.C


#include  
#include  
#include  
#include "errhand.h" 
#include "bitio.h" 
#include "main.h" 
 
#define BITS            15 
#define MAX_CODE        ( ( 1<>8 )+1 ) 
#define END_OF_STREAM   256 
#define BUMP_CODE       257 
#define FLUSH_CODE      258 
#define FIRST_CODE      259 
#define UNUSED          -1 
 
void InitializeDictionary(); 
void InitializeStorage(); 
unsigned int find_child_node( int parent_code,int child_character ); 
unsigned int decode_string( unsigned int offset,unsigned int code ); 
 
char * CompressionName="LZW 15 Bits Variable Rate Encode"; 
char * Usage="infile outfile\n\n"; 
 
struct dictionary{ 
   int code_value; 
   int parent_code; 
   char character; 
   } * dict[TABLE_BANKS]; 
 
#define DICT(i) dict[i>>8][i&0xff] 
 
char decode_stack[TABLE_SIZE]; 
unsigned int next_code; 
int current_code_bits; 
unsigned int next_bump_code; 
 
void InitializeDictionary() 
{ 
  unsigned int i; 
 
  for( i=0;iMAX_CODE ) { 
                 OutputBits( output,( unsigned long )FLUSH_CODE,current_code_bits ); 
                 InitializeDictionary(); 
               } 
             else if( next_code>next_bump_code ){ 
                      OutputBits( output,( unsigned long )BUMP_CODE,current_code_bits ); 
                      current_code_bits++; 
                      next_bump_code<<=1; 
                      next_bump_code|=1; 
                      putc( 'B',stdout ); 
                  } 
               } 
              } 
  OutputBits( output,( unsigned long )string_code,current_code_bits ); 
  OutputBits( output,( unsigned long )END_OF_STREAM,current_code_bits ); 
  while( argc-->0 ) 
         printf( "Unknown argunent:%s\n",* argv++ ); 
} 
 
void ExpandFile( BIT_FILE * input,FILE * output,int argc,char * argv[] ) 
{ 
  unsigned int new_code; 
  unsigned int old_code; 
  int character; 
  unsigned int count; 
 
  InitializeStorage(); 
  while( argc-->0 ) 
         printf( "Unknown argumenr:%s\n",* argv++ ); 
  for( ; ; ) { 
        InitializeDictionary(); 
        old_code=( unsigned int )InputBits( input,current_code_bits ); 
        if( old_code==END_OF_STREAM ) 
            return; 
        character=old_code; 
        putc( old_code,output ); 
        for( ; ; ) { 
             new_code=( unsigned int )InputBits( input,current_code_bits ); 
        if( new_code==END_OF_STREAM ) 
            return; 
        if( new_code==FLUSH_CODE ) 
            break; 
        if( new_code==BUMP_CODE ) { 
            current_code_bits++; 
            putc( 'B',stdout ); 
            continue; 
        } 
        if( new_code>=next_code ) { 
            decode_stack[0]=( char )character; 
            count=decode_string( 1,old_code ); 
            } 
        else 
            count=decode_string( 0,new_code ); 
        character=decode_stack[count-1]; 
        while( count>0 ) 
               putc( decode_stack[--count],output ); 
        DICT( next_code ).parent_code=old_code; 
        DICT( next_code ).character=( char )character; 
        next_code++; 
        old_code=new_code; 
        } 
     } 
} 
 
 
unsigned int find_child_node( int parent_code,int child_character ) 
{ 
  unsigned int index; 
  int offset; 
   
  index=( child_character<<( BITS-8 ) )^parent_code; 
  if( index==0 ) 
      offset=1; 
  else 
      offset=TABLE_SIZE-index; 
  for( ; ; ) { 
       if( DICT( index ).code_value==UNUSED ) 
           return( ( unsigned int )index ); 
       if( DICT( index ).parent_code==parent_code && 
           DICT( index ).character==( char )child_character ) 
           return( index ); 
       if( ( int )index>=offset ) 
           index-=offset; 
       else 
           index+=TABLE_SIZE-offset; 
       } 
} 
 
 
unsigned int decode_string( unsigned int count,unsigned int code ) 
{ 
  while( code>256 ){ 
         decode_stack[count++]=DICT( code ).character; 
         code=DICT( code ).parent_code; 
         } 
  decode_stack[count++]=( char )code; 
  return( count ); 
}