28 lines
950 B
Text
28 lines
950 B
Text
fcn lzwCompress(uncompressed){ // text-->list of 12 bit ints
|
|
dictionary:=(256).pump(Dictionary(),fcn(n){ return(n.toChar(),n) });
|
|
w,compressed:="",List();
|
|
foreach c in (uncompressed){
|
|
wc:=w+c;
|
|
if(dictionary.holds(wc)) w=wc;
|
|
else{
|
|
compressed.append(dictionary[w]); // 12 bits
|
|
dictionary[wc]=dictionary.len();
|
|
w=c;
|
|
}
|
|
}
|
|
if(w) compressed.append(dictionary[w]);
|
|
compressed
|
|
}
|
|
fcn lzwUncompress(compressed){ // compressed data-->text
|
|
dictionary:=(256).pump(Dictionary(),fcn(n){ return(n,n.toChar()) });
|
|
w,decommpressed:=dictionary[compressed[0]],Data(Void,w);
|
|
foreach k in (compressed[1,*]){
|
|
if(dictionary.holds(k)) entry:=dictionary[k];
|
|
else if(k==dictionary.len()) entry:=w+w[0];
|
|
else throw(Exception.ValueError("Invalid compressed data"));
|
|
decommpressed.append(entry);
|
|
dictionary.add(dictionary.len(),w+entry[0]);
|
|
w=entry;
|
|
}
|
|
decommpressed.text
|
|
}
|