🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.postscript
Article #9001

Re: G3 Fax <--> (E)PS (and compressed bitmaps in postscript)

#9001
From: Jim Morris
Date: Fri, 16 Feb 1990 22:16
337 lines
8755 bytes
>galen@hoptoad.UUCP (Galen Wolf)
>I'm interested to find any hardware or software which allows translating
>electronically between G3 Fax and either plain or encapsulated PostScript.

1. According to some quotes in the trade press, I thinkAdobe is working
on such a thing.

2. One of the PostScript clones, GhostScript I think, offers the feature
in one direction: it will produce a raster from PostScript at whatever
resolution you ask -- so ask for 200 by 200. [I've heard all this second
hand.]


 >Are there any postscript hackers than can recode the
>"readrlestring"so that it runs faster?  

Not quite, but here is a program that re-encodes the uncompressed input
to the image operator and usually makes it faster.
-------------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
#ifdef MSDOS
#include <string.h>
#else /* #ifdef MSDOS */
#include <strings.h>
#endif /* #ifdef MSDOS */
#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;
static FILE *infile, *outfile;

extern int optind;
extern char *optarg;

main(argc, argv)
int argc;
char **argv;
{
    int flag;
    int j;
    char *outfname = NULL;

    optind = 1;

    /* get the argument */
    while ((flag = getopt(argc, argv, "f:o:x")) != EOF) {
	switch (flag)
	  {
	  case 'f':
	      minF = atoi (optarg);
	      if (minF<6) minF = 6;
	      break;
	      
	  case 'o':
	      outfname = optarg;
	      break;

	  case 'x':
	  default:
	      fprintf (stderr,
			"Usage: pssqw [-f <value>] [-o outfile] [file]\n");
	      exit (1);
	  }
    }

    if (optind + 1 < argc) {
	fprintf(stderr, "pssqw: can only handle one input file.\n");
	exit(1);
    }

    if (optind < argc) {
	infile = fopen(argv[optind], "r");
	if (!infile) {
	    perror(argv[optind]);
	    exit(1);
	}
    }
    else {
	infile = stdin;
    }
    
    if (outfname) {
	outfile = fopen(outfname, "w");
	if (!outfile) {
	    perror(outfname);
	    exit(1);
	}
    }
    else {
	outfile = stdout;
    }

    nch = getc(infile);

    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 )
	{
	    fprintf(outfile, "%s", pscommand);
	    runlength_encode();
	}
	else
	{
	    fprintf(outfile, "%s\n", line);
	    nch = getc(infile);
	}
    }
}

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 = getc(infile);
    }
}


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 = getc(infile);
	    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;
	    }
	}
    }
    putc('\n', outfile);
}

#define PSLength 72

static  int tlcount = 0;
/* there are tlcount chars sent since the last cr */
PC(c)
char c;
{
    if (++tlcount >= PSLength)
    {
	putc('\n', outfile);
	tlcount = 1;
    }
    putc(c, outfile);
}

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)
    {
	putc('\n', outfile);
	tlcount = length;
    }
    fprintf(outfile, "%d ", n);
}
Technical Details
Message-ID: <AZr7jHi00hl=E430Z2@andrew.cmu.edu>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!pt.cs.cmu.edu!andrew.cmu.edu!jhm+
References: <10260@hoptoad.uucp>, <8027@pt.cs.cmu.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!pt.cs.cmu.edu!andrew.cmu.edu!jhm+
From: jhm+@andrew.cmu.edu (Jim Morris)
Newsgroups: comp.lang.postscript,alt.fax
Subject: Re: G3 Fax <--> (E)PS (and compressed bitmaps in postscript)
Message-ID: <AZr7jHi00hl=E430Z2@andrew.cmu.edu>
Date: 16 Feb 90 22:16:51 GMT
References: <10260@hoptoad.uucp>,
 <8027@pt.cs.cmu.edu>
Organization: Computer Science, Carnegie Mellon, Pittsburgh, PA
Lines: 337
In-Reply-To: <8027@pt.cs.cmu.edu>