Summary

  • In September 1981, Alan R. Katz described a working Rapicom 450 decoder that turned stored fax data into a one-bit bitmap. The fax file already existed; the page still had to be reconstructed.
  • Its bytes, selected header fields and run-length words each needed different bit-order treatment. Block headers supplied position and state after gaps; RFC 797 then proposed a ten-byte bitmap header so other programs could handle the result.

The fax had made it into a file. Congratulations to the file. It could not yet show anyone the page. Its bits had been complemented, reversed inside octets, reversed again inside selected fields, then arranged as paired scan lines with variable-length runs. Alan R. Katz's September 1981 RFC 798 reads like the moment somebody opened that box and discovered the picture was packed backwards in more than one direction. The companion RFC 797 gave the decoded picture a simpler place to live.

Katz implemented the decoder in L10 as part of NLS on TOPS20. A microprocessor interface called FAXIE connected the Rapicom 450 to the computer over a terminal line. The fax machine sent serial data; FAXIE gathered eight bits at a time. Rapicom's MARK and SPACE meanings were opposite RS232's, so the interface complemented bits. The stored file then inverted each data octet's bit order and complemented it under the Rapicom file convention. The decoder had to undo those transformations. The length and command octets were exempt, a small detail with a large capacity to turn an apparently orderly file into soup.

That file had structure. Each device block contained 585 bits, padded with seven zeros to make 74 data octets. A length octet and command octet made an ordinary stored record 76 octets. Commands distinguished setup, data and end. That was enough to move a record around, the subject of the earlier Rapicom file specification. It was not enough to tell a screen which dots were black. For that, Katz had to reconstruct the machine's encoding.

An ordinary letter-size page in his account was roughly 1,726 picture elements wide and 2,100 scan lines tall. Fine Detail encoded every line. Quality encoded every second line; Express every third. The missing lines were repeated when the picture was displayed. Rapicom encoded two lines together, giving each vertical pair four possibilities: white-white, white-black, black-white or black-black. Transitions among those states used variable-length bit patterns. Runs of all-white or all-black columns had counters whose word length could grow from two to seven bits.

A program that read every bit as one pixel would make abstract art, probably against the operator's wishes.

The reversals were separate traps. The stored data octets had their own complement-and-bit-order convention. Within the device block, data count, horizontal position and black and white run-size fields were sent with their internal bits reversed. Sequence number and current state were not. The run-length words in the encoded picture were reversed again at field level. Katz emphasized that reversing an n-bit field was a different operation from reversing and complementing an octet. A single universal “flip the bits” button would have been a fine way to preserve the error.

The block header also kept the drawing from drifting. A 585-bit device block contained a synchronization code, a 37-bit header, a nominal 512-bit data region and a checksum. The data count said how many of those 512 bits were useful; zero meant throw the block away. The header's horizontal position could expose a gap, which the decoder filled white, or an overlap, which new block data replaced. If a sequence number skipped its four-step cycle, a block was missing.

Katz instructed the program to begin each block using the state, run sizes and position in that block's own header, even when they disagreed with the preceding block's ending. This let the decoder resume after a dropped block; it did not make the missing picture material reappear.

Once the page existed as pixels, RFC 797 proposed a deliberately spare file. Four octets gave width, four gave height, one gave horizontal increment and one vertical increment. Pixel data began at octet eleven, scanned left to right from the top, with the end of each row padded to an octet boundary. A vertical increment of one, two or three matched Rapicom's Fine Detail, Quality and Express modes. Display software could repeat a stored row accordingly. The point was modest and powerful: the next program could work with a picture rather than learn the fax machine's private grammar.

Katz reported that his decoder took about two CPU minutes on a DEC KL10/TOPS20 to process an average Fine Detail document. The resulting roughly 1,726-by-2,100-pixel picture used about 204 disk pages. An HP graphics terminal could show portions of it, with zoom; the whole letter-size page did not fit at once. That is an unusually tangible endpoint for a tale about bit order. The document was no longer a file that merely had arrived. It was an image somebody could inspect, and the expensive part was all the knowledge needed to get the pixels to face forward.