
/*
    eps2epsi  Version 0.9

    EPS converts Encapsulated PostScript files into Encapsulated
    Postscript Interchange files.  This means, it adds a simple
	bitmap representation of the postscript file so that the 
	programs which allow ESP to be imported can easily show
	what is being included.

	Copyright 1990, Integrated Systems, Inc.
	Written by Chris Nicotra
	All rights reserved.

	This program requires Adrian Aylward's post v1.1 library
*/

#include <stdio.h>
#include <exec/types.h>
#include <exec/exec.h>
#include <exec/execbase.h>
#include <exec/tasks.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <libraries/dos.h>
#include "postlib.h"

/* Assembler routines */
extern void insertftrap(void);
extern void deleteftrap(void);

struct GfxBase *GfxBase;
struct IntuitionBase *IntuitionBase;
struct library *PSbase;

struct PSparm parm;
int ftrapset;

struct BitMap bmap;

int arec;

extern void __saveds __asm flushpage(register __d0 int y1,
                                     register __d1 int y2);
extern void __saveds __asm copypage(register __d0 int num);

FILE *ofp;
int ow,bpr;

main(argc,argv)
int argc;
char *argv[];
{
    FILE *ifp;
    char buf[100];
    double x1,x2,y1,y2;
    int bnd;
    int w,h;
	int i;

	char *infile,*outfile;
	char *ptr;

	/* ------- Decode the command line options ------- */
	infile = outfile = NULL;

	/*
	    This is overkill right now, but provides the frame
		work for adding other options later.
	*/
	while ((--argc) > 0)
	{
	    ptr = *(++argv);

		if (*ptr == '-')
		{
		    switch (*(++ptr))
			{
			case 'o':
				if (outfile)
				{
				    fprintf(stderr,"Too many output file names\n");
					fflush(stderr);
					exit(0);
				}

				--argc;
			    outfile = *(++argv);
			    break;

			default:
				fprintf(stderr,"Invalid option -%c\n",*ptr);
				fflush(stderr);
			    break;
			}
		}
		else
		{
		    /* This must be the input file name */
			if (infile)
			{
			    fprintf(stderr,"Too many input file names\n");
				fflush(stderr);
				exit(0);
			}

			infile = ptr;
		}
	}

	if (!infile)
	{
	    fprintf(stderr,"No input file was specified\n");
		fflush(stderr);
		exit(0);
	}

    if (!(ifp = fopen(infile,"r")))
    {
		fprintf(stderr,"Unable to open input file '%s'\n",infile);
		fflush(stderr);
		exit(0);
    }

	/* ------- Make sure this is an ESP file ------- */

    if (!fgets(buf,100,ifp))
    {
		fprintf(stderr,"File is empty\n");
		fflush(stderr);
		goto do_exit;
	}

    if (strncmp(buf,"%!PS-Adobe-",10))
    {
		fprintf(stderr,"File '%s' is not an EPS file\n",infile);
		fflush(stderr);
		goto do_exit;
    }

    bnd = 0;

    /* ------- OK, look for the bounding box ------- */

    while (fgets(buf,100,ifp))
    {
		if (!strncmp(buf,"%%BoundingBox:",14))
		{
		    if (sscanf(buf+14,"%lf %lf %lf %lf",&x1,&y1,&x2,&y2) != 4)
		    {
				fprintf(stderr,"Unable to decode the bounding box\n");
				fflush(stderr);
				goto do_exit;
		    }
		     
		    bnd = -1;
		}

		if (!strncmp(buf,"%%BeginImage:",13))
		{
		    fprintf(stderr,"This file already contains an image\n");
		    fflush(stderr);
			goto do_exit;
		}
    }

    if (!bnd)
    {
		fprintf(stderr,"No bounding box\n");
		fflush(stderr);
		goto do_exit;
    }

    /* ------- Open all of the libraries ------- */

	/*
	    Don't bother to check, these if they can't be opened we're in
		more trouble than an error message is going to fix
	*/

    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
    IntuitionBase =
        (struct IntuitionBase *) OpenLibrary("intuition.library", 0);

    if (!(PSbase = OpenLibrary("post.library", 0)))
    {
	    printf("Unable to open PostScript library\n");
		goto do_exit;
    }

	/* ------- Setup the POST parameter block ------- */

	/* Round the width to an even 8 bits */
	w = x2 - x1;
	w += 15;
	w &= ~0x0f;

	ow = x2 - x1;
	ow += 7;
	ow &= ~0x07;
	bpr = ow/8;

	h = y2 - y1;

    parm.page.xsize = w;
	parm.page.ysize = h;
	parm.page.xden = parm.page.yden = 72;

    parm.page.ydir = -1;
	parm.page.depth = 1;

    /* Set up the default memory sizes */
    parm.memvlen = 280000;
    parm.memflen =  60000;
    parm.memllen =  60000;
    parm.memhlen =  20000;

    parm.page.ybase = 0;
    parm.page.yheight = parm.page.ysize;

    parm.page.xbytes = (parm.page.xsize + 15) >> 3 & 0xfffffffe;
    parm.page.len = parm.page.xbytes * parm.page.ysize;

	if (!(parm.page.buf[0] = AllocMem(parm.page.len,MEMF_CHIP|MEMF_CLEAR)))
	{
	    printf("Can't allocate the bitmap\n");
		goto do_exit;
    }

    parm.flushfunc = (APTR) flushpage;
    parm.copyfunc = (APTR) copypage;
    parm.infh = Input();
	parm.outfh = Output();
	parm.errfh = Output();

	/* Setup the bitmap */
    bmap.BytesPerRow = parm.page.xbytes;
    bmap.Rows = parm.page.ysize;
    bmap.Flags = 0;
    bmap.Depth = 1;
	bmap.Planes[0] = parm.page.buf[0];

	/* Setup the floating point trap */
    insertftrap();
    ftrapset = 1;

    if (!(arec = PScreateact(&parm)))
	{
		fprintf(stderr,"Unable to create a POST activation\n");
		fflush(stderr);
        goto do_exit;
	}

	/* Start at the beginning of the input file */
	rewind(ifp);

	if (outfile)
	{
	    if (!(ofp = fopen(outfile,"w")))
		{
		    fprintf(stderr,"Unable to open output file\n");
			fflush(stderr);
			goto do_exit;
		}
	}
	else
	    ofp = stdout;

	/*
	    Scan the input until the position where to preview bitmap is
		to be placed.  Then generate and output the preview image
		and continue.  As the input file is read, it is copied into
		the output file.
	*/
    while (fgets(buf,100,ifp))
	{
		fprintf(ofp,"%s",buf);

	    if (!strncmp(buf,"%%EndComments",13))
		{
			/* ------- Execute the EPS file ------- */
			i=PSintstring(arec,infile,-1,PSFLAGFILE|PSFLAGCLEAR|PSFLAGERASE);

			if (i)
			{
				fprintf(stderr,"POST returned error %d\n",i);
				fflush(stderr);
			}
		}
	}

	/* All done! */

do_exit:

	if (arec)
	    PSdeleteact(arec);

    if (ifp)
		fclose(ifp);

	if (outfile && ofp)
	    fclose(ofp);

	if (GfxBase)
	    CloseLibrary(GfxBase);

	if (IntuitionBase)
	    CloseLibrary(IntuitionBase);

	if (PSbase)
	    CloseLibrary(PSbase);

	if (parm.page.buf[0])
	    FreeMem(parm.page.buf[0],parm.page.len);

    if (ftrapset)
		deleteftrap();

    exit(0);
}


void __saveds sigint()
{
	PSsignalint(arec, 1);
}

/* Signal a floating point error */
void __saveds sigfpe()
{
	PSsignalfpe(arec);
}

void __saveds __asm flushpage(register __d0 int y1, register __d1 int y2)
{
}

/* Copy the page to the output */
void __saveds __asm copypage(register __d0 int num)
{
	int i,j;
	char *ptr;

	fprintf(ofp,"%%%%BeginPreview\n");
	fprintf(ofp,"%%%%ImageWidth:%d\n",ow);
	fprintf(ofp,"%%%%ImageHeight:%d\n",bmap.Rows);
	fprintf(ofp,"%%%%ImageDepth: 1\n");
	fprintf(ofp,"%%%%BeginImage:%d\n",bmap.Rows);

	for (i=0;i<bmap.Rows;i++)
	{
		ptr = bmap.Planes[0] + (i*bmap.BytesPerRow);

	    fprintf(ofp,"%% ");

		for (j=0;j<bpr;j++)
		    fprintf(ofp,"%02x",0x0ff & (*(ptr++)));
		fprintf(ofp,"\n");
	}

    fprintf(ofp,"%%%%EndImage\n");
    fprintf(ofp,"%%%%EndPreview\n");
}

