1. -- RLE8 compression as used in windows bitmaps (BMPs)
  2. -- see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
  3.  
  4. --------------------------------------
  5. --
  6. --------------------------------------
  7. on RLE8_bmp_encode(input, lineWidth)
  8.  
  9.   chunks = []
  10.  
  11.   n = input.length / lineWidth - 1
  12.   if input.length mod lineWidth>0 then n=n+1
  13.  
  14.   repeat with k = 0 to n
  15.    
  16.     str = input.char[lineWidth*k+1..lineWidth*k+lineWidth]
  17.     cnt = str.length
  18.    
  19.     out = ""
  20.    
  21.     repeat with i = 1 to cnt
  22.       c = str.char[i]
  23.       num = 1
  24.       repeat while true
  25.         if i+1>cnt then exit repeat
  26.         if str.char[i+1]<>c then exit repeat
  27.         i = i + 1
  28.         num=num+1
  29.       end repeat
  30.      
  31.       if num>1 OR i=cnt then
  32.         put numtochar(num) after out
  33.         put c after out
  34.       else
  35.        
  36.         if i>cnt-3 then
  37.          
  38.           put numtochar(1) after out
  39.           put str.char[i] after out
  40.          
  41.         else if str.char[i+1]<>str.char[i+2] AND str.char[i+2]<>str.char[i+3] then -- escape to absolute mode
  42.          
  43.           put numtochar(0) after out
  44.           put numtochar(0) after out --> change later
  45.           cntPos = out.length
  46.          
  47.           num = 0
  48.           repeat while true
  49.             if i+1>cnt then
  50.               put str.char[i] after out
  51.               i=i+1
  52.               num=num+1
  53.               exit repeat
  54.             end if
  55.            
  56.             if str.char[i]=str.char[i+1] then exit repeat
  57.            
  58.             put str.char[i] after out
  59.             i=i+1
  60.             num=num+1
  61.           end repeat
  62.          
  63.           put numtochar(num) into char cntPos of out
  64.           if (num mod 2) then put numtochar(0) after out
  65.           i=i-1
  66.          
  67.         else -- don't escape to absolute mode
  68.          
  69.           put numtochar(1) after out
  70.           put str.char[i] after out
  71.          
  72.         end if
  73.        
  74.       end if
  75.      
  76.     end repeat
  77.    
  78.     if k<n then put numtochar(0)&numtochar(0) after out -- end of line
  79.    
  80.     chunks.add(out)
  81.   end repeat
  82.  
  83.   -- assemble as large string
  84.   ret = ""
  85.   repeat with str in chunks
  86.     put str after ret
  87.   end repeat
  88.  
  89.   -- add "end of bitmap" marker
  90.   put numtochar(0)&numtochar(1) after ret
  91.  
  92.   return ret
  93. end
  94.  
  95. --------------------------------------
  96. --
  97. --------------------------------------
  98. on RLE8_bmp_decode (str)
  99.  
  100.   out = ""
  101.   cnt = str.length
  102.   repeat with i = 1 to cnt
  103.    
  104.     o = chartonum(str.char[i])
  105.     case (o) of
  106.       0: -- ESCAPE
  107.        
  108.         i=i+1
  109.        
  110.         case (chartonum(str.char[i])) of
  111.           0: -- put "NEW LINE"
  112.           1: -- put "END OF FILE"
  113.           2: -- put "DELTA"
  114.             i=i+2
  115.            
  116.           otherwise: -- ABSOLUTE MODE
  117.             num = chartonum(str.char[i])
  118.             repeat with j = 1 to num
  119.               i=i+1
  120.               put str.char[i] after out
  121.             end repeat
  122.             if (num mod 2) then i = i + 1
  123.         end case
  124.        
  125.       otherwise:
  126.         i=i+1
  127.         c = str.char[i]
  128.         repeat with j=1 to o
  129.           put c after out
  130.         end repeat
  131.        
  132.     end case
  133.    
  134.   end repeat
  135.   return out
  136. end
  137.  
  138.  
  139.  
[raw code]