{ Вспомогательные процедуры для компрессии/декомпрессии Лемпеля-Зива (LZ78) } {--------------------------------------------------------------------------- (c) Copyright Aleksandrov O.E., 2000 Molecular Physics department, USTU, Ekaterinsburg, K-2, 620002, RUSSIA phone 75-47-15 E-mail: aleks@dpt.ustu.ru (c) Copyright Александров О.Е., 2000 620002, Екатеринбург, К-2, УГТУ, Кафедра молекулярной физики тел. 75-47-15 E-mail: aleks@dpt.ustu.ru ----------------------------------------------------------------------------} Unit LZMiscFs; INTERFACE USES {$IfDef Delphi}SysUtils,{$EndIf} ComTypes, LZTypes; type tLZCompressedSize=packed record SizeInBytes:tIntEx; BitsRest:tByteBitsNumber; end; tCodeLenghtInc=Low(tCodeLength)..(2*High(tCodeLength)+1); tString4=string[4]; { Увеличение на AInc бит сведений о размере данных в AValue } procedure xInc(var AValue:tLZCompressedSize; AInc:word); {$IfDef Delphi} register; {$EndIf} { Преобразование AByte в символьное представление } function ByteToChr(AByte:tByte):tString4; {$IfDef Delphi} procedure RunError(Errorcode: Byte); type ERunError = class(Exception) public ErrorCode: Byte; end; {$EndIf Def Delphi} IMPLEMENTATION procedure xInc(var AValue:tLZCompressedSize; AInc:word); {$IfNDef Delphi} assembler; asm les bx,AValue mov dl,tLZCompressedSize(es:[bx]).BitsRest; xor dh,dh add dx,AInc mov cx,dx; shr dx,3 and cl,00000111b mov tLZCompressedSize(es:[bx]).BitsRest,cl add tLZCompressedSize(es:[bx]).SizeInBytes.lo,dx adc tLZCompressedSize(es:[bx]).SizeInBytes.hi,0 end; {$Else} register; asm { register!!! => AValue=[EAX]; AInc=DX } movzx ecx,tLZCompressedSize([AValue]).BitsRest add cx,AInc {DX=AInc} mov dl,cl; and dl,00000111b mov tLZCompressedSize([AValue]).BitsRest,dl shr ecx,3 add tLZCompressedSize([AValue]).SizeInBytes.lo,ecx adc tLZCompressedSize([AValue]).SizeInBytes.hi,0 end; {$EndIf} function ByteToChr(AByte:tByte):tString4; var s:tString4; begin case AByte of 32..126,128..254: begin ByteToChr:=Chr(AByte); end; else begin Str(AByte,s); ByteToChr:=s; end; end; end; {$IfDef Delphi} procedure RunError(Errorcode: Byte); var Error: ERunError; begin if Errorcode<>0 then begin Error:=ERunError.CreateFmt('RunError(%d)',[Errorcode]); Error.ErrorCode:=Errorcode; raise Error; end; end; {$EndIf Def Delphi} END.