Subject: EPS to EPSI (bug fix)

From: [email-masked] (Dongchul Lim)
Date: Mon, 11 Apr 1994 03:27:09 -0400 (EDT)

Sorry about posting this again, but this fixes some serious
bugs in the previous posting.

*** Usage ***
Let's say you have a PostScript file called 'file.eps'.
1) This step is not necessary, unless you want to find out the exact
   bounding box. 'bbfig' can be found in calypso-2.oit.unc.edu
   in the directory of /pub/packages/TeX/dviware/dvips/dvips/contrib/bbfig.

   % bbfig file.eps > file.bbfig

2) Open 'file.eps' or 'file.bbfig' with 'xpsview'.
      % xpsview file.eps 
   or % xpsview file.bbfig
3) Cut the image within the bounding box with 'snapshot'.
   Save the image into 'file.rgb'.
   % snapshot
4) Convert RGB image to PostScript image and insert it in 'file.eps'.
   % rgb2pv file.eps file.rgb > file.epsi

-Dongchul Lim

------------- CUT HERE (rgb2pv.c) -----------------------------------
/*****************************************************************
* When you have a RGB image of a PostScript file, this program   *
* can be used to put a preview image into the PostScript file.   *
*                                                                *
* Compilation: cc -o rgb2pv rgb2pv.c -limage -lm                 *
* Usage: rgb2pv PSfile RGBfile                                   *
* Author: Dongchul Lim                                           *
*         Department of Chemistry, Yale University               *
*         [email-masked] (April, 1994)                   *
******************************************************************/

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <gl/image.h>
#define READLINE(fp, str)	fgets((str), sizeof((str)), (fp))

static void	image_error(char *msg)
{
	fprintf(stderr, "%s\n", msg);
}

static void	insert_preview (FILE *fp, unsigned long *pv_data, int pv_width, int pv_height)
{
	int	x, y, col, shift;
	int	pv_depth, pv_lines;
	unsigned long	*pixel, p;

	if (!fp || !pv_data || pv_width <= 0 || pv_height <= 0) return;

	/* count the number of Preview lines */
	pv_lines = 0;
	for(y=pv_height-1,col=0;y>=0;y--) {
		for(x=0;x<pv_width;x++) {
			col += 2;
			if (col > 80) {pv_lines++; col = 0;}
		}
		pv_lines++;
		col = 0;
	}

	/* actual writing of preview image */
	pv_depth = 8;
	fprintf(fp, "%%%%BeginPreview: %d %d %d %d\n", pv_width, pv_height, pv_depth, pv_lines);

	for(y=pv_height-1,col=0;y>=0;y--) {
		pixel = pv_data + y * pv_width;
		fprintf(fp, "%%%%");
		for (x=0;x<pv_width;x++) {
			p = *pixel++;
			fprintf(fp, "%02x", (int)(((77*((p>>16)&0XFF))+(151*((p>>8)&0XFF))+(28*(p&0XFF))) >> 8));
			col += 2;
			if (col > 80) {
				fprintf(fp, "\n");
				fprintf(fp, "%%%%");
				col = 0;
			}
		}
		fprintf(fp, "\n");
		col = 0;
	}
	fprintf(fp, "%%%%EndPreview\n");
}

int	main (int argc, char *argv[])
{
	IMAGE	*image;
	FILE	*ifp, *ofp, *tmpfp;
	char	*psfile, *imagefile, str[256];
	int	pv_width, pv_height, pv_lines;
	register int	y, width;
	register unsigned short	*sp, *rp, *gp, *bp, *ap, *rbuf, *gbuf, *bbuf, *abuf;
	register unsigned long	*lp, *base;

	if (argc < 3) {
		fprintf(stderr, "Usage: %s psfile imagefile\n", argv[0]);
		exit(1);
	}
	psfile    = argv[1];
	imagefile = argv[2];

	i_seterror(image_error);
	if (!(image = iopen(imagefile, "r"))) exit(1);
	if (image->xsize <= 0 || image->ysize <= 0 || image->zsize <= 0) {
		fprintf(stderr, "size of image is zero.\n");
		iclose(image);
		exit(1);
	}
		
	/* read in pixel values */
	base = (unsigned long *)malloc(image->xsize * image->ysize * sizeof(unsigned long));
	rbuf = (unsigned short *)malloc(image->xsize * sizeof(unsigned short));
	gbuf = (unsigned short *)malloc(image->xsize * sizeof(unsigned short));
	bbuf = (unsigned short *)malloc(image->xsize * sizeof(unsigned short));
	abuf = (unsigned short *)malloc(image->xsize * sizeof(unsigned short));
	if (!base || !rbuf || !gbuf || !bbuf) {
		iclose(image);
		fprintf(stderr, "not enough memory.\n");
		exit(1);
	}

	lp = base;
	for (y=0;y<image->ysize;y++) {
		width = image->xsize;
		rp = rbuf;
		gp = gbuf;
		bp = bbuf;
		ap = abuf;

		switch (image->zsize) {
		case 1:
		case 2:
			getrow(image, rbuf, y, 0);
			while (width--) *lp++ = 0x00010101 * (*rp++);
			break;
		case 3:
			getrow(image, rbuf, y, 0);
			getrow(image, gbuf, y, 1);
			getrow(image, bbuf, y, 2);
			while (width--) *lp++ = *rp++ | ((*gp++)<<8) | ((*bp++)<<16);
			break;
		default:
			getrow(image, rbuf, y, 0);
			getrow(image, gbuf, y, 1);
			getrow(image, bbuf, y, 2);
			getrow(image, abuf, y, 3);
			while (width--) *lp++ = *rp++ | ((*gp++)<<8) | ((*bp++)<<16) | ((*ap++)<<24);
			break;
		}
	}

	pv_width  = image->xsize;
	pv_height = image->ysize;
	iclose(image);
	free(rbuf);
	free(gbuf);
	free(bbuf);
	free(abuf);

	/* open input PostScript, output PostScript and tmp scractch files */
	if (!(ifp = fopen(psfile, "r"))) {
		fprintf(stderr, "Can't open file %s.\n", psfile);
		free(base);
		exit(1);
	}
	tmpfp = tmpfile();
	ofp = stdout;

	/* get rid of previous preview image */
	rewind(ifp);
	READLINE(ifp, str);
	if (strncmp(str, "%!", 2) != 0) {
		fprintf(stderr, "%s is not a PostScript file.\n", psfile);
		fclose(ifp); fclose(ofp); fclose(tmpfp); free(base);
		exit(1);
	}
	fprintf(tmpfp, "%!PS-Adobe-3.0 EPSI-3.0\n");
	while (READLINE(ifp, str)) {
		if (strncmp(str, "%%BeginPreview:", 15) == 0) {
			sscanf(str+15, "%*d %*d %*d %d", &pv_lines);
			while (pv_lines-- > 0) READLINE(ifp, str);
			continue;
		}
		fprintf(tmpfp, "%s", str);
	}

	/* insert preview image */
	rewind(tmpfp);
	while (READLINE(tmpfp, str)) {
		if (str[0] != '%') {	/* insert preview image */
			insert_preview(ofp, base, pv_width, pv_height);
			fprintf(ofp, "%s", str);
			break;
		}
		fprintf(ofp, "%s", str);
	}
	free(base);

	/* concatenate the rest of the PostScript file to the output */
	while (READLINE(tmpfp, str)) fprintf(ofp, "%s", str);

	/* close all files */
	fclose(ifp);
	fclose(ofp);
	fclose(tmpfp);

	exit(0);
}
------------------ CUT HERE -----------------------------------------