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
--