wcs@skep2.ATT.COM (Bill.Stewart.[ho95c]) (01/30/89)
Does anyone have a Postscript program that can be downloaded to a Postscript printer to uncompress bitmaps? I know it's possible (Glenn Reid periodically alludes to it.) The objective is to download a compressed picture and decompress on the printer, trading printer CPU for transmission time, which can be significant on large pictures. For some pictures, a simple run-length encoding would work well, but for complex grayscale you need something more sophisticated to be worth using. Thanks; Bill -- # Thanks; # Bill Stewart, AT&T Bell Labs 2G218 Holmdel NJ 201-949-0705 ho95c.att.com!wcs # # News. Don't talk to me about News.
pokey@well.UUCP (Jef Poskanzer) (01/30/89)
In the referenced message, wcs@skep2.UUCP (Bill.Stewart) wrote: >Does anyone have a Postscript program that can be downloaded to a >Postscript printer to uncompress bitmaps? The pbmtops filter in recent versions of the PBM package does run-length encoding. However, for all but the slowest printer links, this is slightly slower than sending the raw bitmap. The decrease in transmission time is slightly more than compensated for by the increase in processing time. Perhaps the decoding routine I wrote is suboptimal; perhaps the slowness of current PostScript interpreters makes it a hard problem. As far as I know, everyone who has tried this compression trick has come up with the same slight increase in time. But if anyone wants to prove me wrong and send me a faster decoding routine, I'll be glad to use it. --- Jef Jef Poskanzer jef@helios.ee.lbl.gov ...well!pokey There is no substitute for good manners, except, perhaps, fast reflexes.
kgdykes@watmath.waterloo.edu (Ken Dykes) (01/31/89)
In article <10529@well.UUCP> Jef Poskanzer <jef@helios.ee.lbl.gov> writes: >encoding. However, for all but the slowest printer links, this is slightly >slower than sending the raw bitmap. The decrease in transmission time >is slightly more than compensated for by the increase in processing time. > The thing is, with me, I dont care how long the PRINTER takes, but i dont like the LINE tied-up, ie: I am willing to have the printer glow red hot doing computing I just want quicker transmit times. This is because my gutless pc cannot DO ANYTHING ELSE while doing transmission (well it can, then it slows transmission to the point of "time-out errors") ..Just a viewpoint on the value of marginal compression. -ken -- - Ken Dykes, Software Development Group, U.of.Waterloo Waterloo, Ontario, Canada N2L 3G1 kgdykes@watmath.uucp kgdykes@water.bitnet kgdykes@waterloo.csnet kgdykes@watmath.uwaterloo.ca kgdykes@watmath.edu {backbone}!watmath!kgdykes
jhm+@andrew.cmu.edu (Jim Morris) (02/01/89)
Here is a program that works for me. It seems to compress a business letter by a factor of 5 and sometimes the printing time as well. Your mileage may vary... ------------------------CUT HERE----------------------------- /* pssqw.c Compression of postscript image files just squeezes the white space */ /* Written Jim Morris (james.morris@andrew.cmu.edu) 7/19/88 derived from a version (pscomp.c) by Ganapathy Krishnan (krishnan@cs.buffalo.edu) (716-636-3197) Morris's work was supported by the NSF EXPRES project. */ #include <stdio.h> #ifdef VMS #include <string.h> #else #include <strings.h> #endif #define BSIZE 10000 /* PS internal buffer size */ #define PSLineSize 72 /* Limit on output lines */ #define LINEBUF 300 #define MinimunF 22 /*default shortest run of f's to encode */ /* This number seems to minimize processing time on a Laserwriter If your printer is different, hopefully faster, revising this number may improve performance. */ #define dig(c) ((c) >= '0' && (c) <= '9' ) #define hdig(c) (((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f')) #define hexdig(c) ( dig(c) || hdig (c)) #define white(c) (c == ' ' || c == '\n' || c=='\t') /* Usage pssqw < file.ps | lpr cc pssqw.c -o pssqw This program accepts a PostScript file and writes out a new one in which all the image commands have been altered to use compressed rasters. Each image command must appear on a line by itself and the image data can contain only hex digits and white space. It is possible for the program to malfunction either by missing an image command or mistaking some innocent text for one. If the next command after the image data starts with a hex digit, e.g. endpage, put a PS comment before it, e.g. %end of image Here is an example of the kind of input expected: %! To be embedded, delete the '!' % Bits are stored left-to-right, bottom-to-top; 1=white, 0=black /width 1016 def /height 1321 def % dimensions in pixels /xScale 0.60 def /yScale 0.60 def % scaling factors width xScale mul height yScale mul scale % set scaling /picstr width 7 add 8 idiv string def % define place to read lines % the "image" operator has five parameters: width height 1 % dimensions [width 0 0 height 0 0] % transform matrix {currentfile picstr readhexstring pop} % bits source image % PRINT IT fff fff fffff ffff fffff ffffffff aab034 f09b ....... showpage Here is the PS program that replaces image: pop % discard standard proc /bz 10000 def % co-ordinate with BSIZE above /bf bz string def %place to build lines /ff bz string def ff 0 255 put /hbz bz 1 add 2 idiv def /i 1 def %fill ff with 255 { % [0...i) contains 255, i < bz ff i % start putting at i ff 0 % start taking from 0 i hbz ge {bz i sub getinterval putinterval exit} {i getinterval putinterval /i i i add def } ifelse } loop { % new proc /len currentfile token pop def len 0 lt {ff 0 len neg getinterval} {currentfile bf 0 len getinterval readhexstring pop} ifelse } bind image A squeezed version appears immediately below. */ static char pscommand[] = { "pop/bz 10000 def/bf bz string def/ff bz string def ff 0 255 put /hbz\n\ bz 1 add 2 idiv def/i 1 def{ff i ff 0 i hbz ge{bz i sub getinterval\n\ putinterval exit}{i getinterval putinterval/i i i add def}ifelse}loop\n\ {/len currentfile token pop def len 0 lt{ff 0 len neg getinterval}\n\ {currentfile bf 0 len getinterval readhexstring pop}ifelse}bind image\n" }; static char line[LINEBUF]; static int nch; /* next character from file */ static int minF = MinimunF; main(argc, argv) int argc; char **argv; { int j; /* get the argument */ while (--argc > 0 && (*++argv)[0] == '-') { while (*++(*argv)) { switch (**argv) { case 'f': minF = atoi (*argv+1); if (minF<6) minF = 6; while (*++(*argv)); --(*argv); break; default: fprintf (stderr, "Usage: pssqw [-f<value>] \n"); exit (1); } } } nch = getchar(); for(; ;) { if (nch == EOF) exit(0); readline(); /* look for line starting with "image" */ for (j=0; white(line[j]); j++) ; if (strncmp(&(line[j]), "image", 5) == 0 ) { printf("%s", pscommand); runlength_encode(); } else { printf("%s\n", line); nch = getchar(); } } } readline() { int i; i=0; /* nch contains the next item of input */ for (;;) { if (i>=LINEBUF) { fprintf(stderr, "Line buffer length exceeded\n"); exit(1); } if(nch =='\n' || nch == EOF) { line[i] = '\0'; return(i); } line[i++] = nch; nch = getchar(); } } runlength_encode() { char duffer[2*BSIZE]; /* double sized buffer */ int size = 2*BSIZE; int done = 0; int i, j, lout; for(;!done;) { /* read in a buffer's worth */ for (size=0;size!=2*BSIZE ;) { nch = getchar(); if white(nch) continue; if (hexdig(nch)) duffer[size++] = nch; else {done = 1; break; } } /* write out duffer[0...size) */ size = (size/2)*2; /* ignore odd character */ for(lout=0;lout!=size;) { /* duffer[0...lout) has been put out */ /* find a string of ff's */ for (i=lout; i!=size; i+=2) { /* duffer[lout..i) contains non F-string */ if(duffer[i] != 'f' && duffer[i] != 'F') continue; for (j=i+1; j!=size; j++) { if (duffer[j] != 'f' && duffer[j] != 'F') break; } /* duffer[i...j) are f's */ j = (j/2)*2; /* must be even */ if(j-i >= minF) break; } /* duffer[lout...i) is non-F stuff */ /* duffer[i...j) are f's if i!=size */ if(i>lout) { PNum((i-lout)/2); for (;lout!=i; lout++) PC(duffer[lout]); } if (lout!=size) { PNum(-(j-i)/2); lout = j; } } } printf("\n"); } #define PSLength 72 static int tlcount = 0; /* there are tlcount chars sent since the last cr */ PC(c) char c; { if (++tlcount >= PSLength) { putchar('\n'); tlcount = 1; } putchar(c); } PNum(n) int n; { int an = n; int length = 0; if (n<0) {an = -n; length = 1; } length += (an>9999) ? 6 : (an>999) ? 5 : (an>99) ? 4 : (an>9) ? 3 : 2; if( (tlcount += length) >= PSLength) { printf("\n"); tlcount = length; } printf("%d ", n); }
jos@idca.tds.PHILIPS.nl (Jos Vos) (02/01/89)
In article <10529@well.UUCP> Jef Poskanzer <jef@helios.ee.lbl.gov> writes: >In the referenced message, wcs@skep2.UUCP (Bill.Stewart) wrote: >>Does anyone have a Postscript program that can be downloaded to a >>Postscript printer to uncompress bitmaps? >The pbmtops filter in recent versions of the PBM package does run-length >encoding. However, for all but the slowest printer links, this is slightly >slower than sending the raw bitmap. The decrease in transmission time >is slightly more than compensated for by the increase in processing time. What's the PBM package? Is it available for free? Anyhow, can anybody mail me a working example of PostScript decompression. I still want to try it for rather simple scanned documents. -- -- ###### Jos Vos ###### Internet jos@idca.tds.philips.nl ###### -- ###### ###### UUCP ...!mcvax!philapd!jos ######