jwz@spice.cs.cmu.edu (Jamie Zawinski) (02/10/89)
I wrote some code for sending run-length encoded bitmaps to our PS printer, but it didn't work out very well - if you're sending a big bitmap, and a bit gets inverted, it's only going to be one pixel, and you're not going to notice it. But if the bitmap is run-length encoded, you're going to lose the rest of the image. That's what kept happening - I'd print a file multiple times, and the image would turn to static at a different point each time it was printed. But maybe it will be of use to someone with a more reliable data link, so I've included the PostScript end of the code in this message. (The host end was written in TI Explorer Lisp, and I doubt most of you will find that useful...) Jamie Zawinski jwz@spice.cs.cmu.edu sunpitt!sun!eti!jwz ------ START IGNORING HERE ------- %!ps % % After this prolog, ship something of the form % % <width-in-points> <height-in-points> do-image % <width-of-image-as-32-bit-hex-quantity> % <height-of-image-as-32-bit-hex-quantity> % <compressed-hex-data> % showpage % % The compression is very simple, but also very effective. % First there is a control byte in the range [-128,127]. % If this is negative, then that means replicate the next byte % read -CONTROL+1 times. If it is non-negative, then that means % that the next CONTROL+1 bytes are literal. % -128 is a no-op. % /controlbuf 1 string def /repbuf 1 string def /WHbuf 4 string def /chunk-count 0 def /read-w-and-h { currentfile WHbuf readhexstring pop % read the width and height into /WHbuf as a 4 byte quantity. /w WHbuf 0 get 256 mul WHbuf 1 get add def % set /w and /h to the values in this string, MSB first. /h WHbuf 2 get 256 mul WHbuf 3 get add def } def /read-brun1-chunk { currentfile controlbuf readhexstring pop pop % read one hex character from the stream. /code controlbuf 0 get def % set /code to the character read. code 127 gt {/code code 256 sub def} if % If /code is >127, subtract 256, converting to be in the range [-128,127]. /chunk-count chunk-count 1 add def code -128 eq % -128 is illegal. Print an error message and stop. { (\n%%[ Error: illegal BRUN1 control byte at chunk ) print chunk-count 1 sub ( ) cvs print ( - probably lost some bits. Try re-printing this file. ]%%\n) print stop } { code 0 ge { lit } % >=0 means copy next CODE+1 bytes literally. { rep } % < 0 means replicate next byte -CODE+1 times. ifelse } ifelse } def /lit { % uses dynamic binding of /code - leaves a new string on the stack. currentfile code 1 add string readhexstring pop } def /rep { % uses dynamic binding of /code - leaves a new string on the stack. currentfile repbuf readhexstring pop pop /repchar repbuf 0 get def % get next code. /newstring code neg 1 add string def % build a string. 0 1 newstring length 1 sub % set every element of the new string to be the new char. { newstring exch repchar put } for newstring % leave the new string on the stack. } def /do-image { % takes dest-w and dest-h on stack. There must be image data textually after this. /dest-h exch def /dest-w exch def 0 0 moveto 20 20 translate dest-w dest-h scale read-w-and-h w h 1 [w 0 0 h neg 0 h] {read-brun1-chunk} image showpage } def --