⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdecompress.cpp

📁 bt848,bt878 a采集卡的探测
💻 CPP
字号:
// Our C decompressor - Uses LZW compression taken from 
#include "CDecompress.hpp"

// a tutorial on ftp://x2ftp.oulu.fi (or ftp://cdrom.com/x2ftp mirror)

/* File: dcodlzw.c
   Author: David Bourgin
   Creation date: 25/3/95
   Last update: 12/10/95
   Purpose: Example of LZW decoding with a file source to decompress.
*/


/* Pseudo procedures. */
#define end_of_data() (blk_ptr >= blk_ptr_end)
#define read_byte()  *blk_ptr++
#define write_byte(byte) do { unsigned char Byte=(byte); outblk->ReSize(outblk->Size()+1); ((unsigned char*)outblk->Ptr())[outblk->Size()-1] = Byte; } while(0) 
 
#define LINK_CHAR(dic)  ((*(dic)).character)
#define LINK_PRED(dic)  ((*(dic)).predecessor)

#define TYPE_GIF_ENCODING
/* Enforces including marker codes initialization_code et end_information_code.
   To invalid this option, set the line #define... in comments. */
#ifdef TYPE_GIF_ENCODING
#define AUTO_REINIT_DIC
/* If this macro is defined, the dictionary is always increased
   (even if this can make an error of overflow!).
   At the opposite, if this macro is undefined, the dictionary is no more updated
   as soon as it reaches its maximal capacity. The reception of the code
   'initialization_code' will enforce the dictionary to by flushed.
   To invalid this option, set the line #define... in comments.
   This macro is considered only if TYPE_GIF_ENCODING is defined,
   that is why we have the lines #ifdef... and #endif... */
#endif

bool CDecompress::init_dictionary1()
/* Returned parameters: None.
   Action: First initialization of the dictionary when we start an decoding.
   Errors: None if there is enough room.
*/
{	
	register unsigned int i;

	index_dic_max=1<<EXP2_DIC_MAX;       /* Attention: Possible values: 2^3 to 2^EXP2_DIC_MAX */
	output_bit_counter=8;				/* Attention: Possible values: 1 to EXP2_DIC_MAX-1
											(usually, for pictures, set up to 1, or 4, or 8, in the case
											of monochrome, or 16-colors, or 256-colors picture). */
	if (output_bit_counter==1)
		bit_counter_min_decoding=3;
	else 
		bit_counter_min_decoding=output_bit_counter+1;
	initialization_code=1<<(bit_counter_min_decoding-1);
#ifdef TYPE_GIF_ENCODING
	end_information_code=initialization_code+1;
#else
	end_information_code=initialization_code-1;
#endif
	for (i=0;i<index_dic_max;i++) {
		if ((dictionary[i]=(p_dic_link)malloc(sizeof(t_dic_link)))==NULL) { 
			while (i) { 
				i--;
				free(dictionary[i]);
			}
			return false;
		}
		if (i<initialization_code)
			LINK_CHAR(dictionary[i])=i;
		LINK_PRED(dictionary[i])=NULL;
	}
	index_dic=end_information_code+1;
	bit_counter_decoding=bit_counter_min_decoding;
	return true;
}

bool CDecompress::init_dictionary2()
/* Returned parameters: None.
   Action: Initialization of the dictionary during the decoding.
   The dictionary must have been initialized once by 'init_dictionary1'.
   Errors: None.
*/
{ 
	register unsigned int i;

	for (i=initialization_code;(i<index_dic_max)&&(dictionary[i]!=NULL);i++)
		LINK_PRED(dictionary[i])=NULL;
	index_dic=end_information_code+1;
	bit_counter_decoding=bit_counter_min_decoding;
	return true;
}

void CDecompress::remove_dictionary()
/* Returned parameters: None.
   Action: Removes the dictionary used for the decoding from the dynamical memory.
   Errors: None.
*/
{ 
	register unsigned int i;
	for (i=0;(i<index_dic_max)&&(dictionary[i]!=NULL);i++)
		free(dictionary[i]);
}

void CDecompress::write_output(unsigned int value)
/* Returned parameters: None.
   Action: Writes 'output_bit_counter' via the function write_byte.
   Errors: An input/output error could disturb the running of the program.
*/
{ 
	val_to_write=(val_to_write << output_bit_counter) | value;
	bit_counter_to_write += output_bit_counter;
	while (bit_counter_to_write>=8) { 
		bit_counter_to_write -= 8;
		write_byte((unsigned char)(val_to_write >> bit_counter_to_write));
		val_to_write &= ((1<< bit_counter_to_write)-1);
	}
}

void CDecompress::complete_output()
/* Returned parameters: None.
   Action: Fills the last byte to write with 0-bits, if necessary.
   This procedure is to be considered aith the procedure 'write_output'.
   Errors: An input/output error could disturb the running of the program.
*/
{ 
	if (bit_counter_to_write>0)
		write_byte((unsigned char)(val_to_write << (8-bit_counter_to_write)));
	val_to_write=bit_counter_to_write=0;
}

void CDecompress::write_link(
	p_dic_link chainage,
	unsigned int *character )
/* Returned parameters: 'character' can have been modified.
   Action: Sends the string in the output stream given by the 'link' of the LZW dictionary.
   'character' contains to the end of the routine the first character of the string.
   Errors: None (except a possible overflow of the operational stack allocated
   by the program, which must allows at least 8*INDEX_DIC_MAX bytes, corresponding
   to an exceptional case.
*/
{ 
	if (LINK_PRED(chainage)!=NULL) { 
		write_link(LINK_PRED(chainage),character);
		write_output(LINK_CHAR(chainage));
	} else { 
		write_output(LINK_CHAR(chainage));
		*character=LINK_CHAR(chainage);
	}
}

unsigned int CDecompress::write_string(
	unsigned int pred_code, unsigned int current_code,
	unsigned int first_char)
/* Returned parameters: Returns a byte.
   Action: Writes the string of bytes associated to 'current_node' and returns
   the first character of this string.
   Errors: None.
*/
{ 
	unsigned int character;

	if (current_code<index_dic)
		write_link(dictionary[current_code],&character);
	else { 
		write_link(dictionary[pred_code],&character);
		write_output(first_char);
	}
	return character;
}

void CDecompress::add_string(
	unsigned int code,
	unsigned int first_char)
/* Returned parameters: None.
   Action: Adds the string given by 'code' to the dictionary.
   Errors: None.
*/
{
	LINK_CHAR(dictionary[index_dic])=first_char;
	LINK_PRED(dictionary[index_dic])=dictionary[code];
	index_dic++;
	if (index_dic+1==(unsigned int)(1<<bit_counter_decoding))
		bit_counter_decoding++;
}

unsigned int CDecompress::read_code_lr()
/* Returned parameters: Returns the value of code.
   Action: Returns the value coded on 'bit_counter_decoding' bits from the stream of input codes.
   The bits are stored from left to right. Example: aaabbbbcccc is written:
   Bits     7 6 5 4 3 2 1 0
   Byte 1   a a a b b b b c
   Byte 2   c c c ? ? ? ? ?
   Errors: An input/output error could disturb the running of the program.
*/
{ 
	unsigned int read_code;

	while (bit_counter_to_read<bit_counter_decoding) { 
		val_to_read=(val_to_read<<8)|read_byte();
		bit_counter_to_read += 8;
	}
	bit_counter_to_read -= bit_counter_decoding;
	read_code=val_to_read>>bit_counter_to_read;
	val_to_read &= ((1<<bit_counter_to_read)-1);
	return read_code;
}

unsigned int CDecompress::write_code_rl()
/* Returned parameters: Returns the value of code.
   Action: Returns the value coded on 'bit_counter_decoding' bits from the stream of input codes.
   The bits are stored from right to left. Example: aaabbbbcccc is written:
   Bits     7 6 5 4 3 2 1 0
   Byte 1   c b b b b a a a
   Byte 2   ? ? ? ? ? c c c
   Errors: An input/output error could disturb the running of the program.
*/
{ 
	unsigned int read_code;

	while (bit_counter_to_read<bit_counter_decoding) { 
		val_to_read |= ((unsigned long int)read_byte())<<bit_counter_to_read;
		bit_counter_to_read += 8;
	}
	bit_counter_to_read -= bit_counter_decoding;
	read_code=val_to_read & ((1<<bit_counter_decoding)-1);
	val_to_read >>= bit_counter_decoding;
	return read_code;
}

bool CDecompress::lzwdecoding()
/* Returned parameters: None.
   Action: Compresses with LZW method all bytes read by the function 'read_code_??'.
   (where '??' is 'lr' or 'rl', depending on how you stored the bits in the compressed stream.
   Errors: An input/output error could disturb the running of the program.
*/
{ 
	unsigned int pred_code = 0,current_code;
	unsigned int first_char = 0;

	// (re)init all variables
	val_to_write=0;
	val_to_read=0;
	bit_counter_to_write=0;
	bit_counter_to_read=0;

	if (!end_of_data()) { 
		if (!init_dictionary1()) 
			return false;
		current_code=read_code_lr();
#ifdef TYPE_GIF_ENCODING
		if (current_code!=initialization_code) { 
			remove_dictionary();
			return false;
		}
		if ((current_code=read_code_lr())<initialization_code) { 
			first_char=write_string(pred_code,current_code,first_char);
            pred_code=current_code;
            current_code=read_code_lr();
		}
		while (current_code!=end_information_code) { 
			if (current_code==initialization_code) { 
				if (!init_dictionary2())
					return false;
				current_code=read_code_lr();
				if (current_code<initialization_code) { 
					first_char=write_string(pred_code,current_code,first_char);
					pred_code=current_code;
					current_code=read_code_lr();
				}
			} else { 
				if (current_code>index_dic) { 
					return false;
				}
#ifdef AUTO_REINIT_DIC
				if (index_dic==index_dic_max) { 
					return false;
				}
				first_char=write_string(pred_code,current_code,first_char);
				add_string(pred_code,first_char);
				pred_code=current_code;
				current_code=read_code_lr();
#else
				first_char=write_string(pred_code,current_code,first_char);
				if (index_dic<index_dic_max)
					add_string(pred_code,first_char);
				pred_code=current_code;
				current_code=read_code_lr();
#endif
			}
		}
		remove_dictionary();
#else
		pred_code=current_code;
		first_char=write_string(pred_code,current_code,first_char);
		while ((!end_of_data())||(bit_counter_to_read>=bit_counter_decoding)) { 
			current_code=read_code_lr();
			if (current_code>index_dic) { 
				return false;
			}
			first_char=write_string(pred_code,current_code,first_char);
			if (index_dic==index_dic_max-2) { 
				init_dictionary2();
				if ((!end_of_data())||(bit_counter_to_read>=bit_counter_decoding)) { 
					pred_code=(current_code=read_code_lr());
					first_char=write_string(pred_code,current_code,first_char);
				}
			}
			else 
				add_string(pred_code,first_char);
			pred_code=current_code;
		}
		remove_dictionary();
#endif
		complete_output();
	}
	return true;
}

bool CDecompress::Decompress(CMemory& mem,CMemory& out)
{
	// Set Size to 0
	outblk = &out;
	outblk->ReSize(0);
	// Load input pointers.
	blk_ptr = (unsigned char*)mem.Ptr();
	blk_ptr_end = blk_ptr + mem.Size();
	// Decompress
	return lzwdecoding();
}
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -