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

Source for file Huffman.php

Documentation is available at Huffman.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. /**
  29.  * This class is intented to perform Huffman static
  30.  * compression on files with a PHP script.
  31.  *
  32.  * Such compression is essentially useful for reducing
  33.  * the size of texts by about 43% ; it is at its best
  34.  * when working with data containing strong redundancies
  35.  * at the character level -- that is, the opposite of a
  36.  * binary file in which the characters would be spread
  37.  * over the whole ASCII alphabet.
  38.  *
  39.  * It is questionable whether anyone would want to do
  40.  * such an operation with PHP, when C implementations
  41.  * of much stronger and more versatile algorithms are
  42.  * readily avaible as PHP functions. The main drawback
  43.  * of this script class is slowness despite processing
  44.  * intensiveness (7 to 8 seconds to compress a 300Kb
  45.  * text, about 25 seconds to expand it back).
  46.  *
  47.  * USE AND FUNCTION REFERENCE :
  48.  * 
  49.  * The 4 PHP files having been placed in the same directory, the only ones you
  50.  * have to include are compress.inc.php and/or expand.inc.php according to your
  51.  * needs.
  52.  * 
  53.  * -----------------
  54.  * -- Compression --
  55.  * -----------------
  56.  * 
  57.  * Once a CPRS_Compress object has been constructed, the following functions
  58.  * are available :
  59.  * 
  60.  * + setFiles('path/to/source/file', 'path/to/destination/file'):
  61.  * 
  62.  * This step is mandatory, as you give the paths to the file you want to
  63.  * compress, and the file you want the compressed output written to. These
  64.  * paths will be passed to the PHP fopen() function, see its reference for
  65.  * details. Note that the paths, if local, should be relative to the location
  66.  * of _your_ script, i.e. the one that has included this compression class.
  67.  * 
  68.  * + setTimeLimit(int seconds):
  69.  * 
  70.  * This step is optional. It allows you to force a certain timeout limit
  71.  * for the PHP script, presumably longer than the default configuration on
  72.  * your server, should the job take too long. It simply calls the PHP
  73.  * set_time_limit() function.
  74.  * 
  75.  * + compress():
  76.  * 
  77.  * This is the function that actually executes the job. It receives no
  78.  * parameters, and is of course obligatory.
  79.  * 
  80.  * ---------------
  81.  * -- Expansion --
  82.  * ---------------
  83.  * 
  84.  * Once a CPRS_Expand object has been constructed, the following functions
  85.  * are available :
  86.  * 
  87.  * + setFiles('path/to/source/file', 'path/to/destination/file'):
  88.  * 
  89.  * This step is mandatory, as you give the paths to the file containing the
  90.  * compressed data, and the file you want the expanded output written to. These
  91.  * paths will be passed to the PHP fopen() function, see its reference for
  92.  * details. Note that the paths, if local, should be relative to the location
  93.  * of _your_ script, i.e. the one that has included this compression class.
  94.  * 
  95.  * + setTimeLimit(int seconds):
  96.  * 
  97.  * This step is optional. It allows you to force a certain timeout limit
  98.  * for the PHP script, presumably longer than the default configuration on
  99.  * your server, should the job take too long. It simply calls the PHP
  100.  * set_time_limit() function.
  101.  * 
  102.  * + expand():
  103.  * 
  104.  * This is the function that actually executes the job. It receives no
  105.  * parameters, and is of course obligatory.
  106.  * 
  107.  * 
  108.  * EXTRA NOTICE:
  109.  * 
  110.  * Please also note that some technical considerations apart from the core
  111.  * Huffman static algorithm have probably not been implemented after
  112.  * any standard in this class. That means that any other compressed file,
  113.  * even if you have reason to be certain that it was produced using the
  114.  * Huffman static algorithm, would in all probability not be usable as
  115.  * source file for data expansion with this class.
  116.  * In short, this class can very probably only restore what it itself
  117.  * compressed.
  118.  * 
  119.  * Anyway, thanks for using ! No feedback would be ignored. Feel free
  120.  * to tell me how you came in contact with this class, why you're using
  121.  * it (if at liberty to do so), and to suggest any enhancements, or of
  122.  * course to point out any serious bugs.
  123.  * 
  124.  * @package Text
  125.  */
  126.  
  127. {
  128.     // {{{ properties
  129.     /**
  130.      * Carrier window for reading from input
  131.      * @access protected
  132.      */
  133.     protected $_icarrier;
  134.     
  135.     /**
  136.      * Length of the input carrier at any given time
  137.      * @access protected
  138.      */
  139.     protected $_icarlen;
  140.     
  141.     /**
  142.      * Carrier window for writing to output
  143.      * @access protected
  144.      */
  145.     protected $_ocarrier;
  146.     
  147.     /**
  148.      * Length of the output carrier at any given time
  149.      * @access protected
  150.      */
  151.     protected $_ocarlen;
  152.     
  153.     /**
  154.      * Boolean to check files have been passed
  155.      * @access protected
  156.      */
  157.     protected $_havefiles;
  158.     
  159.     /**
  160.      * Character representing a Branch Node in Tree transmission
  161.      * @access protected
  162.      */
  163.     protected $_nodeChar;
  164.     
  165.     /**
  166.      * The same, character version as opposed to binary string
  167.      * @access protected
  168.      */
  169.     protected $_nodeCharC;
  170.  
  171.     /**
  172.      * Path to the input file
  173.      * @access protected
  174.      */ 
  175.     protected $_ifile;
  176.     
  177.     /**
  178.      * Resource handle of the input file
  179.      * @access protected
  180.      */
  181.     protected $_ifhand;
  182.     
  183.     /**
  184.      * Path to the output file
  185.      * @access protected
  186.      */
  187.     protected $_ofile;
  188.     
  189.     /**
  190.      * Resource handle of the output file
  191.      * @access protected
  192.      */
  193.     protected $_ofhand;
  194.     
  195.     /**
  196.      * Data eventually written to the output file
  197.      * @access protected
  198.      */
  199.     protected $_odata;
  200.  
  201.     /**
  202.      * Array of Node objects
  203.      * @access protected
  204.      */
  205.     protected $_nodes;
  206.     // }}}
  207.     
  208.  
  209.     // {{{ constructor
  210.     /**
  211.      * Constructor
  212.      *
  213.      * @access public
  214.      */
  215.     public function __construct()
  216.     {
  217.         $this->_havefiles = false;
  218.         $this->_nodeChar  = '00000111';
  219.         $this->_nodeCharC = chr(7);
  220.         $this->_odata     = '';
  221.         $this->_nodes     = array();
  222.     }
  223.     // }}}
  224.     
  225.  
  226.     /**
  227.      * setFiles() is called to specify the paths to the input and output files.
  228.      * Having set the relevant variables, it gets resource pointers to the files
  229.      * themselves.
  230.      *
  231.      * @throws Exception
  232.      * @access public
  233.      */
  234.     public function setFiles($ifile ''$ofile '')
  235.     {
  236.         if (trim($ifile== ''{
  237.             throw new Exception('No input file provided.');
  238.         else {
  239.             $this->_ifile = $ifile;
  240.         }
  241.     
  242.         if (trim($ofile== ''{
  243.             throw new Exception('No output file provided.');
  244.         else {
  245.             $this->_ofile = $ofile;
  246.         }
  247.     
  248.         // Getting resource handles to the input and output files
  249.     
  250.         if (!($this->_ifhand = @fopen($this->_ifile'rb'))) {
  251.             throw new Exception('Unable to open input file.');
  252.         }
  253.     
  254.         if (!($this->_ofhand = @fopen($this->_ofile'wb'))) {
  255.             throw new Exception('Unable to open output file.');
  256.         }
  257.         
  258.         // Stating that files have been gotten
  259.         $this->_havefiles = true;
  260.     
  261.         return true;
  262.     }
  263.  
  264.     
  265.     // protected methods
  266.     
  267.     /**
  268.      * Bit-writing with a carrier: output every 8 bits
  269.      *
  270.      * @access protected
  271.      */
  272.     final protected function _bitWrite($str$len)
  273.     {
  274.         // $carrier is the sequence of bits, in a string
  275.         $this->_ocarrier .= $str;
  276.         $this->_ocarlen  += $len;
  277.     
  278.         while ($this->_ocarlen >= 8)
  279.         {
  280.             $this->_odata    .= chr(bindec(substr($this->_ocarrier08)));
  281.             $this->_ocarrier  = substr($this->_ocarrier8);
  282.             $this->_ocarlen  -= 8;
  283.         }
  284.     }
  285.  
  286.     /**
  287.      * Finalizing bit-writing, writing the data.
  288.      *
  289.      * @access protected
  290.      */
  291.     final protected function _bitWriteEnd()
  292.     {
  293.         // If carrier is not finished, complete it to 8 bits with 0's and write it out
  294.         // Adding n zeros is like multipliying by 2^n
  295.     
  296.         if ($this->_ocarlen{
  297.             $this->_odata .= chr(bindec($this->_ocarrierpow(28 - $this->_ocarlen));
  298.         }
  299.     
  300.         // Writing the whole output data to file.
  301.         fwrite($this->_ofhand$this->_odata);
  302.     }
  303.  
  304.     /**
  305.      * Bit-reading with a carrier: input 8 bits at a time.
  306.      *
  307.      * @access protected
  308.      */
  309.     final protected function _bitRead($len)
  310.     {
  311.         // Fill carrier 8 bits (1 char) at a time until we have at least $len bits
  312.     
  313.         // Determining the number n of chars that we are going to have to read
  314.         // This might be zero, if the icarrier is presently long enough
  315.     
  316.         $n ceil(($len $this->_icarlen/ 8);
  317.     
  318.         // Reading those chars, adding each one as 8 binary digits to icarrier
  319.     
  320.         for ($i = 0; $i $n$i++{
  321.             $this->_icarrier .= $this->_decBinDig(ord(fgetc($this->_ifhand))8);
  322.         }
  323.         
  324.         // Getting the portion of icarrier we want to return
  325.         // Then diminishing the icarrier of the returned digits
  326.     
  327.         $ret substr($this->_icarrier0$len);
  328.         $this->_icarrier = substr($this->_icarrier$len);
  329.     
  330.         // Adding the adequate value to icarlen, taking all operations into account
  331.     
  332.         $this->_icarlen += 8 * $n $len;
  333.     
  334.         return $ret;
  335.     }
  336.  
  337.     /**
  338.      * Read 1 bit.
  339.      *
  340.      * @access protected
  341.      */
  342.     final protected function _bitRead1()
  343.     {
  344.         // Faster reading of just 1 bit
  345.         // WARNING : requires icarrier to be originally empty !
  346.         // NO keeping track of carrier length
  347.     
  348.         if ($this->_icarrier == ''{
  349.             $this->_icarrier = $this->_decBinDig(ord(fgetc($this->_ifhand))8);
  350.         }
  351.     
  352.         $ret substr($this->_icarrier01);
  353.         $this->_icarrier = substr($this->_icarrier1);
  354.     
  355.         return $ret;
  356.     }
  357.  
  358.     /**
  359.      * Returns the binary representation of $x as a string, over $n digits, with
  360.      * as many initial zeros as necessary to cover that.
  361.      *  
  362.      * Note: $n has to be more digits than the binary representation of $x
  363.      * originally has!
  364.      *
  365.      * @access protected
  366.      */
  367.     final protected function _decBinDig($x$n)
  368.     {
  369.         return substr(decbin(pow(2$n$x)1);
  370.     }
  371. }
  372.  
  373. ?>

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