D
dingbaosheng
Unregistered / Unconfirmed
GUEST, unregistred user!
如题~~~~~
.prevchar=nochar then
begin
if rembitcount<7 then
begin
tmpcode:=(rembits shl (8-rembitcount)) or (copybyte shl (7-rembitcount)) or ((code shr (rembitcount+1)) and ($7F shr rembitcount));
putbyte(tmpcode);
inc(fwrote);
rembits:= code and ($FF shr(7-rembitcount));
inc(rembitcount);
end
else if rembitcount=7 then
begin
tmpcode:=(rembits shl 1) or copybyte;
putbyte(tmpcode);
inc(fwrote,2);
putbyte(code);
rembits:=empty;
rembitcount:=0;
end;
end
else
begin
tmpcode:=(rembits shl (8-rembitcount)) or (compbyte shl(7-rembitcount)) or (code shr (5+rembitcount) and ($7F shr rembitcount));
putbyte(tmpcode);
inc(fwrote);
rembitcount:=rembitcount+5;
if rembitcount<8 then
rembits:=code and($FF shr(8-rembitcount));
if rembitcount>=8 then
begin
rembits:=(code shr(rembitcount-8)) and $FF;
inc(fwrote);
putbyte(rembits);
rembitcount:=rembitcount-8;
rembits:=code and ($FF shr(8-rembitcount));
end;
end;
if lbyte and (rembitcount>0) then
begin
tmpcode:=((rembits and ($FF shr (8-rembitcount))) shl (8-rembitcount));
putbyte(tmpcode);
inc(fwrote);
end;
end;
function getcode:integer;
var
part1,part2:integer;
iscomp:integer;
c1,c2:integer;
begin
result:=eofchar;
if (fread=fsize) and (rembitcount=0) then
begin
result:=eofchar;
exit;
end;
if rembitcount=0 then
begin
part1:=getbyte;
part2:=getbyte;
iscomp:=(part1 shr 7) and 1;
if iscomp=1 then
begin
c1:=part1 and $7F;
c2:=(part2 shr 3) and $1F;
rembits:=part2 and $7;
rembitcount:=3;
result:=(c1 shl 5) or c2;
end
else if iscomp=0 then
begin
c1:=part1 and $7F;
c2:=(part2 shr 7) and $1;
result:=(c1 shl 1) or c2;
rembits:=part2 and $7F;
rembitcount:=7;
end;
end
else if rembitcount=1 then
begin
part1:=getbyte;
iscomp:=rembits;
if iscomp=1 then
begin
part2:=getbyte;
c1:=part1 and $FF;
c2:=(part2 shr 4) and $F;
rembits:=part2 and $F;
rembitcount:=4;
result:=(c1 shl 4) or c2;
end
else if iscomp=0 then
begin
c1:=part1 and $FF;
result:=c1;
rembits:=empty;
rembitcount:=0;
end;
end
else if rembitcount=2 then
begin
part1:=getbyte;
iscomp:=(rembits shr 1) and 1;
if iscomp=1 then
begin
part2:=getbyte;
c1:=((rembits and 1) shl 7) or ((part1 shr 1) and $7F);
c2:=((part1 and 1) shl 3) or ((part2 shr 5) and $7);
rembits:=part2 and $1F;
rembitcount:=5;
result:=(c1 shl 4) or (c2 and $F);
end
else if iscomp=0 then
begin
c1:=((rembits and 1) shl 7) or ((part1 shr 1) and $7F);
result:=c1;
rembits:=part1 and 1;
rembitcount:=1;
end;
end
else if rembitcount=3 then
begin
part1:=getbyte;
iscomp:=(rembits shr 2) and 1;
if iscomp=1 then
begin
part2:=getbyte;
c1:=((rembits and $3) shl 6) or ((part1 shr 2) and $3F);
c2:=((part1 and $3) shl 2) or ((part2 shr 6) and $3);
rembits:=part2 and $3F;
rembitcount:=6;
result:=(c1 shl 4) or (c2 and $F);
end
else if iscomp=0 then
begin
c1:=((rembits and $3) shl 6) or ((part1 shr 2) and $3F);
result:=c1;
rembits:=part1 and $3;
rembitcount:=2;
end;
end
else if rembitcount=4 then
begin
part1:=getbyte;
iscomp:=(rembits shr 3) and 1;
if iscomp=1 then
begin
part2:=getbyte;
c1:=((rembits and $7) shl 5) or ((part1 shr 3) and $1F);
c2:=((part1 and $7) shl 1) or ((part2 shr 7) and $1);
rembits:=part2 and $7F;
rembitcount:=7;
result:=(c1 shl 4) or (c2 and $F);
end
else if iscomp=0 then
begin
c1:=((rembits and $7) shl 5) or ((part1 shr 3) and $1F);
result:=c1;
rembits:=part1 and $7;
rembitcount:=3;
end;
end
else if rembitcount=5 then
begin
part1:=getbyte;
iscomp:=(rembits shr 4) and 1;
if iscomp=1 then
begin
c1:=((rembits and $F) shl 4) or ((part1 shr 4) and $F);
c2:=part1 and $F;
rembits:=empty;
rembitcount:=0;
result:=(c1 shl 4) or (c2 and $F);
end
else if iscomp=0 then
begin
c1:=((rembits and $F) shl 4) or ((part1 shr 4) and $F);
result:=c1;
rembits:=part1 and $F;
rembitcount:=4;
end;
end
else if rembitcount=6 then
begin
part1:=getbyte;
iscomp:=(rembits shr 5) and 1;
if iscomp=1 then
begin
c1:=((rembits and $1F) shl 3) or ((part1 shr 5) and $7);
c2:=(part1 shr 1) and $F;
rembits:=part1 and 1;
rembitcount:=1;
result:=(c1 shl 4) or (c2 and $F);
end
else if iscomp=0 then
begin
c1:=((rembits and $1F) shl 3) or ((part1 shr 5) and $7);
result:=c1;
rembits:=part1 and $1F;
rembitcount:=5;
end;
end
else if rembitcount=7 then
begin
part1:=getbyte;
iscomp:=(rembits shr 6) and 1;
if iscomp=1 then
begin
c1:=((rembits and $3F) shl 2) or ((part1 shr 6) and $3);
c2:=(part1 shr 2) and $F;
rembits:=part1 and $3;
rembitcount:=2;
result:=(c1 shl 4) or (c2 and $F);
end
else if iscomp=0 then
begin
c1:=((rembits and $3F) shl 2) or ((part1 shr 6) and $3);
result:=c1;
rembits:=part1 and $3F;
rembitcount:=6;
end;
end;
end;
procedure compress;
var
c,wc,w:integer;
begin
initialize;
c:=getbyte;
w:=findstring(nochar,c);
c:=getbyte;
while fread<=fsize-1 do
begin
if lastbyte then
begin
putcode(w);
lastbyte:=false;
InitializeStringtable;
c:=getbyte;
w:=findstring(nochar,c);
c:=getbyte;
end;
wc:=findstring(w,c);
if wc=endlist then
begin
lastbyte:=not(MakeTableEntry(w,c));
putcode(w);
w:=findstring(nochar,c);
end
else
w:=wc;
if not lastbyte then
c:=getbyte;
end;
putcode(w,true);
end;
procedure decompress;
var
unknown:boolean;
finchar,lastchar:integer;
code,oldcode,incode:integer;
c,tempc:integer;
begin
initialize;
unknown:=false;
lastchar:=empty;
oldcode:=getcode;
code:=oldcode;
c:=stringtable[code].nextchar;
putbyte(c);
finchar:=c;
incode:=getcode;
while incode<>eofchar do
begin
if lastbyte then
begin
lastbyte:=false;
InitializeStringTable;
stackpointer:=0;
unknown:=false;
lastchar:=empty;
oldcode:=getcode;
code:=oldcode;
c:=stringtable[code].nextchar;
putbyte(c);
finchar:=c;
incode:=getcode;
end;
code:=incode;
if not stringtable[code].used then
begin
lastchar:=finchar;
code:=oldcode;
unknown:=true;
end;
while(stringtable[code].prevchar<>nochar) do
begin
push(stringtable[code].nextchar);
if lzwerr=true then
break;
code:=stringtable[code].prevchar;
end;
if lzwerr=true then
break;
finchar:=stringtable[code].nextchar;
putbyte(finchar);
pop(tempc);
while(tempc<>empty) do
begin
putbyte(tempc);
pop(tempc);
end;
if unknown then
begin
finchar:=lastchar;
putbyte(finchar);
unknown:=false;
end;
lastbyte:=not(maketableentry(oldcode,finchar));
if not lastbyte then
begin
oldcode:=incode;
incode:=getcode;
end
end;
end;
procedure push(c:integer);
var
s:string;
begin
if stackpointer<4096 then
begin
inc(stackpointer);
stack[stackpointer]:=char(c);
end;
if stackpointer>=4096 then
begin
s:='Stack full at ' +inttostr(inbufpos);
lzwerr:=true;
showmessage(s);
end;
end;
procedure pop(var c:integer);
begin
if stackpointer>0 then
begin
c:=integer(stack[stackpointer]);
dec(stackpointer);
end
else
c:=empty;
end;
end.
-------------------------------------------------------------------------------
To compress the file add the following code to a button
openinputfile('C:/cdidxtmp/myfile.exe');
openoutputfile('C:/cdidxtmp/myfile.bak');
initialize;
compress;
To Decompress
openinputfile('C:/cdidxtmp/myfile.bak');
openoutputfile('C:/cdidxtmp/myfile.exe');
initialize;
decompress;
欢迎访问vcl控件讨论区:http://vcl.xilubbs.com