RLE Encoder

Developer(s): John Ryan, Stan Lemke
Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Graphics

Converts a picture on the screen into a CompuServe-style RLE (run-length encoded) file. You give the name of a picture, it is loaded as a SCREEN$, and the program scans it from the top left, a line at a time, with POINT. It counts alternating runs of black (paper) and white (ink) pixels and stores each run as one printable byte, building the file at address 40000. When it reaches the end it asks for a file name and saves the result as CODE. It is the encoding half of the job that John Ryan’s RLEPro decoder does in reverse.

The REM at line 1 reads “RLE ENCODER – Original program by John Ryan – Presented with author’s consent – modified by … S D Lemke, Lemke Software Development”. The program came from two of Bob Swoger’s Larken RLE picture disks, which hold the BASIC program, a copy marked up with Timachine compiler directives, and the compiled version (a short BASIC loader plus 605 bytes of code at 30000). The zip holds two TAPs. “RLE Encoder” is the BASIC program, which takes over an hour per picture. “RLE Encoder compiled” does the same job in about half a minute; the Run in Browser button uses it. Both TAPs end with three sample pictures from the same disks: SATURN (Saturn from Voyager 2), SHUTLE (the Space Shuttle) and TIGER. Type one of those names at the prompt, then a file name to save the result.

Both versions on the disks were broken and have been repaired here. The loop that counts white pixels (lines 310–390) never advanced to the next pixel. Once the scan reached the first white pixel, the encoder kept writing the same pair of bytes and never finished; the compiled code, made from the same listing, had the same fault. In the BASIC program, line 350 now begins with LET X=X+1. In the compiled code, a three-byte instruction was replaced with a call to an 11-byte routine that does the same increment, appended after the variables. The compiled loader also had two faults, now fixed. Its picture-loading line (1105) had been turned into a REM, so it encoded a blank screen. And its SAVE took the file length from addresses 30628/30629, while the compiled program keeps it at 30613/30614. Output from both repaired versions was checked byte for byte against a reference encoder, and it decodes back to the original picture.

Program Analysis

File Format

  • Bytes 0–1 are “G” and “H”, the CompuServe graphics header. The ESC character that normally comes before them is not written.
  • Each following byte is a run length plus 32, alternating black and white and starting with black. A run is at most 95 pixels; a longer one continues after a zero-length run of the other colour.
  • Only the top 176 lines (22 character rows) are scanned. Then 43 pairs of 127, 32 and a final 43 encode 16 blank lines, making up the 256×192 frame.
  • A byte 7 is written after the data, but the saved length stops before it.

Structure

  • Lines 10–70: start at x=0, y=175, with the output pointer S at 40002 and a row counter C of 176.
  • Lines 100–240: count black pixels until a white one, the end of the screen, or a run of 95.
  • Lines 300–450: count white pixels the same way, then go back for black.
  • Lines 1000–1140: write the header and the padding, and work out the length.
  • Lines 2020–2210: CLEAR 39999, load the picture, run the encoder, and save the file as name.CF.

Notable Techniques

  • The compiled version comes from the same listing marked with Timachine directives (REM !USR 30000, REM !INT +c,x,y,b,s,w,z,a). All its variables are 16-bit integers, stored right after the code.
  • Adding 32 to every run keeps the file printable ASCII, so it could be sent as text to a bulletin board or CompuServe.

Potential Issues

  • The BASIC prompt says “Name of RLE?”, but it wants the name of the picture to load; the loader adds the .C$ extension. The BASIC version saves as name.CF; the compiled one saves under the name exactly as typed.
  • Pictures are read with POINT, so colour is lost: any pixel in ink colour counts as white, whatever its attribute.

This program came from a Larken disk and was converted to run from tape: the LKDOS prefixes on the load and save lines and the LOGICALL load were removed, both programs are saved without variables, the encoder was repaired as described above, and sample pictures were added. Both versions were tested in ZEsarUX on the Saturn picture.

The download now also includes “RLE pictures”: 38 decoded RLE images from a Larken disk labelled “RLE_Pics”, the kind of picture this encoder works with. They are digitized photos and line art, among them Saturn from Voyager 2, the Space Shuttle, the Mercury Seven, the Augmented Lunar Module, the NASA seal, a Ferrari, the TS2068 itself and Max Headroom. A tape loads and shows them one after another, and each is also given as a PNG. One picture on the disk that showed a digitizer’s street address is left out.

Related Content

Image Gallery

Source Code

    1 REM ***********************                                           RLE ENCODER                                           Original program by John Ryan  Presented with author's consent                                  modified by ... S D Lemke          Lemke Software Development           2144 White Oak             Wichita,  Ks.    67207                                      ********************************                                
   10 LET X=0
   20 LET Y=175
   30 LET B=0
   40 LET S=40002
   50 LET W=0
   60 LET Z=0
   70 LET C=176
  100 REM ***********************                                      FIND PAPER (BLACK) FIRST                                  ********************************                                
  110 LET A=POINT (X,Y)
  120 IF A=0 THEN LET B=B+1
  130 IF 0<A THEN GO TO 200
  140 LET X=X+1
  150 IF 255<X THEN LET Y=Y-1
  155 IF 255<X THEN LET C=C-1
  160 IF 255<X THEN LET X=X-256
  165 IF C=0 THEN GO TO 200
  170 IF B=95 THEN GO TO 200
  180 GO TO 110
  200 LET B=B+32
  210 POKE S,B
  220 LET S=S+1
  230 LET B=0
  240 IF C=0 THEN POKE S,32: LET S=S+1: GO TO 1000
  300 REM ***********************                                      FIND INK (WHITE) NEXT                                     ********************************                                
  310 LET A=POINT (X,Y)
  320 IF 0<A THEN LET W=W+1
  330 IF A=0 THEN GO TO 400
  350 LET X=X+1: IF 255<X THEN LET Y=Y-1
  355 IF 255<X THEN LET C=C-1
  360 IF 255<X THEN LET X=X-256
  370 IF C=0 THEN GO TO 400
  380 IF W=95 THEN GO TO 400
  390 GO TO 310
  400 LET W=W+32
  410 POKE S,W
  420 LET S=S+1
  430 LET W=0
  440 IF C=0 THEN GO TO 1000
  450 GO TO 110
 1000 REM ***********************                                FINISH OUT STANDARD FORMAT RLE                                  ********************************                                
 1010 POKE 40000,71
 1020 POKE 40001,72
 1030 POKE S,127
 1040 LET S=S+1
 1050 POKE S,32
 1060 LET S=S+1
 1070 LET Z=Z+1
 1080 IF Z=43 THEN GO TO 1100
 1090 GO TO 1030
 1100 POKE S,43
 1110 LET S=S+1
 1120 POKE S,7
 1130 LET S=S-40000
 1140 GO TO 2200
 2005 REM ***********************                                       RLE ENCODER BASIC                                        ********************************
 2010 REM      ENCODE.RLE
 2020 PAPER 0: INK 7: BORDER 0: CLEAR 39999
 2090 REM     LOAD 
 2100 REM CLS : PRINT "Play your TAPE to LOAD SCREEN$.": LOAD ""SCREEN$ 
 2105 CLS : INPUT "Name of RLE? "; LINE n$: LOAD N$+".C$"SCREEN$ 
 2110 GO TO 10
 2190 REM     SAVE 
 2200 INPUT #0,AT 0,0;"File Name = "; LINE n$: SAVE n$+".CF"CODE 40000,S
 2210 STOP 
 9992 SAVE "RLENCD.B1" LINE 2020
 9998 REM  was LKDOS-only

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.