-- RLE8 compression as used in windows bitmaps (BMPs)
-- see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
--------------------------------------
--
--------------------------------------
on RLE8_bmp_encode(input, lineWidth)
chunks = []
n = input.length / lineWidth - 1
if input.length mod lineWidth>0 then n=n+1
repeat with k = 0 to n
str = input.char[lineWidth*k+1..lineWidth*k+lineWidth]
cnt = str.length
out = ""
repeat with i = 1 to cnt
c = str.char[i]
num = 1
repeat while true
if i+1>cnt then exit repeat
if str.char[i+1]<>c then exit repeat
i = i + 1
num=num+1
end repeat
if num>1 OR i=cnt then
put numtochar(num) after out
put c after out
else
if i>cnt-3 then
put numtochar(1) after out
put str.char[i] after out
else if str.char[i+1]<>str.char[i+2] AND str.char[i+2]<>str.char[i+3] then -- escape to absolute mode
put numtochar(0) after out
put numtochar(0) after out --> change later
cntPos = out.length
num = 0
repeat while true
if i+1>cnt then
put str.char[i] after out
i=i+1
num=num+1
exit repeat
end if
if str.char[i]=str.char[i+1] then exit repeat
put str.char[i] after out
i=i+1
num=num+1
end repeat
put numtochar(num) into char cntPos of out
if (num mod 2) then put numtochar(0) after out
i=i-1
else -- don't escape to absolute mode
put numtochar(1) after out
put str.char[i] after out
end if
end if
end repeat
if k<n then put numtochar(0)&numtochar(0) after out -- end of line
chunks.add(out)
end repeat
-- assemble as large string
ret = ""
repeat with str in chunks
put str after ret
end repeat
-- add "end of bitmap" marker
put numtochar(0)&numtochar(1) after ret
return ret
end
--------------------------------------
--
--------------------------------------
on RLE8_bmp_decode (str)
out = ""
cnt = str.length
repeat with i = 1 to cnt
o = chartonum(str.char[i])
case (o) of
0: -- ESCAPE
i=i+1
case (chartonum(str.char[i])) of
0: -- put "NEW LINE"
1: -- put "END OF FILE"
2: -- put "DELTA"
i=i+2
otherwise: -- ABSOLUTE MODE
num = chartonum(str.char[i])
repeat with j = 1 to num
i=i+1
put str.char[i] after out
end repeat
if (num mod 2) then i = i + 1
end case
otherwise:
i=i+1
c = str.char[i]
repeat with j=1 to o
put c after out
end repeat
end case
end repeat
return out
end