编程语言
首页 > 编程语言> > TIFF图像文件(五):LZW的PHP应用

TIFF图像文件(五):LZW的PHP应用

作者:互联网

一、要点

1、字典的关键字256表示开始,257表示结束;

2、压缩是针对文件的,9位的压缩码要转成8位ascii便于保存为文件;

3、解压时,将ASCII码转成二进制,恢复成9位压缩码再解压;

4、本程序只是针对压缩码小于512,即9bits的。实际情况中,当压缩码大于511后,改成10bits;大于1023,,用11bits;大于2048的,用12bits;不会使用13bits的,即编码不大于4096。

5、本程序能够以表格显示压缩和解压过程;建议用0-9,a-Z等可以显示的字符来测试。

二、程序

<?php
class LZW
{
    private static function initDict() {
        $dict = range("\0", "\xFF");

        return $dict;
    }
    public static function encode($str) {
        $dict = self::initDict();
        $root = '';
        $key = '';
        $num = 258;
        $out = array();
        $bits = '%09b';
        $html = '<table><tr><td>index</td><td>Input</td><td>Root</td><td>Root+Input</td><td>Dictionary</td><td>Out</td></tr>';
        $out = [];
        $out[] = 256;
        $skey = '';

        for ($i = 0;$i < strlen($str);$i++) {
            if ($num > 511)$bits = '%010b';
            if ($num > 1023)$bits = '%011b';
            if ($num > 2047)$bits = '%012b';
            $in = substr($str,$i,1);
            $skey = $skey.'.'.ord($in);
            $html.= '<tr><td>'.($i+1).'</td><td>'.$in.'('.ord($in).')</td><td>'.$root.'</td>';
            $key = array_search($root.$in,$dict);
            if ($key) {
                $root = $root.$in;


                $html.= '<td>'.$root.'</td><td>-</td><td>-</td><tr>';
            } else
            {
                $out[] = array_search($root,$dict);
                $html.= '<td>'.$root.$in.'</td><td>['.$num.']='.$root.$in.'</td><td>'.array_search($root,$dict).'</td><tr>';
                $dict[$num] = $root.$in;
                $num = $num+1;
                $root = $in;
                $skey = ord($in);

            }
        }
        $out[] = array_search($root,$dict);
        $html.= '<tr><td>'.($i+1).'</td><td>-</td><td>'.$root.'</td><td>-</td><td>-</td><td>'.array_search($root,$dict).'</td></tr>';
        $out[] = 257;
        $html.= '</table>';
        echo $html;
        $str = '';
        $bits = '%09b';
        $ar = [];
        echo '压缩输出值(10进制):'.implode('|',$out);
        $bin = [];
        $bo = [];
        for ($i = 0;$i < count($out);$i++) {
            $bo[] = sprintf($bits,$out[$i]);

        }
        echo '<br />';
        echo '压缩输出值(9bits二进制):'.implode('|',$bo);
        echo '<br />';
        $bos = implode('',$bo);
        for ($i = 0;$i < strlen($bos)%8;$i++) {
            $bos.= '0';
        }
        $bos = chunk_split($bos,8,"|");

        $bos = explode('|',$bos);
        for ($i = 0;$i < count($bos)-1;$i++) {
            $bin[] = base_convert(bindec($bos[$i]),10,16);
            $ar[] = chr(bindec($bos[$i]));
        }
        echo '压缩输出值(8bits字节):'.implode('|',$bin);
        //var_dump($out);




        //var_dump($dict);
        return implode('',$ar);
    }
    /**
     * 输出的code先是9bits的,即255~511,当字典的code数量大于511,改成10bits...,即不是定bits
     */
    public static function decode($str) {
        $dict = self::initDict();
        $num = 258;
        $in = '';
        $skey = '';
        $bin = [];
        for ($i = 0;$i < strlen($str);$i++) {
            $a = substr($str,$i,1);

            $in.= sprintf('%08b',ord($a));
            $bin[] = sprintf('%02X',ord($a));

        }
        echo '<br />';
        echo '输入压缩值(8bits字节):'.implode('|',$bin);
        $out = array();
        $html = '<table><tr><td>Index</td><td>Input</td><td>Root</td><td>Root+Input</td><td>Dictionary</td><td>Out</td></tr>';
        $root = '';
        $step = 9;
        //显示255-511
        echo '<br />';

        echo '转换压缩值(9bits二进制):'.chunk_split($in,9,"|");
        for ($i = 0;$i < strlen($in);$i = $i+$step) {
            $bstr = substr($in,$i,$step);
            echo $bstr.'[]';
            if (strlen($bstr) < $step)break;

            $b = bindec(substr($in,$i,$step));
            if ($b == 257)break;
            if ($b == 256 || $num > 4095) {
                $dict = self::initDict();
                $root = '';
                $num = 258;
            } else
            {

                $html.= '<tr><td>'.($i/$step+1).'</td><td>'.$b.'</td><td>'.$root.'</td>';
                if (isset($dict[$b])) {

                    $key = $root.substr($dict[$b],0,1);
                    if (array_search($key,$dict)) {
                        $root = $key;
                        $html.= '<td>'.$key.'</td><td>-</td><td>-</td></tr>';
                        $skey = $b;
                    } else
                    {
                        $out[] = $root;
                        $dict[$num] = $key;
                        $html.= '<td>'.$key.'<td>['.$num.']='.$key.'</td><td>'.$root.'</td><tr>';
                        $num = $num+1;
                        $root = $dict[$b];
                        $skey = $b;
                    }

                } else
                {
                    $key = $root.substr($root,0,1);
                    $dict[$num] = $key;
                    $html.= '<td>'.$root.substr($root,0,1).'<td>['.$num.']='.$root.substr($root,0,1).'</td><td>'.$root.'</td><tr>';
                    $num = $num+1;
                    $out[] = $root;
                    $root = $key;
                    $skey = $key;

                }

            }

            if ($num > 511)$step = 10;
            if ($num > 1023)$step = 11;
            if ($num > 2047)$step = 12;


        }
        $html.= '<tr><td>'.($i/$step+1).'</td><td>-</td><td>'.$root.'</td><td>-</td><td>-</td><td>'.$root.'</td></tr>';
        $html.= '</table>';
        echo $html;
        $out[] = $root;
        //var_dump($dict);
        $str = '';
        $bstr = implode('',$out);
        for ($i = 0;$i < strlen($bstr);$i++) {
            $str.= sprintf('%02X',ord(substr($bstr,$i,1)));
        }
        echo chunk_split($str,6,'|');
        return implode('',$out);
    }

}

 

lzljy 发布了16 篇原创文章 · 获赞 0 · 访问量 838 私信 关注

标签:TIFF,html,num,dict,key,图像文件,PHP,root,out
来源: https://blog.csdn.net/lzljy/article/details/103588206