Code:
'#######################################################
'## superfast/supertiny compression/decompression ##
'## adapted for powerbasic by wayne diamond, sep 2003 ##
'## 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-)
'#######################################################
'ready to compile in pbcc3. to compile with pbwin, replace
'stdout with msgbox and delete the call to waitkey$.
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
[this message has been edited by wayne diamond (edited september 30, 2003).]