XEROX BMENCODE 2 4 1 BMENCODE 1 4 By: Christopher Lane (LANE@SUMEX-AIM.STANFORD.EDU) BMEncode implements a simple scheme to convert binary files into ASCII format so that they can be sent via electronic mail, or similarly limited transmission mediums, and restored to their original form. The basic idea is simple, the source binary file is 'read' into a bitmap (where the first two words of the bitmap contain the file's length) and then MAKEFILE is used to dump the bitmap since it already knows how to dump binary bitmaps in an ASCII format. Commands are also included in the COMS of the output (BMC) file to call the appropriate functions so that the original file is restored (to the connected directory) as a side effect of (SYS)LOADing the BMC file. This scheme is not the most efficient binary to ASCII encoder (the Unix uuencode and uudecode functions are about 25% more space efficient) but it is simple, runs in Lisp and the encoded format is well understood. Due to limits in the maximum size of bitmaps, only files smaller than about 1/4 MB (about 500 Interlisp-D pages) can be encoded this way. This limit, however, is probably larger than some of the electronic mail systems through which the document will travel can handle and should not be a serious limitation. The size of the encoded file is approximately 2 1/16 times larger than the orginal file plus about 1000 bytes (2 pages). A typical encoded 'BMC' file looks like: (FILECREATED "19-Dec-86 10:00:22" {DSK}MYFILE.BMC;1 817 ) (PRETTYCOMPRINT MYFILECOMS) (RPAQQ MYFILECOMS [(BITMAPS MYFILE.TEDIT) (P (for FILE in '(MYFILE.TEDIT) do (PRIN1 "Restoring file ") (PRIN1 (BITMAP.TO.FILE (EVALV FILE) FILE)) (TERPRI]) (RPAQ MYFILE.TEDIT (READBITMAP)) (256 44 "@@EM@@@@BHBHBBCCCFBNCGCCBNC@BNCACEBBBIB@BHBHBBCCCFBNC@BNC@BNC@BB" "B@BNB@CAC@BIBIB@BBCCCFBNCGCCBNC@BNCBCDBBB@BBGKDDECDKGMDHDOECEDEC" ... "BNEDEHEDBBB@DKECDLBMCACACHCFBMCACCB@BHBBCCCFBNCBCECEBNC@BNC@BBBI" "BI@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@") (for FILE in '(MYFILE.TEDIT) do (PRIN1 "Restoring file ") (PRIN1 (BITMAP.TO.FILE (EVALV FILE) FILE)) (TERPRI)) (DECLARE: DONTCOPY (FILEMAP (NIL))) STOP The receiver of the file will have to strip out any electronic mail headers before trying to load the file. There is only one user function (since the Interlisp LOAD function is used to decode the file): (BITMAP.ENCODE FILE[S]) [Function] Encodes FILE[S] into a loadable BMC file. For the file EXAMPLE.TEDIT, it creates EXAMPLECOMS with the entry (BITMAPS EXAMPLE.TEDIT) where the atom EXAMPLE.TEDIT is set to the bitmap version of the file. The function then calls MAKEFILE to make the file EXAMPLE.BMC to the connected directory. If there is more than one file, the name of the first file in the list is used in making the file COMS and output file. The following are the internal functions used to get a file into and out of a bitmap representation: (FILE.TO.BITMAP FILE) [Function] Creates a bitmap BMC.BYTESPERLINE * 4 bits wide by however many bits tall to hold the bytes in FILE. The value of (GETFILEINFO FILE 'LENGTH) is put into the first two words (least significant word first) of the bitmap followed by the body of the file. Returns the bitmap. (BITMAP.TO.FILE BITMAP FILE) [Function] Dumps BITMAP (made by FILE.TO.BITMAP) to FILE using the first two words of the bitmap as the number of bytes in the bitmap to dump. BMC.BYTESPERLINE [Variable] The bitmap's width is kept to 256 bits so that when encoded in the 4 binary bits per ASCII byte format that MAKEFILE uses, it will be well within the line width of most text editors (important when stripping out electronic mail headers). This width can be adjusted to make more efficiently encoded files. The width setting variable only affects the encoding function, the decoding function doesn't care about the width of the bitmap. Its initial value is 64. BMC.EXTENSION [Variable] The file name extension used for bitmap encoded Interlisp loadable files, initially 'BMC'. BMC.MAKEFILE.OPTIONS [Variable] The options passed to MAKEFILE, initially '(NEW). (LIST ((PAGE NIL (FOLIOINFO (ARABIC) STARTINGPAGE# 1) (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF SLOPE REGULAR WEIGHT MEDIUM) FORMATINFO (ARABIC)) (174 36 288 36) NIL) (HEADING NIL (HEADINGTYPE RUNNINGHEAD) (84 744 444 36) NIL) (TEXT NIL NIL (84 96 456 600) NIL))) (PAGE NIL NIL (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF SLOPE REGULAR WEIGHT MEDIUM)) (282 42 72 36) NIL) (HEADING NIL (HEADINGTYPE RUNNINGHEAD) (84 744 444 36) NIL) (TEXT NIL NIL (84 96 456 600) NIL))) (PAGE NIL NIL (0 0 612 792) ((FOLIO NIL (PARALOOKS (QUAD CENTERED) CHARLOOKS (SUPERSCRIPT 0 SIZE 10 FAMILY MODERN OVERLINE OFF STRIKEOUT OFF UNDERLINE OFF SLOPE REGULAR WEIGHT MEDIUM)) (282 42 72 36) NIL) (HEADING NIL (HEADINGTYPE RUNNINGHEAD) (84 744 444 36) NIL) (TEXT NIL NIL (84 96 456 600) NIL)))))($$(1 1 (8( (8D PAGEHEADING RUNNINGHEAD TERMINALTERMINAL HELVETICA MODERN MODERN MODERN MODERNMODERN LOGO   HRULE.GETFNMODERN  HRULE.GETFNMODERN  HRULE.GETFNMODERN   HRULE.GETFNMODERN  HRULE.GETFNMODERN 5)=*'(9!CCCD/$ e _ W   [ 28z