1. -- RLE-Compression for 24-bit RGB pixel values (3-Byte-triples)
  2. -- loosely based on RLE8 compression in windows bitmaps (BMPs),
  3. -- see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
  4.  
  5. --------------------------------------
  6. --
  7. --------------------------------------
  8. on RLE24_encode (str)  
  9.   out = ""
  10.   cnt = str.length/3
  11.   repeat with i = 1 to cnt
  12.     c = get_tripel_enc(str, i)
  13.     num = 1
  14.    
  15.     repeat while true
  16.       if i+1>cnt or num>254 then exit repeat
  17.       if get_tripel_enc(str, i+1)<>c then exit repeat
  18.       i = i + 1
  19.       num=num+1
  20.     end repeat
  21.    
  22.     if num>1 OR i=cnt then
  23.       put numtochar(num) after out
  24.       put c after out
  25.     else
  26.      
  27.       if i>cnt-3 then
  28.        
  29.         put numtochar(1) after out
  30.         put get_tripel_enc(str, i) after out
  31.        
  32.       else if get_tripel_enc(str, i+1)<>get_tripel_enc(str, i+2) AND get_tripel_enc(str, i+2)<>get_tripel_enc(str, i+3) then -- escape to absolute mode
  33.        
  34.         put numtochar(0) after out
  35.         put numtochar(0) after out --> change later
  36.         cntPos = out.length
  37.        
  38.         num = 0
  39.         repeat while true
  40.           if i+1>cnt or num>254 then
  41.             put get_tripel_enc(str, i) after out
  42.             i=i+1
  43.             num=num+1
  44.             exit repeat
  45.           end if
  46.          
  47.           t = get_tripel_enc(str, i)
  48.           if t=get_tripel_enc(str, i+1) then exit repeat
  49.           put t after out
  50.          
  51.           i=i+1
  52.           num=num+1
  53.         end repeat
  54.        
  55.         put numtochar(num) into char cntPos of out
  56.         i=i-1
  57.        
  58.       else -- don't escape to absolute mode
  59.        
  60.         put numtochar(1) after out
  61.         put get_tripel_enc(str, i) after out
  62.        
  63.       end if
  64.     end if
  65.   end repeat
  66.  
  67.   return out
  68. end
  69.  
  70. --------------------------------------
  71. --
  72. --------------------------------------
  73. on RLE24_decode (str)  
  74.   out = ""
  75.   cnt = str.length
  76.   repeat with i = 1 to cnt
  77.     o = chartonum(str.char[i])
  78.     case (o) of
  79.       0: -- ESCAPE
  80.         i=i+1
  81.         --        case (chartonum(str.char[i])) of
  82.         --          0: -- put "NEW LINE"
  83.         --          1: -- put "END OF FILE"
  84.         --          2: --put "DELTA"
  85.         --            i=i+1
  86.         --            --out.add( "delta-x:" && l[i] )
  87.         --            i=i+1
  88.         --            --out.add( "delta-y:" && l[i] )
  89.         --            
  90.         --          otherwise: -- put "ABSOLUTE MODE"
  91.         num = chartonum(str.char[i])
  92.         repeat with j = 1 to num
  93.           put get_tripel_dec(str, i) after out
  94.           i=i+3
  95.         end repeat
  96.         --        end case
  97.        
  98.       otherwise:
  99.         c = get_tripel_dec(str, i)
  100.         i=i+3
  101.         repeat with j=1 to o
  102.           put c after out
  103.         end repeat
  104.        
  105.     end case
  106.    
  107.   end repeat
  108.   return out
  109. end
  110.  
  111. --------------------------------------
  112. -- utilities
  113. --------------------------------------
  114. on get_tripel_enc (str, i)
  115.   pos = (i-1)*3+1
  116.   return str.char[pos]&str.char[pos+1]&str.char[pos+2]
  117. end
  118.  
  119. on get_tripel_dec (str, pos)
  120.   return str.char[pos+1]&str.char[pos+2]&str.char[pos+3]
  121. end
  122.  
  123.  
[raw code]