2024-04-29

Navigation

Skip Navigation Links

Hash algorithms

Asymmetric Algorithms

Symmetric Cipher Algorithms

Encoding Algorithms

Compression Algorithms

Pseudo Random Number Algorithms

Steganography

Library Wrappers

String Comparison

Others

Syntax highlighting by Prism
PBCrypto.com Mirror

RLE

Algorithm creator(s)

n/a


PB author(s)

Petr Schreiber, Ralph Berger


Description

RLE (run length encoding) compression/decompression.


Note

Most effective on bitmaps.


Source

https://forum.powerbasic.com/forum/user-to-user-discussions/source-code/23182-rle-compression-for-pbcc-pbdll?t=22569


See also


Source Code

Download source code file rle.bas (Right-click -> "Save as ...")

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' rle compression
' not too fast - if you need more speed try using strptr
' in for x - loop
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' (in the first version there is a problem - in large fields of equal chars
' it sometimes cautions a mistake (control char on a place of third char)
' normally is sequention controlChar_numberOfChars_Char and bad sequention
' was in several files  controlChar_numberOfChars_controlChar !!)
' Compression is now faster (not enough!)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
FUNCTION RLECompress(BYVAL text1 AS STRING) AS STRING

LOCAL x AS INTEGER
LOCAL fchar AS INTEGER
LOCAL flag AS LONG
LOCAL maxlen AS INTEGER
LOCAL test AS INTEGER
LOCAL START AS LONG
LOCAL ENDE AS LONG
LOCAL tt AS LONG
LOCAL procstr AS STRING
LOCAL prevChr AS BYTE
LOCAL aktChr AS BYTE
LOCAL countChr AS LONG
LOCAL maxChr AS LONG
LOCAL flagChr AS BYTE
LOCAL START2 AS LONG

''''' count characters used
DIM cUsed(0:255) AS LONG
DIM cSmysl(0:255) AS LONG
rem in cSmysl field are characters with min.one repetition

START = STRPTR(text1)
ENDE = START + LEN(TEXT1)

maxChr=0
countChr=1
FOR tt = START TO ENDE
    aktChr=PEEK( tt )
    INCR cUsed(aktChr)
        IF tt=START THEN
            prevChr=aktChr
            flagChr=0
        ELSE
           IF prevChr=aktChr THEN
rem Is that a sequention or only one char?
              INCR countChr
              maxChr=MAX(maxChr,countChr)
rem Maximum repeated chars
           ELSE
              countChr=1
              flagChr=0
           END IF
              prevChr=aktChr
              IF flagChr=0 AND countChr>3 THEN
                 flagChr=1
                 INCR cSmysl(aktChr)
rem aktChr is in the file with repetition min.4 chars
              END IF
        END IF
NEXT tt
''''' no unused char -> no compression
maxChr=MIN(maxChr,255) 'maxChr can be max 255 - type overflow (byte)
IF maxChr < 4 THEN
rem no usefull repetition
    FUNCTION = text1
    EXIT FUNCTION
END IF

''''' unused char is startmark for rle
FOR fchar = 255 TO 0 STEP -1
    IF cUsed(fchar) = 0 THEN EXIT FOR
NEXT fchar

''''' no unused char -> no compression
IF fchar < 0 THEN
    FUNCTION = text1
    EXIT FUNCTION
END IF

procstr = text1

''''' loop through all chars
FOR x = 0 TO 255
    IF cUsed(x) < 4 THEN ITERATE FOR ''' not interesting, skip to next char
    IF cSmysl(x)=0 THEN ITERATE FOR    'not interesting (group of chars < 4), skip to next char
    maxlen = MAX(MIN(maxChr, cUsed(x)), 5)''' Range 5 to max length of repetition
        FOR test = maxlen TO 4 STEP -1
            flag = INSTR(procStr,REPEAT$( test , CHR$(x))) ''' drill down search lenght
            IF flag = 0 THEN ITERATE FOR
''' start rle compression
                    WHILE flag<>0
                          START2=STRPTR(procStr)

                        IF PEEK(START2+flag-3)=fchar THEN
rem                        IF MID$(procStr,flag-2,1)=CHR$(fchar) THEN 'slower alternative
rem Is position of flag the third position of previous controlChars ? - I must skip it or shift it
to right
                           IF test>4 THEN
                                  INCR flag
                                  testnov&=test-1
rem I shift it to right
                           ELSE
rem I skip it
                                  ITERATE FOR
                           END IF
                        ELSE
                                  testnov&=test
                        END IF
                       
procStr=LEFT$(procStr,flag-1)+CHR$(fchar,testnov&,x)+MID$(procstr,flag+testnov&)
                        flag = INSTR( flag+2, procStr, REPEAT$( testnov& , CHR$(x)))
rem I find next "test" sequention
                    WEND
REM             next code is potentialy dangerous - no control about left third byte (fchar)
rem             function REPLACE is "blind" to control chars in a text
REM                REPLACE MID$(procStr,flag,test) _ ''' found char * len
REM                        WITH CHR$(fchar,test,x) _ ''' RLE sign,len,char
REM                        IN procStr
        NEXT test
NEXT x
    FUNCTION = CHR$(255,255,fchar,255) + procStr
END FUNCTION

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' decompress rle encoded strings
' this one should be fast enough
'
FUNCTION RLEDeCompress(text1 AS STRING) AS STRING

LOCAL fchar AS STRING, _
procStr AS STRING, _
flag AS LONG

''' check for magic header
IF ASC(MID$(TEXT1,1,1)) <> 255 OR _
            ASC(MID$(TEXT1,2,1)) <> 255 OR _
            ASC(MID$(TEXT1,4,1)) <> 255 THEN
REM                PRINT "It is not RLE file"
            FUNCTION = text1
            EXIT FUNCTION
ELSE
    fChar = MID$(TEXT1,3,1)
    procStr = MID$(TEXT1,5)
END IF

''' replace rle entries with real values
DO
    flag = INSTR(procStr,fChar)
        IF flag = 0 THEN
            EXIT LOOP
        ELSE
rem without a previous control in Compression is this function dangerous
rem (sequention controlChar_numberOfChars_controlChar is a suicide for a file )
            REPLACE MID$(procStr,flag,3) _ ''' RLE sign,len,char
            WITH REPEAT$(ASC(MID$(procStr,flag+1,1)), MID$(procStr, flag+2,1)) _ ''' create char *
len
            IN procStr
        END IF
LOOP

FUNCTION = procStr

END FUNCTION

Mirror provided by Knuth Konrad