Compressie script

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Storeman storeman

storeman storeman

04/06/2008 23:19:00
Quote Anchor link
Ik ben voor de hobby eens wat aan het experimenteren met compressie. Ik heb de huffen class al gevonden en al getest, deze is echter behoorlijk traag met grotere bestanden en dus niet echt bruikbaar.

Ik ben al wat verder aan het zoeken geweest en ik stuitte op LZW (http://en.wikipedia.org/wiki/LZW). Dit lijkt tamelijk eenvoudig te implementeren(en dus te begrijpen) en ook niet té processorintensief.

Ik krijg het echter nog niet volledig aan de praat in php, heb helaas net mijn opzetje weer weggegooid.

Wel vond ik nog een class: http://www.phpclasses.org/browse/file/20090.html

Maar die zit vol errors en decode ook niet helemaal goed. Mijn insteek is om dit in twee functies te bouwen (compress/decompress)

Dus, voor de geinteresseerde/geprikkelde mede phphulper:

Compressor
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
w = NIL;
   while (read a char c) do
       if (wc exists in dictionary) then
           w = wc;
       else
           add wc to the dictionary;
           output the code for w;
           w = c;
       endif
   done
   output the code for w;


Decompress
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
read a char k;
   output k;
   w = k;
   while (read a char k) do
      if (index k exists in dictionary) then
          entry = dictionary entry for k;
      else if (index k does not exist in dictionary && k == currSizeDict)
          entry = w + w[0];
      else
          signal invalid code;
      endif
      output entry;
      add w+entry[0] to the dictionary;
      w = entry;
   done


Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

function compressLzw( $input){

    $inputArr = str_split( $input, 1);
    
    $w = '';
    $wc = '';
    $dict = array();
    $output = '';
    
    foreach( $input as $char ){
        
        $wc = $w . $char;
        
        if( in_array($wc)){
            
        }
else{
            $dict[] = $w;
            
            $output .= $w;
            
            $w = $char;
        }
        
    }


    return $output;
}

[
/code]
 
PHP hulp

PHP hulp

20/04/2024 00:12:48
 
Arend a

Arend a

05/06/2008 00:43:00
Quote Anchor link
Je bent op de hoogte van de gzip() functies van phphulp of de mod_deflate functionaliteit van apache die deze functies in C code implementeren (dus in een niet geintrepeteerde taal, daarom stukken sneller bij het verwerken van grote hoeveelheid data).

http://httpd.apache.org/docs/2.0/mod/mod_deflate.html
http://nl2.php.net/manual/en/ref.zlib.php

Ook weet ik niet zeker of dit wel op ascii (text) niveau gaat werken. LWZ werkt voorzover ik weet op byte niveau. Bedenk eens wat er gebeurd als je een binair bestand als een bmp/rar bestand probeert te lezen? Wanneer deze naar ascii wordt vertaald loopt het compleet in de soep. Dus je zult waarschijnlijk een manier moeten verzinnen om de code naar een binair systeem te vertalen, dan wordt het opeens een stuk ingewikkelder.
 
Storeman storeman

storeman storeman

05/06/2008 09:57:00
Quote Anchor link
asc2bin of bin2asc zijn twee functies welke ik al heb, deze zijn redelijk eenvoudig, dus daar zou het niet op stuk moeten lopen.

Wat ik begrijp uit het apache verhaal, dat is vooral voor text/html en consorten en niet zozeer voor transport van data.

Ik wil tussen een server en een client communicatie mogelijk maken, het liefst wat compressie erover om het leed wat te verzachten. Begrijp me goed, die compressie hoeft niet super te zijn, maar op normale tekst/programmeercode moet toch wel een 25% te winnen zijn zonder ingewikkelde zaken.
 
Storeman storeman

storeman storeman

05/06/2008 17:28:00
Quote Anchor link
Ik heb het voor zover wel werkend gekregen, echter heb ik ook de gzip zlib een bestudeerd, dat scheelt behoorlijk qua performance!

Toch maar ff mijn code plaatsen welke misschien nog ooit in de library belandt:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php
// to convert ascii text use this function
function asc2bin($in) #syntax - asc2bin("text to convert");
{
    $out = '';
    
    for ($i = 0, $len = strlen($in); $i < $len; $i++) {
        $out .= sprintf("%08b", ord($in{$i}) );
    }

    
    return $out;
}


//use this function to convert binary back to readable ascii text
function bin2asc($in)#syntax - bin2asc("binary to convert");
{
    $out = '';
    
    for ($i = 0, $len = strlen($in); $i < $len; $i += 8) {
        $out .= chr(bindec(substr($in,$i,8)));
    }

    return $out;
}

function
compressLzw( $input){

    $inputArr = str_split( $input, 1);
    
    $w = NULL;
    $wc = '';
    $dict = array();
    $arrOutput = array();
    $iPos = 0;
    
    for( $iPos; $iPos<256; $iPos++){
        $dict[$iPos] = chr($iPos);
    }

    
    foreach( $inputArr as $char ){
        
        $wc = $w . $char;
        
        if( in_array($wc, $dict) ){
            $w = $wc;
        }
else{
            $dict[$iPos] = $wc;
            $iPos++;
            
            $arrOutput[] = array_search($w, $dict);
            
            $w = $char;
        }
    }

    $arrOutput[] = array_search($w, $dict);
    
    $strBitlength = strlen(decbin($iPos));
    $strOutput = str_pad( $strBitlength, 2, "0", STR_PAD_LEFT);
    
    $strBinOutput = '';
    foreach( $arrOutput as $index ){
        $strBinOutput .= sprintf("%0".$strBitlength."b", $index);
    }

    
    $iPadSize = 8 - strlen($strBinOutput)%8;
    
    $strBinOutput = sprintf("%0" . $iPadSize."b", "0") . $strBinOutput;
    
    return $strOutput . strval($iPadSize) . bin2asc( $strBinOutput );
}

function
decompressLzw( $input ){

    $iBitlength = intval(substr($input, 0, 2));
    $iPadLength = intval(substr($input, 2, 1));
    $input = substr($input, 3 );
    
    $inputBinary = substr(asc2bin($input), $iPadLength);
    $inputArr = str_split( $inputBinary, $iBitlength);
    
    $entry = '';
    $dict = array();
    $iPos = 0;
    
    for( $iPos; $iPos<256; $iPos++){
        $dict[$iPos] = chr($iPos);
    }

    
    
    $w = $output = chr( bindec( array_shift($inputArr) ) );
    
    foreach( $inputArr as $binCode){
        $intVal = bindec($binCode);
        
        if( isset($dict[ $intVal ]) ){
            $entry = $dict[ $intVal ];
        }
elseif( $intVal >= $iPos ){
            $entry = $w . $w{0};
        }
else{
            die('invalid');
        }

        
        $output .= $entry;
        
        $dict[$iPos] = $w . $entry{0};
        $iPos++;
        
        $w = $entry;
    }

    
    return $output;
}
[
/code]
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.