Text
[ class tree: Text ] [ index: Text ] [ all elements ]

Source for file HuffmanExpand.php

Documentation is available at HuffmanExpand.php

  1. <?php
  2.  
  3. // {{{ license
  4.  
  5. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  6. //
  7. // +----------------------------------------------------------------------+
  8. // | PHP Version 4                                                        |
  9. // +----------------------------------------------------------------------+
  10. // | Copyright (c) 1997-2002 The PHP Group                                |
  11. // +----------------------------------------------------------------------+
  12. // | This source file is subject to version 2.0 of the PHP license,       |
  13. // | that is bundled with this package in the file LICENSE, and is        |
  14. // | available at through the world-wide-web at                           |
  15. // | http://www.php.net/license/2_02.txt.                                 |
  16. // | If you did not receive a copy of the PHP license and are unable to   |
  17. // | obtain it through the world-wide-web, please send a note to          |
  18. // | license@php.net so we can mail you a copy immediately.               |
  19. // +----------------------------------------------------------------------+
  20. // | Authors: Markus Nix <mnix@docuverse.de>                              |
  21. // |          David Holmes <exaton@free.fr> (original version)            |
  22. // +----------------------------------------------------------------------+
  23. //
  24.  
  25. // }}}
  26.  
  27.  
  28. require_once 'Text/Huffman.php';
  29.  
  30.  
  31. /**
  32.  * Huffman Expansion Class
  33.  *
  34.  * @package Text
  35.  */
  36.  
  37. {
  38.     // {{{ properties
  39.     /**
  40.      * Size of the output file, in bytes
  41.      * @access protected
  42.      */ 
  43.     protected $_ofsize;
  44.     
  45.     /**
  46.      * For use in Huffman Tree reconstruction
  47.      * @access protected
  48.      */
  49.     protected $_ttlnodes;
  50.     // }}}
  51.     
  52.     
  53.     // {{{ constructor
  54.     /**
  55.      * Constructor
  56.      *
  57.      * @access public
  58.      */
  59.     public function __construct()
  60.     {
  61.         parent::__construct();
  62.     
  63.         // Initializing expansion-specific variables
  64.         $this->_icarrier = '';
  65.         $this->_icarlen  = 0;
  66.     }
  67.     // }}}
  68.     
  69.  
  70.     /**
  71.      * Perform expansion.
  72.      *
  73.      * @access public
  74.      */
  75.     public function expand()
  76.     {
  77.         if (!$this->_havefiles{
  78.             throw new Exception('Files not provided.');
  79.         }
  80.     
  81.         // From header: reading Huffman tree (with no weights, mind you)
  82.         $this->_reconstructTree();
  83.     
  84.         // From header: number of characters to read (ie. size of output file)
  85.         $this->_ofsize = bindec($this->_bitRead(24));
  86.     
  87.         // Reading bit-by-bit and generating output
  88.         $this->_readToMakeOutput();
  89.     
  90.         // Writing the output and closing resource handles
  91.         fwrite($this->_ofhand$this->_odata);
  92.  
  93.         fclose($this->_ofhand);
  94.         fclose($this->_ifhand);
  95.     }
  96.  
  97.     
  98.     // private methods
  99.     
  100.     /**
  101.      * Reconstruct the Huffman tree transmitted in header.
  102.      *
  103.      * @access private
  104.      */
  105.     private function _readTPForChild($par$child$childid$charin)
  106.     {
  107.         // Creating child, setting right parent and right child for parent
  108.         $this->_nodes[$par][$child$childid;
  109.     
  110.         $char ($charin == $this->_nodeCharC)'' $charin;
  111.     
  112.         $node = array(
  113.             '_char'   => $char,
  114.             '_w'      => 0,
  115.             '_par'    => $par,
  116.             '_child0' => -1,
  117.             '_child1' => -1,
  118.             '_lndone' => false
  119.         );
  120.         
  121.         $this->_nodes[$childid$node;
  122.     
  123.         // Special business if we have a Branch Node
  124.         // Doing all of this for the child!
  125.         if ($char === ''{
  126.             $this->_readTreePart($childid);
  127.         }
  128.     }   
  129.  
  130.     /**
  131.      * @access private
  132.      */
  133.     private function _readTreePart($nodenum)
  134.     {
  135.         // Reading from the header, creating a child
  136.         $charin fgetc($this->_ifhand);
  137.         $this->_readTPForChild($nodenum'_child0'++$this->_ttlnodes$charin);
  138.     
  139.         $charin fgetc($this->_ifhand);
  140.         $this->_readTPForChild($nodenum'_child1'++$this->_ttlnodes$charin);
  141.     }
  142.  
  143.     /**
  144.      * @access private
  145.      */
  146.     private function _reconstructTree()
  147.     {
  148.         // Creating Root Node. Here root is indexed 0.
  149.         // It's parent is -1, it's children are as yet unknown.
  150.         // NOTE : weights no longer have the slightest importance here
  151.     
  152.         $node = array(
  153.             '_char'   => '',
  154.             '_w'      => 0,
  155.             '_par'    => -1,
  156.             '_child0' => -1,
  157.             '_child1' => -1,
  158.             '_lndone' => false
  159.         );
  160.         
  161.         $this->_nodes[0$node;
  162.     
  163.         // Launching the business
  164.         $this->_ttlnodes = 0; // Init value 
  165.         $this->_readTreePart(0);
  166.     }
  167.  
  168.     /**
  169.      * Reading the compressed data bit-by-bit and generating the output.
  170.      *
  171.      * Huffman Compression has unique-prefix property, so as soon as
  172.      * we recognise a code, we can assume the corresponding char.
  173.      * All adding up, by reading $ofsize chars from the file, we should get
  174.      * to the end of it !
  175.      *
  176.      * @access private
  177.      */
  178.     private function _readUntilLeaf($curnode)
  179.     {
  180.         if ($curnode['_char'!== ''{
  181.             return $curnode['_char'];
  182.         }
  183.     
  184.         if ($this->_bitRead1()) {
  185.             return $this->_readUntilLeaf($this->_nodes[$curnode['_child1']]);
  186.         }
  187.     
  188.         return $this->_readUntilLeaf($this->_nodes[$curnode['_child0']]);
  189.     }
  190.  
  191.     /**
  192.      * We follow the Tree down from Root with the successive bits read
  193.      * We know we have found the character as soon as we hit a leaf Node.
  194.      *
  195.      * @access private
  196.      */
  197.     private function _readToMakeOutput()
  198.     {   
  199.         for ($i = 0; $i $this->_ofsize$i++{
  200.             $this->_odata .= $this->_readUntilLeaf($this->_nodes[0]);
  201.         }
  202.     }
  203. }
  204.  
  205. ?>

Documentation generated on Mon, 11 Mar 2019 13:54:22 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.