[fpc-pascal] LZMA Algorithm fails on 64bit
Matthias Klumpp
matthias at nlinux.org
Mon Jan 25 14:27:00 CET 2010
> The stream is compressed with 32 bits version ? Or are the 64 bits
> compressed files the ones that fail to be decompressed in 64 bits also
> ?
I cpmpressed a stream with the 64bits version. I can uncompress it
successfully on 32bit, but not on 64bit.
I haven't tried to decompress 32bit compressed files under 64bit, but
decompressing files compressed under 64bit does not work under 64bit, but
on 32bit.
> So the question a 32 bits compressed LZMA can be decompressed with 32
> bits "decode", and the same stream decompressed with the 64 bits
> version ?
I'll try, but I think it won't work.
I included the Decoder function at the end of this file...
##################################################
function TLZMADecoder.Code(const
inStream,outStream:TStream;outSize:int64):boolean;
var state,rep0,rep1,rep2,rep3:Int64;
nowPos64:Int64;
prevByte:byte;
posState:int64;
decoder2:TLZMADecoder2;
len,distance,posSlot,numDirectBits:Int64;
lpos:int64;
progint:int64;
begin
DoProgress(LPAMax,outSize);
m_RangeDecoder.SetStream(inStream);
m_OutWindow.SetStream(outStream);
self.Init;
state := ULZMABase.StateInit;
rep0 := 0; rep1 := 0; rep2 := 0; rep3 := 0;
nowPos64 := 0;
prevByte := 0;
progint:=outsize div CodeProgressInterval;
lpos:=progint;
while (outSize < 0) or (nowPos64 < outSize) do
begin
if (nowPos64 >=lpos) then begin
DoProgress(LPAPos,nowPos64);
lpos:=lpos+progint;
end;
posState := nowPos64 and m_PosStateMask;
if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state shl
ULZMABase.kNumPosStatesBitsMax) + posState) = 0) then
begin
decoder2 := m_LiteralDecoder.GetDecoder(nowPos64, prevByte);
if not ULZMABase.StateIsCharState(state) then
prevByte := decoder2.DecodeWithMatchByte(m_RangeDecoder,
m_OutWindow.GetByte(rep0))
else prevByte := decoder2.DecodeNormal(m_RangeDecoder);
m_OutWindow.PutByte(prevByte);
state := ULZMABase.StateUpdateChar(state);
inc(nowPos64);
end else
begin
if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) = 1) then
begin
len := 0;
if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) = 0)
then begin
if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders,
(state shl ULZMABase.kNumPosStatesBitsMax) + posState) = 0) then
begin
state := ULZMABase.StateUpdateShortRep(state);
len := 1;
end;
end else
begin
if m_RangeDecoder.DecodeBit(m_IsRepG1Decoders,
state) = 0 then
distance := rep1
else
begin
if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders,
state) = 0) then
distance := rep2
else
begin
distance := rep3;
rep3 := rep2;
end;
rep2 := rep1;
end;
rep1 := rep0;
rep0 := distance;
end;
if len = 0 then begin
len := m_RepLenDecoder.Decode(m_RangeDecoder, posState)
+ ULZMABase.kMatchMinLen;
state := ULZMABase.StateUpdateRep(state);
end;
end else begin
rep3 := rep2;
rep2 := rep1;
rep1 := rep0;
len := ULZMABase.kMatchMinLen +
m_LenDecoder.Decode(m_RangeDecoder, posState);
state := ULZMABase.StateUpdateMatch(state);
posSlot :=
m_PosSlotDecoder[ULZMABase.GetLenToPosState(len)].Decode(m_RangeDecoder);
if posSlot >= ULZMABase.kStartPosModelIndex then begin
numDirectBits := (posSlot shr 1) - 1;
rep0 := ((2 or (posSlot and 1)) shl numDirectBits);
if posSlot < ULZMABase.kEndPosModelIndex then
rep0 := rep0 +
UBitTreeDecoder.ReverseDecode(m_PosDecoders,
rep0 - posSlot - 1, m_RangeDecoder,
numDirectBits)
else
begin
rep0 := rep0 +
(m_RangeDecoder.DecodeDirectBits(
numDirectBits -
ULZMABase.kNumAlignBits) shl ULZMABase.kNumAlignBits);
rep0 := rep0 +
m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
if rep0 < 0 then
begin
if rep0 = -1 then
break;
result:=false;
exit;
end;
end;
end else rep0 := posSlot;
end;
if (rep0 >= nowPos64) or (rep0 >= m_DictionarySizeCheck) then
begin
m_OutWindow.Flush();
result:=false;
exit;
end;
m_OutWindow.CopyBlock(rep0, len);
nowPos64 := nowPos64 + len;
prevByte := m_OutWindow.GetByte(0);
end;
end;
m_OutWindow.Flush();
m_OutWindow.ReleaseStream();
m_RangeDecoder.ReleaseStream();
DoProgress(LPAPos,nowPos64);
result:=true;
end;
More information about the fpc-pascal
mailing list