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

📄 huffcompress.c

📁 经典远程控制代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

	// Encode the Input Data
	__asm
	{
		// Point to the Source Data
		MOV		ESI,pInput

		// Set the Loop Count
		MOV		EDX,dwCount
		MOV		dwLoop,EDX

		// Point to the Codes Array
		MOV		EDX,pCodes

		// Clear the Count of Used Bits
		MOV		EDI,0

		// Main Loop for Reading Bytes
		_LoopInput:

		// Clear the EAX Register for the Input Character
		MOV		EAX,0

		// Read the Input Byte and Increment the Input Pointer
		LODSB

		// Get the Compression Code (Bytes 0 - 255 in Array)
		MOV		EBX,[EDX + EAX * 4]

		// Get the Compression Code Bit Count (Bytes 256 - 511 in Array)
		MOV		ECX,[EDX + 1024 + EAX * 4]

		// See How Many Bits Can be Shifted to the Output DWORD
		ADD		EDI,ECX
		CMP		EDI,32
		JLE		_ShiftBits

		// See How Many Bits of the Last Code Can't Be Used
		SUB		EDI,32

		// Adjust ECX to Handle only the Bits that Can Be Used
		SUB		ECX,EDI

		// Set the Output Flag
		MOV		fOutput,TRUE

		// Start the Bit Shifting
		_ShiftBits:

		// Check for Outputting a full DWORD
		CMP		fOutput,FALSE
		JE		_Continue

		// Increment the Compression Count
		ADD		dwNewCount,4

		// Remove the Bits we Used
		MOV		EAX,32
		SUB		EAX,EDI
		MOV		ECX,EAX

		// Reset the Output Flag
		MOV		fOutput,FALSE

		// Decrement the Main Loop Counter
		_Continue:
		DEC		dwLoop
		JNZ		_LoopInput

		// Update Any Remaining Compression data in the Buffer
		CMP		EDI,0
		JE		_Exit

		// Left Shift the Remaining Bits
		MOV		EAX,32
		SUB		EAX,EDI
		MOV		ECX,EAX

		// Increment the Compression Count
		ADD		dwNewCount,4

		// Finished Compressing the Input Data
		_Exit:
	}

	// Return the Compression Count
	return dwNewCount;
}

// Compress the Count of Input Data to Output Data returning the new Count
DWORD HuffmanCompress(BYTE *pInput,DWORD dwCount,WORD iTreeSize,DWORD *pByteTree,DWORD *pCodes,BYTE *pOutput)
{
	// Allocation Variables
	BYTE	*pStartInput = pInput;
	BYTE	*pStartOutput = pOutput;

	// Variables Used for Code Shifting
	DWORD	dwUnusedByte = 0;
	BOOL	fOutput = FALSE;

	// Compressed Size with Initial Space for Codes
	DWORD	dwNewCount = 0;

	// Loop Variable
	DWORD	dwLoop;

	// Get the Tree Size and Table Storage Requirement
	__asm
	{
		// Get the Table Storage
		MOV		EAX,0
		MOV		AX,iTreeSize
		MOV		wTreeSize,AX
		SHL		EAX,2
		MOV		dwStorage,EAX
	}

	// Encode the Input Data
	__asm
	{
		// Point to the Destination Data
		MOV		EDI,pOutput

		// Store the UnCompressed Count
		MOV		EAX,dwCount
		MOV		[EDI],EAX

		// Move Past the UnCompressed Count
		ADD		EDI,4

		// Move in the Number of Codes to the Output
		MOV		ECX,0
		MOV		CX,wTreeSize
		MOV		[EDI],CX

		// Move Past the Number of Codes
		ADD		EDI,2

		// Initialize the Base Storage Requirement
		MOV		EDX,dwStorage
		MOV		dwNewCount,EDX

		// Add 6 for the DWORD and WORD that Stores the UnCompressed Count and Number of Tree Entries
		ADD		dwNewCount,6

		// Adjust the Start of the Output Compressed Data, Skipping Byte Tree
		SHR		EDX,1
		ADD		EDI,EDX

		// Store the Pointer to the Output
		MOV		pOutput,EDI

		// Set the Loop Count
		MOV		EDX,dwCount
		MOV		dwLoop,EDX

		// Point to the Codes Array
		MOV		EDX,pCodes

		// Clear the Count of Used Bits
		MOV		EDI,0

		// Initialize the Storage DWORD
		XOR		ESI,ESI

		// Main Loop for Reading Bytes
		_LoopInput:

		// Clear the EAX Register for the Input Character
		MOV		EAX,0

		// Save the ESI Register
		PUSH	ESI

		// Point to the Source Data
		MOV		ESI,pInput

		// Read an Input Byte
		MOV		AL,[ESI]

		// Increment the Pointer to the Source Data
		INC		ESI

		// Store the Pointer to the Source Data
		MOV		pInput,ESI

		// Restore the ESI Register
		POP		ESI

		// Get the Compression Code (Bytes 0 - 255 in Array)
		MOV		EBX,[EDX + EAX * 4]

		// Get the Compression Code Bit Count (Bytes 256 - 511 in Array)
		MOV		ECX,[EDX + 1024 + EAX * 4]

		// See How Many Bits Can be Shifted to the Output DWORD
		ADD		EDI,ECX
		CMP		EDI,32
		JLE		_ShiftBits

		// See How Many Bits of the Last Code Can't Be Used
		SUB		EDI,32

		// Adjust ECX to Handle only the Bits that Can Be Used
		SUB		ECX,EDI

		// Save the Code
		MOV		dwUnusedByte,EBX

		// Shift the Input Symbol to the Right
		PUSH	ECX
		MOV		ECX,EDI
		SHR		EBX,CL
		POP		ECX

		// Set the Output Flag
		MOV		fOutput,TRUE

		// Start the Bit Shifting
		_ShiftBits:

		// Shift the Output Symbol to Handle a New Symbol
		SHL		ESI,CL

		// OR the Output Symbol with New Symbol
		OR		ESI,EBX

		// Check for Outputting a full DWORD
		CMP		fOutput,FALSE
		JE		_Continue

		// Output an Encoded Symbol
		MOV		EAX,ESI
		PUSH	EDI
		MOV		EDI,pOutput
		MOV		[EDI],EAX
		POP		EDI
		ADD		pOutput,4

		// Increment the Compression Count
		ADD		dwNewCount,4

		// Remove the Bits we Used
		MOV		EAX,32
		SUB		EAX,EDI
		MOV		ECX,EAX

		// Restore the Unused Portion of the Code
		MOV		EAX,dwUnusedByte
		SHL		EAX,CL
		SHR		EAX,CL

		// Update the Code to Have the Left Over Bits
		MOV		ESI,EAX

		// Initialize the Left Over Bits
		MOV		dwUnusedByte,0

		// Reset the Output Flag
		MOV		fOutput,FALSE

		// Decrement the Main Loop Counter
		_Continue:
		DEC		dwLoop
		JNZ		_LoopInput

		// Update Any Remaining Compression data in the Buffer
		CMP		EDI,0
		JE		_Exit

		// Left Shift the Remaining Bits
		MOV		EAX,32
		SUB		EAX,EDI
		MOV		ECX,EAX
		SHL		ESI,CL

		// Output the Final Encoded Symbol
		MOV		EAX,ESI
		MOV		EDI,pOutput
		MOV		[EDI],EAX

		// Increment the Compression Count
		ADD		dwNewCount,4

		// Finished Compressing the Input Data
		_Exit:
	}

	// Set the Start of the Byte Tree
	pOutput = pStartOutput + 6;

	// Copy the DWORD Byte Tree to a WORD Byte Tree
	D2W(&wByteTree[0],pByteTree,dwStorage/4);

	// Copy the Byte Tree
	memblast(pOutput,&wByteTree[0],dwStorage/2);
	
	// Restore the Pointer to the Start of the Input
	pInput = pStartInput;

	// Restore the Pointer to the Start of the Output
	pOutput = pStartOutput;

	// Return the Compression Count
	return dwNewCount;
}

// Get the UnCompressed Count of Output Data
DWORD HuffmanGetSize(BYTE *pInput)
{
	DWORD	dwUnCount;

	__asm
	{
		// Point to the Source Data
		MOV		ESI,pInput

		// Get the UnCompressed Count
		MOV		EAX,[ESI]
		MOV		dwUnCount,EAX
	}

	// Return the UnCompressed Count
	return dwUnCount;
}

// UnCompress the Compressed Count of Input Data to Output Data returning the UnCompressed Count
DWORD HuffmanUnCompress(BYTE *pInput,BYTE *pOutput)
{
	// UnCompressed Count
	DWORD	dwUnCount;

	// Allocation Variables
	BYTE	*pStartInput = pInput;
	BYTE	*pStartOutput = pOutput;

	// UnCompressed Variables
	DWORD	dwLoop;

	// Initialize the Weights Array
	HuffmanInitArrays();

	// Copy the Decoding Dictionary
	__asm
	{
		// Point to the Source Data
		MOV		ESI,pInput

		// Get the UnCompressed Count
		MOV		EAX,[ESI]
		MOV		dwUnCount,EAX

		// Move Past the Uncompressed Count
		ADD		ESI,4

		// Get the Tree Size
		MOV		EAX,0
		MOV		AX,[ESI]
		MOV		wTreeSize,AX

		// Increment the Pointer to the Encoded Data
		ADD		ESI,2

		// Store the Start of the Compressed Data
		MOV		pInput,ESI

		// Compute the Root Index
		MOV		dwRootIndex,EAX
		SUB		dwRootIndex,3

		// Compute the Table Storage Requirement
		SHL		EAX,2
		MOV		dwStorage,EAX
	}

	// Copy the Decoding Byte Tree
	memblast(&wByteTree[0],pInput,dwStorage/2);

	// Convert the WORD Byte Tree to a DWORD Byte Tree
	W2D(&dwByteTree[0],&wByteTree[0],dwStorage/4);

	// Decode the Input Data
	__asm
	{
		// Increment the Pointer to the Data
		MOV		EAX,dwStorage
		SHR		EAX,1
		ADD		pInput,EAX

		// Point to the Byte Code Tree
		MOV		ESI,OFFSET dwByteTree[0]

		// Set the Loop Count for Amount of Bytes to Uncompress
		MOV		EDX,dwUnCount
		MOV		dwLoop,EDX

		// Calculate the Index of the Root
		MOV		EBX,dwRootIndex

		// Main Loop for Reading Bytes
		_LoopInput:

		// Point to the Source Data
		MOV		EDI,pInput

		// Read a DWORD of Encoded Data
		MOV		ECX,[EDI]

		// Increment the Source Data Pointer by a DWORD
		ADD		pInput,4

		// Initialize the Number of Bits to Process
		MOV		EAX,32

		// Left Shift the Encoded Data 1 Bit at a Time
		_LeftShift:

		// Initialize the Decode Storage
		MOV		EDX,0

		// Left Shift the Code into the Decode Storage
		SHL		ECX,1

		// Bit + 1 = Number of Children, ie The Direction in Tree to Move
		ADC		EDX,1

		// Index the Child of the Parent
		ADD		EBX,EDX

		// Decrement the Bits Processed
		DEC		EAX

		// Check for a Leaf Node
		MOV		EDI,[ESI + EBX * 4]
		CMP		EDI,256
		JLE		_LeafNode

		// Index the Child's Parent
		MOV		EDI,EBX
		SUB		EDI,EDX

		// Match the Child to a Parent
		_TestParent:

 		// Index the Previous Parent in the Tree
		SUB		EDI,3

		// Get the Child's Parent
		MOV		EDX,[ESI + EDI * 4]

		// Compare the Parent with the Child
		CMP		EDX,[ESI + EBX * 4]
		JNE		_TestParent

		// Update the Parent Index
		MOV		EBX,EDI

		// Check the Bits Processed upto this Point
		CMP		EAX,0

		// Check for More Bits to Process
		JNZ		_LeftShift

		// Read in another DWORD
		JMP		_LoopInput

		// Output a Decoded Symbol
		_LeafNode:

		// Point to the Destination Data
		MOV		EDI,pOutput

		// Output the Code
		MOV		EDX,[ESI + EBX * 4]
		MOV		[EDI],DL

		// Increment the Destination Data by 1 Byte
		INC		pOutput

		// Calculate the Index of the Root
		MOV		EBX,dwRootIndex

		// Decrement the Loop Counter
		DEC		dwLoop
		JZ		_Exit

		// Check for More Bits to Process
		CMP		EAX,0
		JNZ		_LeftShift

		// Read a New DWORD
		JMP		_LoopInput

		// Finished Decompressing
		_Exit:
	}

	// Restore the Pointer to the Start of the Input
	pInput = pStartInput;

	// Restore the Pointer to the Start of the Output
	pOutput = pStartOutput;

	// Return the Count of UnCompressed Data
	return dwUnCount;
}

// Copy a DWORD Array to a WORD Array
void D2W(void* dest,void* src,DWORD count)
{
	__asm
	{
		MOV		ESI,src		// Copy the Source Address to the Register
		MOV		EDI,dest	// Copy the Destination to the Register
		MOV		ECX,count	// Copy the Count to the Register

		_CopyD2W:
		MOV		EAX,[ESI]
		MOV		[EDI],AX
		ADD		ESI,4
		ADD		EDI,2
		DEC		ECX
		JNZ		_CopyD2W
	}
}

// Copy a WORD Array to a DWORD Array
void W2D(void* dest,void* src,DWORD count)
{
	__asm
	{
		MOV		ESI,src		// Copy the Source Address to the Register
		MOV		EDI,dest	// Copy the Destination to the Register
		MOV		ECX,count	// Copy the Count to the Register

		XOR		EAX,EAX
		_CopyW2D:
		MOV		AX,[ESI]
		MOV		[EDI],EAX
		ADD		ESI,2
		ADD		EDI,4
		DEC		ECX
		JNZ		_CopyW2D
	}
}

⌨️ 快捷键说明

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