Location: PHPKode > scripts > Huffman Compress > huffman-compress/expand.inc.php
<?

/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+	HUFFMAN STATIC COMPRESSION
+	A PHP Implementation
+
+	by Exaton (hide@address.com)
+
+	Released as Freeware.
+	Use & modify as you see fit, no guarantee provided.
+
+	See README file for version info.
+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/

/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+	expand.inc.php
+
+	You only have to include this file in order to expand a file.
+
+	Use :
+
+	$expander = new CPRS_Expand();
+	$expander -> SetFiles("path/to/input/file", "path/to/output/file");
+	$expander -> Expand();
+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/

// Inclusions

include_once("compresslib.inc.php");

// Class definition

class CPRS_Expand extends CPRS
{
	var $icarrier;		// Carrier window for reading from input
	var $icarlen;		// Lenght of the input carrier at any given time
	
	var $ofsize;		// Size of the output file, in bytes
	
	var $ttlnodes;		// For use in Huffman Tree reconstruction

/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/

/*#############################################################################
#
#	Expansion functions
#
#############################################################################*/

/******************************************************************************
*
*	Reconstruct the Huffman tree transmitted in header
*
******************************************************************************/

// Inner cross-recursive function

function ReadTPForChild($par, $child, $childid, $charin)
{
	// Creating child, setting right parent and right child for parent
	
	$this -> nodes[$par] -> $child = $childid;
	
	$char = $charin == $this -> NodeCharC ? "" : $charin;
	
	$this -> nodes[$childid] = new Node($char, 0, $par);
	
	// Special business if we have a Branch Node
	// Doing all of this for the child !
	
	if ($char === "")
		$this -> ReadTreePart($childid);
}	

// Outer cross-recursive function

function ReadTreePart($nodenum)
{
	// Reading from the header, creating a child
	
	$charin = fgetc($this -> ifhand);
	$this -> ReadTPForChild($nodenum, "child0", ++$this -> ttlnodes, $charin);
	
	$charin = fgetc($this -> ifhand);
	$this -> ReadTPForChild($nodenum, "child1", ++$this -> ttlnodes, $charin);
}

// Master function

function ReconstructTree()
{
	// Creating Root Node. Here root is indexed 0.
	// It's parent is -1, it's children are as yet unknown.
	// NOTE : weights no longer have the slightest importance here
	
	$this -> nodes[0] = new Node("", 0);
	
	// Launching the business
	
	$this -> ttlnodes = 0; // Init value	
	$this -> ReadTreePart(0);
}

/******************************************************************************
*
*	Reading the compressed data bit-by-bit and generating the output.
*
*	Huffman Compression has unique-prefix property, so as soon as we recognise a code,
*	we can assume the corresponding char. All adding up, by reading $ofsize chars from the file, we should get
*	to the end of it !
*
******************************************************************************/

// Recursive function

function ReadUntilLeaf($curnode)
{
	if ($curnode -> char !== "")
		return $curnode -> char;
	
	if ($this -> BitRead1())
		return $this -> ReadUntilLeaf($this -> nodes[$curnode -> child1]);
	return $this -> ReadUntilLeaf($this -> nodes[$curnode -> child0]);
}

// Master function

function Read2MakeOutput()
{	
	for($i = 0; $i < $this -> ofsize; $i++)
	{
		// We follow the Tree down from Root with the successive bits read
		// We know we have found the character as soon as we hit a leaf Node
		
		$this -> odata .= $this -> ReadUntilLeaf($this -> nodes[0]);
	}
}

/*#############################################################################
#
#	Debug stuff
#
#############################################################################*/

/******************************************************************************
*
*	Showing how long the operation lasted.
*
******************************************************************************/

function ShowDebug_Time()
{
	echo "Expansion lasted ".round(($this -> debug_t2 - $this -> debug_t1) * 1000 )." ms<br><br>";
}

/******************************************************************************
*
*	Master Debug function, calling other ones according to debug settings.
*
******************************************************************************/

function ShowDebug()
{
	if ($this -> debug_time)
		$this -> ShowDebug_Time();
}

/*#############################################################################
#
#	Class functions
#
#############################################################################*/

/******************************************************************************
*
*	Constructor function. Setting some general variables.
*
******************************************************************************/

function CPRS_Expand()
{
	// Having general variables be set (parent function)
	
	$this -> InitSettings();
	
	// Setting a greater time limit than standard
	// Can me modified by the user later on with SetTimeLimit()
	
	$this -> SetTimeLimit(60);	
	
	// Initializing expansion-specific variables
	
	$this -> icarrier = "";
	$this -> icarlen = 0;
}

/******************************************************************************
*
*	Expand() is the principal function called to do the job.
*
******************************************************************************/

function Expand()
{
	if (!$this -> havefiles)
		$this -> Error("Files not provided");
	
	if ($this -> debug_time)
		$this -> debug_t1 = time_micro();
	
	//	
	// WORKING WITH INPUT
	//

	// From header : reading Huffman tree (with no weights, mind you)
	
	$this -> ReconstructTree();
	
	// From header : number of characters to read (ie. size of output file)
	
	$this -> ofsize = bindec($this -> BitRead(24));
	
	//
	// WORKING WITH OUTPUT
	//
	
	// Reading bit-by-bit and generating output
	
	$this -> Read2MakeOutput();
	
	// Writing the output and closing resource handles
	
	fwrite($this -> ofhand, $this -> odata);

	fclose($this -> ofhand);
	fclose($this -> ifhand);

	if ($this -> debug_time)
		$this -> debug_t2 = time_micro();
	
	// Calling Debug stuff in case any has been activated
	
	$this -> ShowDebug();
}

/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+*/

} // CPRS_Expand class

?>
Return current item: Huffman Compress