📄 hufftesc.c
字号:
return NULL ;
}
fibterms -= 2 ;
fibn1 = 1 ;
fibn = 2 ;
for( i = 2 ; ( fibterms > 0 ) && ( i < *n ) ; ) {
for( j = i ; j < ( ( ( i + fibn ) < *n ) ? ( i + fibn ) : *n ) ; j += 1 ) {
switch( datatype ) {
case BYTEDATA :
( ( unsigned char * )fib )[ j ] = ( unsigned char )fibn ;
break ;
case HWORDDATA :
( ( unsigned short * )fib )[ j ] = ( unsigned short )fibn ;
break ;
case WORDDATA :
( ( unsigned int * )fib )[ j ] = fibn ;
break ;
}
}
fibn = fibn + fibn1 ;
fibn1 = fibn - fibn1 ;
i = j ;
fibterms -= 1 ;
}
if( i < *n ) {
*n = i ;
}
printf( "A Fibonacci sequence has been created with %d entries.\n\n", *n ) ;
return fib ;
}
/**** GetSymbolsFromSymbolCount *****************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* get the array of sorted symbols from an array of structures of symbols and frequency of occurrence
* for each symbol
*
* Inputs
* ------
* symbolcountptr
* - an array of symbol count structures that references the sorted symbols and frequencies
* nSymbols
* - the number of structures referenced by the array given
* Return Values
* ------ ------
* void * - the created array of sorted symbols with nSymbols entries
* array is unsigned char, unsigned short or unsigned int data according to symbol type
* given in the structures and needs casting to the appropriate type before it can be used
* NULL - some error occurred (memory problems?)
*
* Memory allocated (not deallocated)
* ------ --------- --- -----------
* the returned array
* deallocate after use
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static void *GetSymbolsFromSymbolCount( SymbolCountPtr symbolcountptr, unsigned int nSymbols )
{
void *symbols ;
unsigned int i ;
if( ( symbolcountptr == NULL ) || ( nSymbols == 0 ) ) {
fprintf( stderr, "[GetSymbolsFromSymbolCount] Error in input arguments, aborting.\n\n" ) ;
/* function name given since intended as internal error for programmer */
return NULL ;
}
switch( symbolcountptr[ 0 ].symbol.symboltype ) {
case BYTE :
symbols = calloc( nSymbols, sizeof( unsigned char ) ) ;
break ;
case HWORD :
symbols = calloc( nSymbols, sizeof( unsigned short ) ) ;
break ;
case WORD :
symbols = calloc( nSymbols, sizeof( unsigned int ) ) ;
break ;
default :
fprintf( stderr, "[GetSymbolsFromSymbolCount] Error in input arguments, aborting.\n\n" ) ;
/* function name given since intended as internal error for programmer */
return NULL ;
}
if( symbols == NULL ) {
fprintf( stderr, "Cannot allocate memory for data, aborting.\n\n" ) ;
return NULL ;
}
for( i = 0 ; i < nSymbols ; i += 1 ) {
switch( symbolcountptr[ i ].symbol.symboltype ) {
case BYTE :
( ( unsigned char * )symbols )[ i ] = symbolcountptr[ i ].symbol.symbol.byte ;
break ;
case HWORD :
( ( unsigned short * )symbols )[ i ] = symbolcountptr[ i ].symbol.symbol.hword ;
break ;
case WORD :
( ( unsigned int * )symbols )[ i ] = symbolcountptr[ i ].symbol.symbol.word ;
break ;
default :
break ;
}
}
return symbols ;
}
/**** huff_main *********************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* initialise the application then loop whilst the user is still working
*
* Return Values
* ------ ------
* 0 - application terminated correctly
* 1 - some error occurred
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
int huff_main( int argc, char **argv )
{
unsigned int option ;
#ifdef __BIG_ENDIAN
char newStdIn[ ] = "stdinb" ;
char newStdOut[ ] = "stdoutb" ;
char newStdErr[ ] = "stderrb" ;
#else
char newStdIn[ ] = "stdinl" ;
char newStdOut[ ] = "stdoutl" ;
char newStdErr[ ] = "stderrl" ;
#endif
unsigned int stdio = 0 ;
if( ChangeStdIO( &argc, &argv, newStdIn, stdin ) == STDINID ) {
stdio |= ( 1 << STDINID ) ;
}
if( ChangeStdIO( &argc, &argv, newStdOut, stdout ) == STDOUTID ) {
stdio |= ( 1 << STDOUTID ) ;
}
if( ChangeStdIO( &argc, &argv, newStdErr, stderr ) == STDERRID ) {
stdio |= ( 1 << STDERRID ) ;
}
printf( "Program to perform Huffman encoding and decoding.\n\n" ) ;
while( 1 ) {
if( ( option = NextTask( HUFFMAN_OPTIONS, &Menu ) ) == 0 ) {
break ;
}
Code( option ) ;
}
/* redirection based on trying to open files that don't exist do using defaults */
if( stdio & ( 1 << STDINID ) ) {
ResetStdIO( stdin ) ;
}
if( stdio & ( 1 << STDOUTID ) ) {
ResetStdIO( stdout ) ;
}
if( stdio & ( 1 << STDERRID ) ) {
ResetStdIO( stderr ) ;
}
return 0 ;
}
/**** HuffmanDecode *****************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* decode a previously Huffman encoded bit stream to retrieve the original data before
* coding
*
* Inputs
* ------
* symbols
* - an array of symbols that occurred in the original data sorted into increasing order
* of frequency of occurrence
* the symbols should be unsigned char, unsigned short or unsigned int determined by datatype
* nSymbols
* - the number of symbols referenced by the array
* nOutputs
* - the number of symbols to retrieve from the encoded data
* this value is normally the number of symbols that have been encoded
* encodedBitStreamDataPtr
* - a pointer to a bit stream state structure that contains the bit stream to decode
* datatype
* - the type of the symbols and data to retrieve
* BYTEDATA byte-size data
* HWORDDATA halfword-size data
* WORDDATA word-size data
* freqCodeLen
* - an array of frequency of occurrence for each length of codeword
* maxcodewlen
* - the maximum length of codeword in the coded data
* (maxcodewlen+1) also defines the maximum index into the array freqCodeLen
* Return Values
* ------ ------
* void * - the decoded array of data
* array is unsigned char, unsigned short or unsigned int data according to datatype
* and needs casting to the appropriate type before it can be used
* NULL - some error occurred (memory problems?)
*
* Memory allocated (not deallocated)
* ------ --------- --- -----------
* the returned array
* deallocate after use
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static void *HuffmanDecode( void *symbols, unsigned int nSymbols, unsigned int nOutputs, BitStreamStatePtr encodedBitStreamDataPtr, unsigned int datatype, unsigned int freqCodeLen[ ], unsigned int maxcwlen )
{
BitStreamStatePtr bitStreamStatePtr ;
void *decoded ;
void *decodeTable ;
unsigned char *codedLengths ;
unsigned int nDecodes ;
unsigned int i ;
if( ( symbols == NULL ) || ( nSymbols == 0 ) || ( nOutputs == 0 ) || ( encodedBitStreamDataPtr == NULL ) || ( freqCodeLen == NULL ) || ( maxcwlen == 0 ) || ( maxcwlen > MAXCODEBITS ) ) {
fprintf( stderr, "[HuffmanDecode] Error in input arguments, aborting.\n\n" ) ;
/* function name given since intended as internal error for programmer */
return NULL ;
}
printf( "Initialising the Huffman stream for decoding...\n\n" ) ;
/* could dispose of encodedBitStreamDataPtr after creating decoding structure, however this is not done here */
if( ( bitStreamStatePtr = InitBitStreamStateDecoding( NULL, 0, encodedBitStreamDataPtr ) ) == NULL ) {
return NULL ;
}
printf( "Stream for decoding initialised.\n\n" ) ;
switch( datatype ) {
case BYTEDATA :
decoded = calloc( nOutputs, sizeof( unsigned char ) ) ;
break ;
case HWORDDATA :
decoded = calloc( nOutputs, sizeof( unsigned short ) ) ;
break ;
case WORDDATA :
decoded = calloc( nOutputs, sizeof( unsigned int ) ) ;
break ;
default :
fprintf( stderr, "[HuffmanDecode] Error in input arguments, aborting.\n\n" ) ;
decoded = NULL ;
}
if( decoded == NULL ) {
fprintf( stderr, "Cannot allocate memory for data, aborting.\n\n" ) ;
DisposeBitStreamStatePtr( bitStreamStatePtr ) ;
return NULL ;
}
printf( "Generating the Huffman decoding table and tree...\n\n" ) ;
switch( datatype ) {
case BYTEDATA :
decodeTable = MakeHuffDecodeTable8( ( unsigned char * )symbols, nSymbols, freqCodeLen, maxcwlen, TABLEBITS, &codedLengths ) ;
break ;
case HWORDDATA :
decodeTable = MakeHuffDecodeTable16( ( unsigned short * )symbols, nSymbols, freqCodeLen, maxcwlen, TABLEBITS, &codedLengths ) ;
break ;
case WORDDATA :
decodeTable = MakeHuffDecodeTable32( ( unsigned int * )symbols, nSymbols, freqCodeLen, maxcwlen, TABLEBITS, &codedLengths ) ;
break ;
default :
fprintf( stderr, "[HuffmanDecode] Error in input arguments, aborting.\n\n" ) ;
decodeTable = NULL ;
}
if( decodeTable == NULL ) {
DisposeBitStreamStatePtr( bitStreamStatePtr ) ;
free( decoded ) ;
return NULL ;
}
printf( "Huffman decoding table and tree generated.\n\n" ) ;
printf( "Huffman decoding the data...\n\n" ) ;
for( i = 0 ; i < CODECSPLIT ; i += 1 ) {
if( i == CODECSPLIT - 1 ) {
nDecodes = nOutputs - ( i * ( nOutputs/CODECSPLIT ) ) ;
}
else {
nDecodes = nOutputs/CODECSPLIT ;
}
switch( datatype ) {
case BYTEDATA :
bitStreamStatePtr = BitDecodeSymbols( bitStreamStatePtr, nDecodes, ( ( unsigned char * )decoded ) + ( i * ( nOutputs/CODECSPLIT ) ), codedLengths, decodeTable, datatype ) ;
break ;
case HWORDDATA :
bitStreamStatePtr = BitDecodeSymbols( bitStreamStatePtr, nDecodes, ( ( unsigned short * )decoded ) + ( i * ( nOutputs/CODECSPLIT ) ), codedLengths, decodeTable, datatype ) ;
break ;
case WORDDATA :
bitStreamStatePtr = BitDecodeSymbols( bitStreamStatePtr, nDecodes, ( ( unsigned int * )decoded ) + ( i * ( nOutputs/CODECSPLIT ) ), codedLengths, decodeTable, datatype ) ;
break ;
default :
break ;
}
}
printf( "Data has been Huffman decoded.\n\n" ) ;
free( decodeTable ) ;
free( ( void * ) codedLengths ) ;
DisposeBitStreamStatePtr( bitStreamStatePtr ) ;
return decoded ;
}
/**** HuffmanEncode *****************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* Huffman encode the given data to a bit stream
*
* Inputs
* ------
* inputs
* - an array of data to encode
* the data is unsigned char, unsigned short or unsigned int determined by datatype
* nInputs
* - the number of data items from the array to encode
* symbols
* - an array of symbols that occurred in the original data sorted into increasing order
* of frequency of occurrence
* the symbols should be unsigned char, unsigned short or unsigned int determined by datatype
* nSymbols
* - the number of symbols referenced by the array
* datatype
* - the type of the symbols and data to retrieve
* BYTEDATA byte-size data
* HWORDDATA halfword-size data
* WORDDATA word-size data
* freqCodeLen
* - an array of frequency of occurrence for each length of codeword
* maxcodewlen
* - the maximum length of codeword in the coded data
* (maxcodewlen+1) also defines the maximum index into the array freqCodeLen
* bitlength
* - a pointer to an unsigned int to hold the number of bits referenced by the bitstream returned
* Outputs
* -------
* bitlength
* - a pointer to the number of bits in the encoded stream returned
* undefined if NULL returned
* Return Values
* ------ ------
* BitStreamStatePtr - a pointer to a bit stream state structure that references the encoded stream
* NULL - some error occurred (memory problems?)
*
* Memory allocated (not deallocated)
* ------ --------- --- -----------
* the returned structure
* deallocate after use by DisposeBitStreamStatePtr
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static BitStreamStatePtr HuffmanEncode( void *inputs, unsigned int nInputs, void *symbols, unsigned int nSymbols, unsigned int datatype, unsigned int freqCodeLen[ ], unsigned int maxcwlen, unsigned int *bitlength )
{
unsigned int numberBytes ;
BitStreamStatePtr bitStreamStatePtr ;
unsigned int *encodeTable ;
unsigned int i ;
int cwlen ;
unsigned int nCodes ;
if( ( inputs == NULL ) || ( nInputs == 0 ) || ( symbols == NULL ) || ( nSymbols == 0 ) || ( freqCodeLen == NULL ) || ( maxcwlen == 0 ) || ( maxcwlen > MAXCODEBITS ) || ( bitlength == NULL ) ) {
fprintf( stderr, "[HuffmanEncode] Error in input arguments, aborting.\n\n" ) ;
/* function name given since intended as internal error for programmer */
return NULL ;
}
/* get maximum length of codeword in bits */
numberBytes = 0 ;
for( i = 1 ; i <= maxcwlen ; i += 1 ) {
numberBytes = ( ( freqCodeLen[ i ] > 0 ) ? i : numberBytes ) ;
}
/* assume all codewords of max length, then require following number of bits */
numberBytes *= nInputs ;
/* get nearest whole number of bytes to hold maximum number of bits */
numberBytes = ( ( numberBytes + 7 )/8 ) ;
if( ( bitStreamStatePtr = InitBitStreamStateCoding( numberBytes ) ) == NULL ) {
return NULL ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -