Code: Select all
'#######################################################
'## Superfast/Supertiny Compression/Decompression ##
'## Original code is by "Jack Qwerty" / 29A, 1998 ##
'## Source: http://29a.host.sk/29a-3/29a-3.2_f ##
'## Cheers to Hutcho for helping with stack issues! ##
'#######################################################
'This is a good example that virus coders ARE capable of
'creating useful things! Why they don't put their efforts
'to such things more often, I have no idea, you'd have
'to ask a psychologist. 8-)
'#######################################################
FUNCTION Compress(BYVAL ptrInData AS DWORD, BYVAL LenInData AS
DWORD, BYVAL ptrOutData AS DWORD, BYVAL ptrTmpData AS DWORD) AS
DWORD
#REGISTER NONE
! push ptrTmpData
! push LenInData
! push ptrInData
! push ptrOutData
! call Start
! mov FUNCTION, eax
EXIT FUNCTION
Start:
! sub edx, edx
! xchg eax, edx
! pushad
! mov ebp, esp
! and ecx, eax
! mov edi, [ebp+&h30]
! cld
! mov ch, &h40
! push edi
! rep stosd
! sub edx, &h2864E25C
! mov esi, [ebp+&h28]
! jnz pack0
! dec edx
pack0:
! push ecx
! sub ax, &h0AEB6
! mov edi, [ebp+&h24]
! pop ebx
! stosw
! xchg eax, edx
! pop ebp
! stosd
! push edi
! xchg eax, edx
! push esp
pack1:
! test cl, 7
! lodsb
! jnz pack3
! xchg edx, [esp]
! adc ah, dl
! pop edx
! xchg edi, [esp]
! ror edx, 1
! mov [edi], ah
! jc pack2
! xor edx, &h2C047C3E
pack2:
! pop edi
! mov ah, &h0FF
! push edi
! xor edx, &h76C52B8D
! inc edi
! push edx
pack3:
! cmp al, [ebx+ebp]
! jz pack5
! ror edx, 1
! mov [ebx+ebp], al
! jnc pack4
! xor edx, &h2C047C3E
pack4:
! mov bh, al
! xor edx, &h5AC157B3
! adc al, dl
! stosb
! mov al, bh
! stc
pack5:
! inc ecx
! mov bh, bl
! rcl ah, 1
! cmp ecx, [esp+&h34]
! mov bl, al
! jc pack1
! ror ah, cl
! pop ebx
! add ah, bl
! pop esi
! mov ebp, esp
! sub edi, [ebp+&h24]
! mov [ebp+&h14], edx
! xchg ah, [esi]
! add [ebp+&h1C], edi
! popad
! ret &h10
END FUNCTION
FUNCTION Decompress(BYVAL ptrInData AS DWORD, BYVAL LenInData AS
DWORD, BYVAL ptrOutData AS DWORD, BYVAL ptrTmpData AS DWORD) AS
DWORD
#REGISTER NONE
! push ptrTmpData
! push LenInData
! push ptrInData
! push ptrOutData
! call Start
! mov FUNCTION, eax
EXIT FUNCTION
Start:
! sub eax, eax
! pushad
! mov ebp, esp
! and ecx, eax
! mov edi, [ebp+&h30]
! cld
! mov ch, &h40
! push edi
! rep stosd
! mov esi, [ebp+&h28]
! xchg ebx, eax
! add ecx, [ebp+&h2C]
! lodsw
! mov edi, [ebp+&h24]
! add ecx,-6
! pop ebp
! lodsd
! xchg eax, edx
unpack0:
! test byte ptr [esp+&h1C], 7
! jnz unpack2
! ror edx, 1
! jecxz unpack5
! jnc unpack1
! xor edx, &h2C047C3E
unpack1:
! lodsb
! dec ecx
! xor edx, &h5AC157B3
! sbb al, dl
! mov ah, al
unpack2:
! shl ah, 1
! inc byte ptr [esp+&h1C]
! jnc unpack4
! ror edx, 1
! jecxz unpack5
! jc unpack3
! xor edx, &h2C047C3E
unpack3:
! lodsb
! dec ecx
! xor edx, &h76C52B8D
! sbb al, dl
! mov [ebx+ebp], al
unpack4:
! mov al, [ebx+ebp]
! mov bh, bl
! stosb
! mov bl, al
! jmp unpack0
! dec edx
! push ecx
unpack5:
! sub edi, [esp+&h24]
! mov [esp+&h1C], edi
! popad
! ret &h10
END FUNCTION
FUNCTION PBMAIN() AS LONG
DIM sInData AS STRING, sOutData AS STRING, sTmpData AS STRING *
65535, OutSize AS DWORD
'// Data to compress
sInData = REPEAT$(1000, "testing")
'// Compress it ...
sOutData = STRING$(LEN(sInData),0)
OutSize = Compress(BYVAL STRPTR(sInData), BYVAL LEN(sInData),
BYVAL STRPTR(sOutData), BYVAL VARPTR(sTmpData))
IF OutSize > LEN(sInData) THEN
STDOUT "Unable to compress this data (probably not enough
repetition)."
WAITKEY$
EXIT FUNCTION
END IF
STDOUT "Original size = " & STR$(LEN(sInData)) & " bytes"
STDOUT "Compressed size = " & STR$(OutSize) & " bytes (" &
TRIM$(STR$((OutSize / LEN(sInData)) * 100)) & "%)"
sInData = LEFT$(sOutData, OutSize) '// sInData now contains the
compressed string.
'// Decompress sInData
sOutData = STRING$(LEN(sInData) * 10,0) '// allocate enough space
OutSize = Decompress(BYVAL STRPTR(sInData), BYVAL LEN(sInData),
BYVAL STRPTR(sOutData), BYVAL VARPTR(sTmpData))
STDOUT "Decompressed size = " & STR$(OutSize) & " bytes"
sInData = LEFT$(sOutData, OutSize)
WAITKEY$
END FUNCTION
Code: Select all
OpenConsole()
Procedure.l Compress(PtrInData.l,LenInData.l,PtrOutData.l,PtrTmpData.l)
EndProcedure
Procedure.l Decompress(PtrInData.l,LenInData.l,PtrOutData.l,PtrTmpData.l)
EndProcedure
sInData.s=Space(1000) ;Input buffer (maybe AllocateMemory would be better)
sOutData.s=Space(Len(sInData.s)*10) ;Compressed string
*TmpData.l=AllocateMemory(0,65535,0) ;Working buffer
stringa$="Nel mezzo del cammin di nostra vita" ;String to compress
;// Data to compress
For i.b=1 To Len(stringa$)
PokeB(@sInData.s+i.b-1,Asc(Mid(stringa$,i.b,1)))
Next
; Why DOESN'T [ CopyMemoryString("Test",@sInData.s) ] work ?
PrintN(sInData.s)
;// Compress it ...
;OutSize.l = Compress(@sInData.s, Len(sInData.s), @sOutData.s, *TmpData.l)
If OutSize.l > Len(sInData.s)
PrintN("Unable to compress this data (probably not enough repetition).")
Else
PrintN("Original size = "+Str(Len(sInData.s))+" bytes")
PrintN("Compressed size = "+Str(OutSize.l)+" bytes ("+Trim(Str((OutSize.l / Len(sInData.s)) * 100))+"%)")
sInData.s = Left(sOutData.s,OutSize.l) ;sInData now contains the compressed string.
;// Decompress sInData
;OutSize.l = Decompress(@sInData.s, Len(sInData.s), @sOutData.s, *TmpData.l)
PrintN("Decompressed size = "+Str(OutSize.l)+" bytes")
sInData.s = Left(sOutData.s, OutSize.l)
EndIf
tasto$=Input()
CloseConsole()
End



