[comp.graphics] pcx2rf

mike@relgyro.stanford.edu (Mike Macgirvin) (12/10/88)

	The following is a program I wrote to convert PC paintbrush .PCX
files (as used by Ventura Publisher, etc.) to Sun rasterfiles. The original
purpose was to place images scanned from a PC package into FrameMaker. There
are no doubt other applications. Possible extensions include accepting
and outputting color images.
mike@relgyro.stanford.edu
---------------------------% SNIP SNIP SNIP %----------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	pcx2rf.c
# This archive created: Fri Dec  9 16:47:34 1988
export PATH; PATH=/bin:$PATH
echo shar: extracting "'pcx2rf.c'" '(3752 characters)'
if test -f 'pcx2rf.c'
then
	echo shar: will not over-write existing file "'pcx2rf.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'pcx2rf.c'
	X/* pcx2rf.c */
	X/*   Convert single plane PC paintbrush (.PCX) file to Sun rasterfile 
	X * format. We assume here a binary bitmap with no color information, and
	X * standard PCX run length encoding bitmap. The following program is
	X * released as is, with no warranty expressed as to its correctness or
	X * suitability for any particular application. The name of the author
	X * shall remain on any copies or derivative works. Otherwise, there are
	X * no restrictions as to its use, or transfer.
	X *
	X * Mike Macgirvin
	X * Stanford Relativity Gyro Program GP-B
	X * Stanford, Calif. 94503
	X * ARPA: mike@relgyro.stanford.edu
	X * 9 DEC 88
	X *
	X *
	X */
	X
	X#include <rasterfile.h>
	X#include <stdio.h>
	X
	X
	Xstruct rasterfile ras;
	XFILE *fi;
	XFILE *fo;
	X
	Xint bytes_per_row = 0;
	Xint fill_req = 0;
	X
	Xunsigned char pcxhd[128];
	X
	Xmain(argc,argv)
	X     int argc;
	X     char **argv;
	X{
	X  int cnt,c,n;
	X  int xmin = 0;
	X  int xmax = 0;
	X  int ymin = 0;
	X  int ymax = 0;
	X  int status = 0;
	X
	X  if(argc != 3) {
	X    (void) fprintf(stderr,"usage: %s infile.pcx outfile.rf\n",argv[0]);
	X    exit(0);
	X  }
	X                                                  /* open files */
	X  if((fi = fopen(argv[1],"r")) == NULL) {
	X    perror("pcx2rf :input file");
	X    exit(1);
	X  }
	X  if((fo = fopen(argv[2],"w")) == NULL) {
	X    perror("pcx2rf :output file");
	X    exit(1);
	X  }
	X                                                  /* read .PCX header */
	X  for(cnt = 0; cnt < 127; cnt ++) {
	X    if((c = getc(fi)) == EOF) {
	X      (void) fprintf(stderr,"Incomplete .PCX header\n");
	X      exit(1);
	X    }
	X    pcxhd[cnt] = c;
	X  }
	X                                 /* calculate raster header and swap bytes */
	X  xmin = pcxhd[4] + ( 256 * pcxhd[5]);
	X  ymin = pcxhd[6] + ( 256 * pcxhd[7]);
	X  xmax = pcxhd[8] + ( 256 * pcxhd[9]);
	X  ymax = pcxhd[10]+ ( 256 * pcxhd[11]);
	X  xmax = xmax - xmin + 1;
	X  ymax = ymax - ymin + 1;
	X  bytes_per_row = pcxhd[66] + (256 * pcxhd[67]);
	X                     /* Sun requires multiples of 16 bits, pad if necessary */
	X  if(bytes_per_row & 1)
	X    fill_req = 1;
	X  (void)
	X  printf("%d pixels X %d pixels, %d bytes per row\n",xmax,ymax,bytes_per_row);
	X  ras.ras_magic = RAS_MAGIC;
	X  ras.ras_width = xmax;
	X                                /* if necessary, round off to 16 bits */
	X  if(n = xmax & 15)
	X    ras.ras_width = xmax + (16 - n);
	X  ras.ras_height = ymax;
	X  ras.ras_depth = 1;
	X  ras.ras_length = (bytes_per_row * fill_req) + ( bytes_per_row * ymax );
	X  ras.ras_type = 1;
	X  ras.ras_maptype = 0;
	X  ras.ras_maplength = 0;
	X                               /* write out rasterfile header */
	X  (void) fwrite((char *) &ras,sizeof(struct rasterfile),1,fo);
	X                               /* transform compressed bitmap */
	X  status = readpcx();
	X                               /* we b done */
	X  (void) fclose(fi);
	X  (void) fclose(fo);
	X
	X  exit(status);
	X}
	X
	X
	Xreadpcx()
	X{
	X  /* goes like this: read a byte. if the two high bits are set, then the
	X   * low 6 bits contain a repeat count, and the char to repeat is the next
	X   * char in the file. If the two high bits are not set, then this is the
	X   * char to write. At the end of each row, pad if necessary to multiple of
	X   * 16 bits. We also invert the image.
	X   */
	X
	X  int byte_cnt = 0;
	X  int c;
	X  int x;
	X  int cnt;
	X  while((c = fgetc(fi)) != EOF) {
	X    if(c & 0xC0) {
	X      cnt = c & 0x3F;
	X      if((c = fgetc(fi)) == EOF) {
	X	(void) fprintf(stderr,"Unexpected end of file on input\n");
	X	return(1);
	X      }
	X      for(x = 0; x < cnt; x ++) {
	X	(void) fputc(255 - c,fo);
	X	byte_cnt ++;
	X	if(byte_cnt == bytes_per_row - 1) {
	X	  if(fill_req) (void) fputc(0,fo);
	X	  byte_cnt = 0;
	X	}
	X      }
	X    }
	X    else {
	X      (void) fputc(255 - c,fo);
	X      byte_cnt ++;
	X      if(byte_cnt == bytes_per_row - 1) {
	X	if(fill_req) (void) fputc(0,fo);
	X	byte_cnt = 0;
	X      }
	X    }
	X  }
	X  return(0);
	X}
	X
SHAR_EOF
if test 3752 -ne "`wc -c < 'pcx2rf.c'`"
then
	echo shar: error transmitting "'pcx2rf.c'" '(should have been 3752 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0