powered by nequal
Home » IO_Zlib » Timeline » 2856

Changeset 2856 -- 2012-01-26 15:06:50

Author
よや
Comment
Deflate 処理を分離

Diffs

IO_Zlib/trunk/IO/Zlib/Deflate.php

@@ -0,0 +1,355 @@
+<?php
+
+require_once('IO/Bit.php');
+
+/*
+ * BTYPE:2 Custom Huffma 用 クラス (BTYPE:1 は今の所ベタに処理)
+ */
+
+class IO_Zlib_HuffmanReader_Custom {
+    var $_huffman_table_rev;
+    var $_hclen_min;
+    var $_hclen_max;
+    function __construct($hclen_list) {
+        ; // ハフマン符号長からテーブルを復元して逆引きテーブルを作成する
+        if (! is_array($hclen_list)) {
+            throw new Exception("huffman_table_from_hclen(hclen_list=$hclen_list)");
+        }
+        $hclen_list_len = count($hclen_list);
+        $hclen_min = min(array_diff($hclen_list, array(0)));
+        $hclen_max = max($hclen_list);
+        if ($hclen_min > $hclen_max) {
+            throw new Exception("huffman_table_from_hclen: hclen_min($hclen_min) > hclen_max($hclen_max)");
+        }
+        $huffman_table_rev = array();
+        $hcode = 0;
+        for ($i = $hclen_min ; $i <= $hclen_max ; $i++) {
+            $huffman_table_rev[$i] = array();
+            for ($j = 0 ; $j < $hclen_list_len; $j++) {
+                if ($hclen_list[$j] == $i) {
+                    $huffman_table_rev[$i][$hcode] = $j;
+                    $hcode ++;
+                }
+            }
+            $hcode *= 2;
+        }
+        $this->_huffman_table_rev = $huffman_table_rev;
+        $huffman_table_rev_keys = array_keys($huffman_table_rev);
+        $this->_hclen_min = $hclen_min;
+        $this->_hclen_max = $hclen_max;
+    }
+    /*
+     * 逆引きテーブルを参照して符号に対応する元データ(literal/length)を返す
+     */
+    function getValue(&$reader) {
+        $hcode = 0;
+        for ($i = 0 ; $i < $this->_hclen_min ; $i++) {
+            $hcode = ($hcode << 1) | $reader->getUIBitLSB();
+        }
+        foreach (range($this->_hclen_min, $this->_hclen_max) as $hclen) {
+            $hccode_table = $this->_huffman_table_rev[$hclen];
+            if (isset($hccode_table[$hcode])) {
+                return $hccode_table[$hcode];
+            }
+            $hcode = ($hcode << 1) | $reader->getUIBitLSB();
+        }
+        throw new Exception("Illegal Huffman Code");
+    }
+}
+
+class IO_Zlib_Deflate {
+    var $compressed_data = null;
+    // fixed huffman table (length, distance)
+    static $lzss_length_table = array(
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
+        15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
+        67, 83, 99,
+        115, 131, 163, 195, 227, 258
+        );
+    static $lzss_distance_table = array(
+        1, 2, 3, 4, 5, 7, 9, 13 ,17 ,25,
+        33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
+        1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
+        );
+    function parse($deflatedata, $offset) {
+        $reader = new IO_Bit();
+        $reader->input($deflatedata);
+        $reader->setOffset($offset, 0);
+        /*
+         * compression data block
+         */
+        $compressd_data = array();
+        while (true) {
+            $block = array();
+            $bfinal = $reader->getUIBitLSB();
+            $btype = $reader->getUIBitsLSB(2);
+            $block['(BFINAL)'] = $bfinal;
+            $block['BTYPE'] = $btype;
+            switch ($btype) {
+            case 0: // no compression data
+                $len = $reader->getUI16LE();
+                $block['LEN'] = $len;
+                $block['NLEN'] = $reader->getUI16LE(); // 1's complement of LEN
+                $block['Data'] = $reader->getData($len);
+                break;
+            case 1: // compressed with fixed Huffman codes;
+                $data = array();
+                while (true) {
+                    $hcode = 0;
+                    // ハフマン符号をリテラル/距離符号に変換
+                    for ($i = 0 ; $i < 7 ; $i++) {
+                        $hcode = ($hcode << 1) | $reader->getUIBitLSB();
+                    }
+                    if ($hcode <= 0x17) { // End of Code or Length Code
+                        $lit_or_len = $hcode + 256;
+                    } else {
+                        $hcode = ($hcode << 1) | $reader->getUIBitLSB();
+                        if ($hcode <= 0xBF) { // Literal Code
+                            $lit_or_len = $hcode - 0x30;
+                        } else if ($hcode <= 0xC7) { // Length Code
+                            $lit_or_len = $hcode - 0xC0 + 280;
+                        } else {
+                            $hcode = ($hcode << 1) | $reader->getUIBitLSB();
+                            $lit_or_len = $hcode - 0x190 + 144;
+                        }
+                    }
+                    // リテラル/距離符号を解釈して保存
+                    if ($lit_or_len < 256) {
+                        $data []= array('Value' => $lit_or_len);
+                    } else if ($lit_or_len > 256) {
+                        $lzss_length = self::$lzss_length_table[$lit_or_len - 257];
+                        if ((264 < $lit_or_len) && ($lit_or_len < 285)) {
+                            $lzss_length_extend_bits = floor(($lit_or_len - 261) / 4);
+                            $lzss_length_extend = $reader->getUIBitsLSB($lzss_length_extend_bits);
+                        } else { // 257-264, 285 => 0
+                            $lzss_length_extend = 0;
+                        }
+                        $lzss_distance_value = 0;
+                        for ($i = 0 ; $i < 5 ; $i++) {
+                            $lzss_distance_value =  ($lzss_distance_value << 1) | $reader->getUIBitLSB();
+                        }
+                        if ($lzss_distance_value >= 30) {
+                            throw new Exception("distance_value=$lzss_distance_value");
+                        }
+                        $lzss_distance = self::$lzss_distance_table[$lzss_distance_value];
+                        if ($lzss_distance_value < 4) {
+                            $lzss_distance_extend = 0;
+                        } else {
+                            $lzss_distance_extend_bits = floor(($lzss_distance_value - 2) / 2);
+                            $lzss_distance_extend = $reader->getUIBitsLSB($lzss_distance_extend_bits);
+                        }
+                        $data []= array('Length' => $lzss_length,
+                                        'LengthExtend' => $lzss_length_extend,
+                                        'Distance' => $lzss_distance,
+                                        'DistanceExtend' => $lzss_distance_extend);
+                    } else { // 256: End of Code
+                        break;
+                    }
+                } // while end
+                $block['Data'] = $data;
+                break;
+            case 2: // compressed with dynamic Huffman codes
+
+                //  まず、ハフマン符号化されたハフマンテーブルを復元する
+                $hlit  = $reader->getUIBitsLSB(5) + 257;
+                $hdist = $reader->getUIBitsLSB(5) + 1;
+                $hclen = $reader->getUIBitsLSB(4) + 4;
+                $block['HLIT'] = $hlit;
+                $block['HDIST'] = $hdist;
+                $block['HCLEN'] = $hclen;
+                // ハフマンテーブルのハフマン符号長を読み取る (phase 1)
+                $hclen_order = array(16, 17, 18,
+                                     0,  8, 7,  9, 6, 10, 5, 11,
+                                     4, 12, 3, 13, 2, 14, 1, 15);
+                $hclen_list = array_fill(0, 19, 0);
+                for ($i = 0 ; $i < $hclen ; $i++) {
+                    $len = $reader->getUIBitsLSB(3);
+                    $hclen_list[$hclen_order[$i]] = $len;
+                }
+//                $block['HCLEN_LIST'] = $hclen_list;
+                // ハフマン符号長からハフマン符号テーブルを生成する。(phase1)
+                $huffman_reader_custom19 = new IO_Zlib_HuffmanReader_Custom($hclen_list);
+
+                /*
+                 * ハフマンテーブルのハフマン符号長を読み取る (phase 2)
+                 */
+                $lit_and_dist_len_list = array();
+                $lit_and_dist_count = $hlit + $hdist;
+                for ($i = 0 ; $i < $lit_and_dist_count ; $i++) {
+                    $lit_or_len = $huffman_reader_custom19->getValue($reader);
+                    switch ($lit_or_len) {
+                    default: // 1-15
+                        $literal = $lit_or_len;
+                        $lit_and_dist_len_list [] = $literal;
+                        break;
+                    case 16:
+                        $length = $reader->getUIBitsLSB(2) + 3;
+                        for ($j = 0 ; $j < $length; $j++) {
+                            $lit_and_dist_len_list [] = $literal;
+                        }
+                        $i += $length - 1;
+                        break;
+                    case 17:
+                        $length = $reader->getUIBitsLSB(3) + 3;
+                        for ($j = 0 ; $j < $length; $j++) {
+                            $lit_and_dist_len_list [] = 0;
+                        }
+                        $i += $length - 1;
+                        break;
+                    case 18:
+                        $length = $reader->getUIBitsLSB(7) + 11;
+                        for ($j = 0 ; $j < $length; $j++) {
+                            $lit_and_dist_len_list [] = 0;
+                        }
+                        $i += $length - 1;
+                        break;
+                    }
+                }
+                unset($literal); // 後のブロックで誤って使われないように
+
+                /*
+                 * ハフマン符号長からハフマン符号テーブルを生成する。(phase2)
+                 * (リテラルと距離を別々に処理)
+                 */
+                $lit_len_list  = array_slice($lit_and_dist_len_list, 0, $hlit);
+                $dist_len_list = array_slice($lit_and_dist_len_list, $hlit);
+
+                $huffman_reader_custom_lit = new IO_Zlib_HuffmanReader_Custom($lit_len_list);
+                $huffman_reader_custom_dist = new IO_Zlib_HuffmanReader_Custom($dist_len_list);
+
+                /*
+                 * ここまでで、ハフマン符号テーブルの復元終わり。
+                 * ここからが、実際のデータのデコード処理
+                 */
+                $data = array();
+                while (true) {
+                    $lit_or_len = $huffman_reader_custom_lit->getValue($reader);
+                    if ($lit_or_len < 256) { // literal
+                        $data []= array('Value' => $lit_or_len);
+                    } else if ($lit_or_len > 256) { // length
+                        $lzss_length = self::$lzss_length_table[$lit_or_len - 257];
+                        if ((264 < $lit_or_len) && ($lit_or_len < 285)) {
+                            $lzss_length_extend_bits = floor(($lit_or_len - 261) / 4);
+                            $lzss_length_extend = $reader->getUIBitsLSB($lzss_length_extend_bits);
+                        } else { // 257-264, 285 => 0
+                            $lzss_length_extend = 0;
+                        }
+                        $lzss_distance_value = $huffman_reader_custom_dist->getValue($reader);
+                        $lzss_distance = self::$lzss_distance_table[$lzss_distance_value];
+                        if ($lzss_distance_value < 4) {
+                            $lzss_distance_extend = 0;
+                        } else {
+                            $lzss_distance_extend_bits = floor(($lzss_distance_value - 2) / 2);
+                            $lzss_distance_extend = $reader->getUIBitsLSB($lzss_distance_extend_bits);
+                        }
+                        $data []= array('Length' => $lzss_length,
+                                        'LengthExtend' => $lzss_length_extend,
+                                        'Distance' => $lzss_distance,
+                                        'DistanceExtend' => $lzss_distance_extend);
+                    } else { // 256:End
+//                        $data []= array('Value' => $hcode);
+                        break;
+                    }
+                } // while end
+                $block['Data'] = $data;
+                break;
+            default: // = 3
+                throw new Exception("Error BTYPE($btype)");
+                break;
+            }
+            $compressed_data [] = $block;
+            $this->compressed_data = $compressed_data;
+            if ($bfinal == 1) { // BFINAL
+                break;
+            }
+        }
+        $reader->byteAlign(); // XXX
+        list ($last_offset, $dummy) = $reader->getOffset();
+        return $last_offset - $offset; // deflate length
+    }
+
+    function dump() {
+        /*
+         *  compression data block
+         */
+        foreach ($this->compressed_data as $block) {
+            $btype = $block['BTYPE'];
+            echo "(BFINAL)={$block['(BFINAL)']} BTYPE:$btype\n";
+            switch ($btype)  {
+            case 0: // uncomress
+                echo "LEN:{$block['LEN']} NLEN:{$block['NLEN']} Data:{$block['Data']}\n";
+                break;
+            case 1: // fixed huffman
+            case 2: // dynamic huffman
+                if ($btype == 2) {
+                    echo "HLIT:{$block['HLIT']} HDIST:{$block['HDIST']} HCLEN:{$block['HCLEN']} ";
+                }
+                foreach ($block['Data'] as $value) {
+                    if (isset($value['Value'])) {
+                        printf("%02X(%c) ", $value['Value'], $value['Value']);
+                    } else if (isset($value['Length'])) {
+                        echo "Length:{$value['Length']}+{$value['LengthExtend']} Distance:{$value['Distance']}+{$value['DistanceExtend']} ";
+                    } else { // Maybe Terminate Value
+                        printf("%d(Terminate)", $value['Value']);
+                    }
+                }
+                echo "\n";
+                break;
+            }
+        }
+    }
+
+    /*
+     * uncompress method
+     */
+    function inflate($zipdata) {
+        if (is_null($this->compressed_data)) {
+            $this->parse($zipdata);
+        }
+        $data = '';
+        foreach ($this->compressed_data as $block) {
+            switch ($block['BTYPE']) {
+            case 0: // uncompress
+                $data .= $block['Data'];
+                break;
+            case 1: // fixed huffman
+            case 2: // dynamic huffman
+                foreach ($block['Data'] as $value) {
+                    if (isset($value['Value'])) {
+                        $data .= chr($value['Value']);
+                    } else {
+                        $lzss_length = $value['Length'] + $value['LengthExtend'];
+                        $lzss_distance = $value['Distance'] + $value['DistanceExtend'];
+                        $data_len = strlen($data);
+                        if ($data_len < $lzss_distance) {
+                            throw new Exception("data_len:$data_len < distance:$lzss_distance({$value['Distance']}+{$value['DistanceExtend']})");
+                        }
+                        $start_pos = $data_len - $lzss_distance;
+                        $end_pos = $start_pos  + $lzss_length - 1;
+                        for ($i = $start_pos ; $i <= $end_pos ; $i++) {
+                            $data .= $data[$i];
+                        }
+                    }
+                }
+                break;
+            }
+        }
+        return $data;
+    }
+
+    /*
+     * compress method
+     * type:0(no compression) only
+     */
+    function deflate($data) {
+        $cursol = 0;
+        $deflatedata = '';
+        for ($data_len = strlen($data); $data_len > 0; $data_len -= $len, $cursol += $len) {
+            $len = ($data_len < 65535)?$data_len:65535;
+            $nlen = ~$len;
+            $deflatedata .= "\x01".pack('v', $len).pack('v', $nlen);
+            $deflatedata .= substr($data, $cursol, $len);
+        }
+        return $deflatedata;
+    }
+}
属性に変更があったパス: IO_Zlib/trunk/IO/Zlib/Deflate.php
___________________________________________________________________
追加: svn:keywords
+ Id
追加: svn:eol-style
+ native

IO_Zlib/trunk/IO/Zlib.php

@@ -1,84 +1,20 @@
<?php
require_once('IO/Bit.php');
+require_once('IO/Zlib/Deflate.php');
define ('MOD_ADLER', 65521);
-/*
- * BTYPE:2 Custom Huffma 用 クラス (BTYPE:1 は今の所ベタに処理)
- */
-
-class IO_Zlib_HuffmanReader_Custom {
-    var $_huffman_table_rev;
-    var $_hclen_min;
-    var $_hclen_max;
-    function __construct($hclen_list) {
-        ; // ハフマン符号長からテーブルを復元して逆引きテーブルを作成する
-        if (! is_array($hclen_list)) {
-            throw new Exception("huffman_table_from_hclen(hclen_list=$hclen_list)");
-        }
-        $hclen_list_len = count($hclen_list);
-        $hclen_min = min(array_diff($hclen_list, array(0)));
-        $hclen_max = max($hclen_list);
-        if ($hclen_min > $hclen_max) {
-            throw new Exception("huffman_table_from_hclen: hclen_min($hclen_min) > hclen_max($hclen_max)");
-        }
-        $huffman_table_rev = array();
-        $hcode = 0;
-        for ($i = $hclen_min ; $i <= $hclen_max ; $i++) {
-            $huffman_table_rev[$i] = array();
-            for ($j = 0 ; $j < $hclen_list_len; $j++) {
-                if ($hclen_list[$j] == $i) {
-                    $huffman_table_rev[$i][$hcode] = $j;
-                    $hcode ++;
-                }
-            }
-            $hcode *= 2;
-        }
-        $this->_huffman_table_rev = $huffman_table_rev;
-        $huffman_table_rev_keys = array_keys($huffman_table_rev);
-        $this->_hclen_min = $hclen_min;
-        $this->_hclen_max = $hclen_max;
-    }
-    /*
-     * 逆引きテーブルを参照して符号に対応する元データ(literal/length)を返す
-     */
-    function getValue(&$reader) {
-        $hcode = 0;
-        for ($i = 0 ; $i < $this->_hclen_min ; $i++) {
-            $hcode = ($hcode << 1) | $reader->getUIBitLSB();
-        }
-        foreach (range($this->_hclen_min, $this->_hclen_max) as $hclen) {
-            $hccode_table = $this->_huffman_table_rev[$hclen];
-            if (isset($hccode_table[$hcode])) {
-                return $hccode_table[$hcode];
-            }
-            $hcode = ($hcode << 1) | $reader->getUIBitLSB();
-        }
-        throw new Exception("Illegal Huffman Code");
-    }
-}
-
class IO_Zlib {
var $cmf;
var $flg;
var $dictid = null;
-    var $compressed_data = null;
+    var $deflate = null;
// fixed huffman table (length, distance)
-    static $lz77_length_table = array(
-        3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
-        15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
-        67, 83, 99,
-        115, 131, 163, 195, 227, 258
-        );
-    static $lz77_distance_table = array(
-        1, 2, 3, 4, 5, 7, 9, 13 ,17 ,25,
-        33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
-        1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
-        );
-    function parse($zipdata) {
+    function parse($zipdata, $offset = 0) {
$reader = new IO_Bit();
$reader->input($zipdata);
+        $reader->setOffset($offset, 0);
/*
* zlib header info
*/
@@ -94,191 +30,11 @@
/*
* compression data block
*/
-        $compressd_data = array();
-        while (true) {
-            $block = array();
-            $bfinal = $reader->getUIBitLSB();
-            $btype = $reader->getUIBitsLSB(2);
-            $block['(BFINAL)'] = $bfinal;
-            $block['BTYPE'] = $btype;
-            switch ($btype) {
-            case 0: // no compression data
-                $len = $reader->getUI16LE();
-                $block['LEN'] = $len;
-                $block['NLEN'] = $reader->getUI16LE(); // 1's complement of LEN
-                $block['Data'] = $reader->getData($len);
-                break;
-            case 1: // compressed with fixed Huffman codes;
-                $data = array();
-                while (true) {
-                    $hcode = 0;
-                    // ハフマン符号をリテラル/距離符号に変換
-                    for ($i = 0 ; $i < 7 ; $i++) {
-                        $hcode = ($hcode << 1) | $reader->getUIBitLSB();
-                    }
-                    if ($hcode <= 0x17) { // End of Code or Length Code
-                        $lit_or_len = $hcode + 256;
-                    } else {
-                        $hcode = ($hcode << 1) | $reader->getUIBitLSB();
-                        if ($hcode <= 0xBF) { // Literal Code
-                            $lit_or_len = $hcode - 0x30;
-                        } else if ($hcode <= 0xC7) { // Length Code
-                            $lit_or_len = $hcode - 0xC0 + 280;
-                        } else {
-                            $hcode = ($hcode << 1) | $reader->getUIBitLSB();
-                            $lit_or_len = $hcode - 0x190 + 144;
-                        }
-                    }
-                    // リテラル/距離符号を解釈して保存
-                    if ($lit_or_len < 256) {
-                        $data []= array('Value' => $lit_or_len);
-                    } else if ($lit_or_len > 256) {
-                        $lz77_length = self::$lz77_length_table[$lit_or_len - 257];
-                        if ((264 < $lit_or_len) && ($lit_or_len < 285)) {
-                            $lz77_length_extend_bits = floor(($lit_or_len - 261) / 4);
-                            $lz77_length_extend = $reader->getUIBitsLSB($lz77_length_extend_bits);
-                        } else { // 257-264, 285 => 0
-                            $lz77_length_extend = 0;
-                        }
-                        $lz77_distance_value = 0;
-                        for ($i = 0 ; $i < 5 ; $i++) {
-                            $lz77_distance_value =  ($lz77_distance_value << 1) | $reader->getUIBitLSB();
-                        }
-                        if ($lz77_distance_value >= 30) {
-                            throw new Exception("distance_value=$lz77_distance_value");
-                        }
-                        $lz77_distance = self::$lz77_distance_table[$lz77_distance_value];
-                        if ($lz77_distance_value < 4) {
-                            $lz77_distance_extend = 0;
-                        } else {
-                            $lz77_distance_extend_bits = floor(($lz77_distance_value - 2) / 2);
-                            $lz77_distance_extend = $reader->getUIBitsLSB($lz77_distance_extend_bits);
-                        }
-                        $data []= array('Length' => $lz77_length,
-                                        'LengthExtend' => $lz77_length_extend,
-                                        'Distance' => $lz77_distance,
-                                        'DistanceExtend' => $lz77_distance_extend);
-                    } else { // 256: End of Code
-                        break;
-                    }
-                } // while end
-                $block['Data'] = $data;
-                break;
-            case 2: // compressed with dynamic Huffman codes
-
-                //  まず、ハフマン符号化されたハフマンテーブルを復元する
-                $hlit  = $reader->getUIBitsLSB(5) + 257;
-                $hdist = $reader->getUIBitsLSB(5) + 1;
-                $hclen = $reader->getUIBitsLSB(4) + 4;
-                $block['HLIT'] = $hlit;
-                $block['HDIST'] = $hdist;
-                $block['HCLEN'] = $hclen;
-                // ハフマンテーブルのハフマン符号長を読み取る (phase 1)
-                $hclen_order = array(16, 17, 18,
-                                     0,  8, 7,  9, 6, 10, 5, 11,
-                                     4, 12, 3, 13, 2, 14, 1, 15);
-                $hclen_list = array_fill(0, 19, 0);
-                for ($i = 0 ; $i < $hclen ; $i++) {
-                    $len = $reader->getUIBitsLSB(3);
-                    $hclen_list[$hclen_order[$i]] = $len;
-                }
-//                $block['HCLEN_LIST'] = $hclen_list;
-                // ハフマン符号長からハフマン符号テーブルを生成する。(phase1)
-                $huffman_reader_custom19 = new IO_Zlib_HuffmanReader_Custom($hclen_list);
-
-                /*
-                 * ハフマンテーブルのハフマン符号長を読み取る (phase 2)
-                 */
-                $lit_and_dist_len_list = array();
-                $lit_and_dist_count = $hlit + $hdist;
-                for ($i = 0 ; $i < $lit_and_dist_count ; $i++) {
-                    $lit_or_len = $huffman_reader_custom19->getValue($reader);
-                    switch ($lit_or_len) {
-                    default: // 1-15
-                        $literal = $lit_or_len;
-                        $lit_and_dist_len_list [] = $literal;
-                        break;
-                    case 16:
-                        $length = $reader->getUIBitsLSB(2) + 3;
-                        for ($j = 0 ; $j < $length; $j++) {
-                            $lit_and_dist_len_list [] = $literal;
-                        }
-                        $i += $length - 1;
-                        break;
-                    case 17:
-                        $length = $reader->getUIBitsLSB(3) + 3;
-                        for ($j = 0 ; $j < $length; $j++) {
-                            $lit_and_dist_len_list [] = 0;
-                        }
-                        $i += $length - 1;
-                        break;
-                    case 18:
-                        $length = $reader->getUIBitsLSB(7) + 11;
-                        for ($j = 0 ; $j < $length; $j++) {
-                            $lit_and_dist_len_list [] = 0;
-                        }
-                        $i += $length - 1;
-                        break;
-                    }
-                }
-                unset($literal); // 後のブロックで誤って使われないように
-
-                /*
-                 * ハフマン符号長からハフマン符号テーブルを生成する。(phase2)
-                 * (リテラルと距離を別々に処理)
-                 */
-                $lit_len_list  = array_slice($lit_and_dist_len_list, 0, $hlit);
-                $dist_len_list = array_slice($lit_and_dist_len_list, $hlit);
-
-                $huffman_reader_custom_lit = new IO_Zlib_HuffmanReader_Custom($lit_len_list);
-                $huffman_reader_custom_dist = new IO_Zlib_HuffmanReader_Custom($dist_len_list);
-
-                /*
-                 * ここまでで、ハフマン符号テーブルの復元終わり。
-                 * ここからが、実際のデータのデコード処理
-                 */
-                $data = array();
-                while (true) {
-                    $lit_or_len = $huffman_reader_custom_lit->getValue($reader);
-                    if ($lit_or_len < 256) { // literal
-                        $data []= array('Value' => $lit_or_len);
-                    } else if ($lit_or_len > 256) { // length
-                        $lz77_length = self::$lz77_length_table[$lit_or_len - 257];
-                        if ((264 < $lit_or_len) && ($lit_or_len < 285)) {
-                            $lz77_length_extend_bits = floor(($lit_or_len - 261) / 4);
-                            $lz77_length_extend = $reader->getUIBitsLSB($lz77_length_extend_bits);
-                        } else { // 257-264, 285 => 0
-                            $lz77_length_extend = 0;
-                        }
-                        $lz77_distance_value = $huffman_reader_custom_dist->getValue($reader);
-                        $lz77_distance = self::$lz77_distance_table[$lz77_distance_value];
-                        if ($lz77_distance_value < 4) {
-                            $lz77_distance_extend = 0;
-                        } else {
-                            $lz77_distance_extend_bits = floor(($lz77_distance_value - 2) / 2);
-                            $lz77_distance_extend = $reader->getUIBitsLSB($lz77_distance_extend_bits);
-                        }
-                        $data []= array('Length' => $lz77_length,
-                                        'LengthExtend' => $lz77_length_extend,
-                                        'Distance' => $lz77_distance,
-                                        'DistanceExtend' => $lz77_distance_extend);
-                    } else { // 256:End
-//                        $data []= array('Value' => $hcode);
-                        break;
-                    }
-                } // while end
-                $block['Data'] = $data;
-                break;
-            default: // = 3
-                throw new Exception("Error BTYPE($btype)");
-                break;
-            }
-            $compressed_data [] = $block;
-            $this->compressed_data = $compressed_data;
-            if ($bfinal == 1) { // BFINAL
-                break;
-            }
-        }
+        $deflate = new IO_Zlib_Deflate();
+        list($deflate_offset, $dummy) = $reader->getOffset();
+        $deflate_length = $deflate->parse($zipdata, $deflate_offset);
+        $this->deflate = $deflate;
+        $reader->setOffset($offset + $deflate_offset + $deflate_length, 0);
if ($reader->hasNextData(4)) { // XXX
$this->adler32 = $reader->getUI32BE();
} else {
@@ -302,31 +58,7 @@
/*
*  compression data block
*/
-        foreach ($this->compressed_data as $block) {
-            $btype = $block['BTYPE'];
-            echo "(BFINAL)={$block['(BFINAL)']} BTYPE:$btype\n";
-            switch ($btype)  {
-            case 0: // uncomress
-                echo "LEN:{$block['LEN']} NLEN:{$block['NLEN']} Data:{$block['Data']}\n";
-                break;
-            case 1: // fixed huffman
-            case 2: // dynamic huffman
-                if ($btype == 2) {
-                    echo "HLIT:{$block['HLIT']} HDIST:{$block['HDIST']} HCLEN:{$block['HCLEN']} ";
-                }
-                foreach ($block['Data'] as $value) {
-                    if (isset($value['Value'])) {
-                        printf("%02X(%c) ", $value['Value'], $value['Value']);
-                    } else if (isset($value['Length'])) {
-                        echo "Length:{$value['Length']}+{$value['LengthExtend']} Distance:{$value['Distance']}+{$value['DistanceExtend']} ";
-                    } else { // Maybe Terminate Value
-                        printf("%d(Terminate)", $value['Value']);
-                    }
-                }
-                echo "\n";
-                break;
-            }
-        }
+        $this->deflate->dump();
echo "ADLER32:{$this->adler32}\n";
}
@@ -334,36 +66,8 @@
* uncompress method
*/
function inflate($zipdata) {
-        $this->parse($zipdata);
-        $data = '';
-        foreach ($this->compressed_data as $block) {
-            switch ($block['BTYPE']) {
-            case 0: // uncompress
-                $data .= $block['Data'];
-                break;
-            case 1: // fixed huffman
-            case 2: // dynamic huffman
-                foreach ($block['Data'] as $value) {
-                    if (isset($value['Value'])) {
-                        $data .= chr($value['Value']);
-                    } else {
-                        $lz77_length = $value['Length'] + $value['LengthExtend'];
-                        $lz77_distance = $value['Distance'] + $value['DistanceExtend'];
-                        $data_len = strlen($data);
-                        if ($data_len < $lz77_distance) {
-                            throw new Exception("data_len:$data_len < distance:$lz77_distance({$value['Distance']}+{$value['DistanceExtend']})");
-                        }
-                        $start_pos = $data_len - $lz77_distance;
-                        $end_pos = $start_pos  + $lz77_length - 1;
-                        for ($i = $start_pos ; $i <= $end_pos ; $i++) {
-                            $data .= $data[$i];
-                        }
-                    }
-                }
-                break;
-            }
-        }
-        return $data;
+        $this->parse($zipdata);
+        return IO_SWF_Deflate($zipdata);
}
/*
@@ -371,23 +75,9 @@
* type:0(no compression) only
*/
function deflate($data) {
-        $zlibdata = "\x78\x01";
-        $cursol = 0;
-        $limit_size = 65535;
-        for ($data_len = strlen($data); $data_len > 0; $data_len -= $len, $cursol += $len) {
-            if ($data_len <= $limit_size) {
-                $zlibdata .= "\x01"; // BFINAL:1 BTYPE:0
-                $len = $data_len;
-            } else {
-                $zlibdata .= "\x00"; // BFINAL:0 BTYPE:0
-                $len = $limit_size;
-            }
-            $nlen = ~$len;
-
-            $zlibdata .= pack('v', $len).pack('v', $nlen);
-            $zlibdata .= substr($data, $cursol, $len);
-        }
-        return $zlibdata.pack('N', self::adler32($data));
+        $zlibheader = "\x78\x01";
+        $deflatedata = IO_Zlib_Deflate::deflate($data);
+        return $zlibheader.$deflatedata.pack('N', self::adler32($data));
}
function adler32($data) {
$a = 1;