Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.079 Beiträge
Delphi 12 Athens
|
AW: Komprimierung : Wie geht das?
15. Jul 2010, 23:00
doch mal getestet:
die Längenberechnung war erstmal falsch, so daß da zuwenig gelöscht wurde und es bei mehrfachen #0 dann zur Endlosschleife kam, da die #0 immer wieder eingefügt wurde.
- AnsiString, wegen den Unicode-Delphis und da es hier für einen "Byte-Stream" verwendet wird
- Dec(a, i);
, zur Längenberechnung war falsch ... mußte Dec(a, i - 1);
sein
- und dann noch so einige andere Kleinigkeiten
Delphi-Quellcode:
function LauflängenKodierung(S: AnsiString): AnsiString;
var
i, a: Integer;
c: AnsiChar;
begin
i := 1;
while i <= Length(S) do
if (i < Length(S)) and (S[i] = S[i + 1]) then begin
c := S[i];
a := i + 1;
while (a < Length(S)) and (c = S[a + 1]) and (a - i < 65790) do Inc(a);
Dec(a, i - 1);
if (a < 4) and (c <> #0) then begin
Inc(i, a);
Continue;
end;
Delete(S, i, a);
if a < 256 then begin
Insert(#0 + AnsiChar(a - 1) + C, S, i);
Inc(i, 3);
end else begin
Dec(a, 256);
Insert(#0#255 + AnsiChar(a div 256) + AnsiChar(a mod 256) + C, S, i);
Inc(i, 5);
end;
end else if S[i] = #0 then begin
Insert(#0, S, i);
Inc(i, 2);
end else Inc(i);
Result := S;
end;
function LauflängenDekodierung(S: AnsiString): AnsiString;
var
i, a: Integer;
c: AnsiChar;
begin
i := 1;
while i < Length(S) do
if S[i] = #0 then begin
a := Ord(S[i + 1]);
if a = 0 then begin
Delete(S, i, 1);
Inc(i);
end else if a < 255 then begin
Inc(a);
c := S[i + 2];
Delete(S, i, 3);
Insert(StringOfChar(c, a), S, i);
Inc(i, a);
end else begin
a := Ord(S[i + 2]) * 256 + Ord(S[i + 3]) + 256;
c := S[i + 4];
Delete(S, i, 5);
Insert(StringOfChar(c, a), S, i);
Inc(i, a);
end;
end else Inc(i);
Result := S;
end;
procedure TForm5.FormCreate(Sender: TObject);
var S: TStream;
A, B, C: AnsiString;
begin
S := TFileStream.Create(' test.bmp', fmOpenRead or fmShareDenyNone);
SetLength(A, S.Size);
S.ReadBuffer(A[1], S.Size);
S.Free;
B := LauflängenKodierung(A);
C := LauflängenDekodierung(B);
ShowMessage(Format(' %d=%d (%d) ... %d (%.1n%%)',
[Length(A), Length(C), Ord(A = C), Length(B), Length(B) / Length(A) * 100]));
end;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
Geändert von himitsu (15. Jul 2010 um 23:10 Uhr)
|