Supertiny
Algorithm creator(s)
"Jacky Qwerty / 29A"
PB author(s)
Wayne Diamond
Description
The smallest (code size) and fastest compression/decompression algorithm at the PB Crypto Archives. Compression is usually better than RLE, but not as good as most other algorithms as the algorithm was designed for small size and fast execution speed rather than strong compression.
Note
n/a
Source
https://forum.powerbasic.com/forum/user-to-user-discussions/source-code/24661-superfast-supertiny-de-compression-algorithm?t=24012
See also
n/a
Source Code
Download source code file supertiny.bas (Right-click -> "Save as ...")
'#######################################################
'## 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