summaryrefslogtreecommitdiff
path: root/Build/source/texk/dvipsk/emspecial.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/dvipsk/emspecial.c')
-rw-r--r--Build/source/texk/dvipsk/emspecial.c1469
1 files changed, 0 insertions, 1469 deletions
diff --git a/Build/source/texk/dvipsk/emspecial.c b/Build/source/texk/dvipsk/emspecial.c
deleted file mode 100644
index 38e450d050e..00000000000
--- a/Build/source/texk/dvipsk/emspecial.c
+++ /dev/null
@@ -1,1469 +0,0 @@
-/* $Id$
- * emspecial.c
- * This routine handles the emTeX special commands.
- */
-#include "dvips.h" /* The copyright notice in that file is included too!*/
-
-#include <ctype.h>
-#include <stdlib.h>
-/*
- * The external declarations:
- */
-#include "protos.h"
-
-#ifdef EMTEX
-/* emtex specials, added by rjl */
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
-static long emmax = 161;
-
-/*
- * We define these seek constants if they don't have their
- * values already defined.
- */
-#ifndef SEEK_SET
-#define SEEK_SET (0)
-#endif
-#ifndef SEEK_END
-#define SEEK_END (2)
-#endif
-
-struct empt {
- struct empt *next;
- shalfword point;
- integer x, y;
-};
-
-static struct empt **empoints = NULL;
-boolean emused = FALSE; /* true if em points used on this page */
-integer emx, emy;
-
-struct emunit {
- const char *unit;
- float factor;
-};
-struct emunit emtable[] = {
- {"pt",72.27},
- {"pc",72.27/12},
- {"in",1.0},
- {"bp",72.0},
- {"cm",2.54},
- {"mm",25.4},
- {"dd",72.27/(1238.0/1157)},
- {"cc",72.27/12/(1238.0/1157)},
- {"sp",72.27*65536},
- {0,0.0}
-};
-
-static void emgraph(char *filename, float emwidth, float emheight);
-
-/* clear the empoints array if necessary */
-void
-emclear(void)
-{
- int i;
- if (emused && empoints)
- for (i=0; i<emmax; i++)
- empoints[i] = 0;
- emused = FALSE;
-}
-
-/* put an empoint into the empoints array */
-static struct empt *
-emptput(shalfword point, integer x, integer y)
-{
- struct empt *p;
- int start;
-
- emused = TRUE;
- start = point % emmax;
- p = empoints[start];
- while ( p ) {
- if ( p->point == point )
- break;
- p = p->next;
- }
- if (p == 0) {
- p = (struct empt *)mymalloc(sizeof(struct empt));
- p->next = empoints[start];
- empoints[start] = p;
- }
- p->point = point;
- p->x = x;
- p->y = y;
- return(p);
-}
-
-/* get an empoint from the empoints array */
-static struct empt *
-emptget(shalfword point)
-{
- struct empt *p;
- int start;
-
- start = point % emmax;
- if (emused == TRUE) {
- p = empoints[start];
- while (p) {
- if (p->point == point)
- return p;
- p = p->next;
- }
- }
- sprintf(errbuf,"!em: point %d not defined",point);
- specerror(errbuf);
- return(NULL); /* never returns due to error */
-}
-
-
-/* convert width into dpi units */
-static float
-emunits(float width, char *unit)
-{
-struct emunit *p;
- for (p=emtable; p->unit; p++) {
- if (strcmp(p->unit,unit)==0)
- return( width * actualdpi / p->factor );
- }
- return (-1.0); /* invalid unit */
-}
-
-/* The main routine for \special{em:graph ...} called from dospecial.c */
-/* the line cut parameter is not supported (and is ignored) */
-
-void
-emspecial(char *p)
-{
-float emwidth, emheight;
-shalfword empoint1, empoint2;
-struct empt *empoint;
-char emunit[30];
-char emstr[500];
-char *emp;
-
- hvpos();
- for (emp = p+3; *emp && isspace((unsigned char)*emp); emp++); /* skip blanks */
- if (strncmp(emp, "linewidth", 9) == 0) {
- /* code for linewidth */
- for (emp = emp+9; *emp && isspace((unsigned char)*emp); emp++); /* skip blanks */
- sscanf(emp, "%f%2s", &emwidth, emunit);
- emwidth = emunits(emwidth,emunit);
- if (emwidth!=-1.0) {
- snprintf(emstr, sizeof(emstr), "%.1f setlinewidth", emwidth);
- cmdout(emstr);
-#ifdef DEBUG
- if (dd(D_SPECIAL))
- fprintf(stderr, "em special: Linewidth set to %.1f dots\n",
- emwidth);
-#endif
- } else {
- sprintf(errbuf,"Unknown em: special width");
- specerror(errbuf);
- }
- }
- else if (strncmp(emp, "moveto", 6) == 0) {
-#ifdef DEBUG
- if (dd(D_SPECIAL))
-#ifdef SHORTINT
- fprintf(stderr, "em special: moveto %ld,%ld\n", hh, vv);
-#else
- fprintf(stderr, "em special: moveto %d,%d\n", hh, vv);
-#endif
-#endif
- emx = hh;
- emy = vv;
- }
- else if (strncmp(emp, "lineto", 6) == 0) {
-#ifdef DEBUG
- if (dd(D_SPECIAL))
-#ifdef SHORTINT
- fprintf(stderr, "em special: lineto %ld,%ld\n", hh, vv);
-#else
- fprintf(stderr, "em special: lineto %d,%d\n", hh, vv);
-#endif
-#endif
- cmdout("np");
- numout(emx);
- numout(emy);
- cmdout("a");
- numout(hh);
- numout(vv);
- cmdout("li");
- cmdout("st");
- emx = hh;
- emy = vv;
- }
- else if (strncmp(emp, "point", 5) == 0) {
- if (empoints == NULL) {
- empoints =
- (struct empt **)mymalloc((integer)emmax * sizeof(struct empt *));
- emused = TRUE;
- emclear();
- }
- for (emp = emp+5; *emp && isspace((unsigned char)*emp); emp++); /* skip blanks */
- empoint1 = (shalfword)atoi(emp);
- empoint = emptput(empoint1,hh,vv);
-#ifdef DEBUG
- if (dd(D_SPECIAL))
-#ifdef SHORTINT
- fprintf(stderr, "em special: Point %d is %ld,%ld\n",
-#else
- fprintf(stderr, "em special: Point %d is %d,%d\n",
-#endif
- empoint->point, empoint->x, empoint->y);
-#endif
- }
- else if (strncmp(emp, "line", 4) == 0) {
- for (emp = emp+4; *emp && isspace((unsigned char)*emp); emp++); /* skip blanks */
- empoint1 = (shalfword)atoi(emp);
- for (; *emp && isdigit((unsigned char)*emp); emp++); /* skip point 1 */
- if ( *emp && strchr("hvp",*emp)!=0 )
- emp++; /* skip line cut */
- for (; *emp && isspace((unsigned char)*emp); emp++); /* skip blanks */
- if ( *emp && (*emp==',') )
- emp++; /* skip comma separator */
- for (; *emp && isspace((unsigned char)*emp); emp++); /* skip blanks */
- empoint2 = (shalfword)atoi(emp);
- for (; *emp && isdigit((unsigned char)*emp); emp++); /* skip point 2 */
- if ( *emp && strchr("hvp",*emp)!=0 )
- emp++; /* skip line cut */
- for (; *emp && isspace((unsigned char)*emp); emp++); /* skip blanks */
- if ( *emp && (*emp==',') )
- emp++; /* skip comma separator */
- emwidth = -1.0;
- emunit[0]='\0';
- sscanf(emp, "%f%2s", &emwidth, emunit);
- emwidth = emunits(emwidth,emunit);
-#ifdef DEBUG
- if (dd(D_SPECIAL))
- fprintf(stderr, "em special: Line from point %d to point %d\n",
- empoint1, empoint2);
-#endif
- cmdout("np");
- if (emwidth!=-1.0) {
-#ifdef DEBUG
- if (dd(D_SPECIAL))
- fprintf(stderr,"em special: Linewidth temporarily set to %.1f dots\n",
- emwidth);
-#endif
- strcpy(emstr,"currentlinewidth");
- cmdout(emstr);
- snprintf(emstr, sizeof(emstr), "%.1f setlinewidth", emwidth);
- cmdout(emstr);
- }
- empoint = emptget(empoint1);
- numout(empoint->x);
- numout(empoint->y);
- cmdout("a");
- empoint = emptget(empoint2);
- numout(empoint->x);
- numout(empoint->y);
- cmdout("li");
- cmdout("st");
- if (emwidth!=-1.0) {
- strcpy(emstr,"setlinewidth");
- cmdout(emstr);
- }
- }
- else if (strncmp(emp, "message", 7) == 0) {
- fprintf_str(stderr, "em message: %s\n", emp+7);
- }
- else if (strncmp(emp, "graph", 5) == 0) {
- int i;
- for (emp = emp+5; *emp && isspace((unsigned char)*emp); emp++); /* skip blanks */
- for (i=0; *emp && !isspace((unsigned char)*emp) && !(*emp==','); emp++) {
- if (i > (int)sizeof(emstr) - 2) {
- fprintf(stderr, "em:graph: special too long, truncating\n");
- break;
- }
- emstr[i++] = *emp; /* copy filename */
- }
- emstr[i] = '\0';
- /* now get optional width and height */
- emwidth = emheight = -1.0; /* no dimension is <= 0 */
- for (; *emp && ( isspace((unsigned char)*emp) || (*emp==',') ); emp++)
- ; /* skip blanks and comma */
- if (*emp) {
- sscanf(emp, "%f%2s", &emwidth, emunit); /* read width */
- emwidth = emunits(emwidth,emunit); /* convert to pixels */
- for (; *emp && (*emp=='.'||isdigit((unsigned char)*emp)||isalpha((unsigned char)*emp)); emp++)
- ; /* skip width dimension */
- for (; *emp && ( isspace((unsigned char)*emp) || (*emp==',') ); emp++)
- ; /* skip blanks and comma */
- if (*emp) {
- sscanf(emp, "%f%2s", &emheight, emunit); /* read height */
- emheight = emunits(emheight,emunit)*vactualdpi/actualdpi;
- }
- }
- if (emstr[0]) {
- emgraph(emstr,emwidth,emheight);
- }
- else {
- fprintf(stderr, "em:graph: no file given\n");
- }
- }
- else {
- sprintf(errbuf,
- "Unknown em: command (%s) in \\special will be ignored", p);
- specerror(errbuf);
- }
- return;
- }
-
-
-/* em:graph routines */
-
-/* The graphics routines currently decode 3 types of IBM-PC based graphics */
-/* files: .pcx, .bmp, .msp. The information on the formats has occasionally */
-/* been sketchy, and subject to interpretation. I have attempted to implement*/
-/* these routines to correctly decode the graphics file types mentioned. */
-/* The compressed .bmp file type has not been tested fully due to a lack of */
-/* test files. */
-/* */
-/* The method of reading in the headers of the binary files is ungainly, but */
-/* portable. Failure to use a byte by byte read and convert method will */
-/* result in portability problems. Specifically there is no requirement that */
-/* elements of a C structure be contiguous, only that they have an ascending */
-/* order of addresses. */
-/* */
-/* The current implementations of the graphics format to postscript */
-/* conversion are not the most efficient possible. Specifically: color */
-/* formats are converted to RGB ratios prior to using a simple thresholding */
-/* method to determine if the postscript bit is to be set. The thresholding */
-/* method is compabible with that used in emtex's drivers. */
-/* */
-/* Please send bug reports relating to the em:graph routines to: */
-/* maurice@bruce.cs.monash.edu.au */
-/* */
-/* My thanks to Russell Lang for his assistance with the implementation of */
-/* these routines in a manner compatible with dvips and for the optimization */
-/* of some routines. */
-/* */
-/* Maurice Castro */
-/* 8 Oct 92 */
-
-/* Routines to read binary numbers from IBM PC file types */
-static integer
-readinteger(FILE *f)
-{
- integer i;
- int r;
-
- i = 0;
- for (r = 0; r < 4; r++)
- {
- i = i | ( ((integer) fgetc(f)) << (8*r) );
- }
- return(i);
-}
-
-static halfword
-readhalfword(FILE *f)
-{
- halfword i;
- int r;
-
- i = 0;
- for (r = 0; r < 2; r++)
- {
- i = i | ( ((halfword) fgetc(f)) << (8*r) );
- }
- return(i);
-}
-
-#define readquarterword(f) ((unsigned char)fgetc(f))
-#define tobyte(x) ((x/8) + (x%8 ? 1 : 0))
-
-/* These routines will decode PCX files produced by Microsoft
- * Windows Paint. Other programs may not produce files which
- * will be successfully decoded, most notably version 1.xx of
- * PC Paint. */
-
-/*
- * Type declarations. integer must be a 32-bit signed; shalfword must
- * be a sixteen-bit signed; halfword must be a sixteen-bit unsigned;
- * quarterword must be an eight-bit unsigned.
- */
-typedef struct
-{
- quarterword man;
- quarterword ver;
- quarterword enc;
- quarterword bitperpix;
- halfword xmin;
- halfword ymin;
- halfword xmax;
- halfword ymax;
- halfword hres;
- halfword vres;
- quarterword pal[48];
- quarterword reserved;
- quarterword colorplanes;
- halfword byteperline;
- halfword paltype;
- quarterword fill[58];
-} PCXHEAD;
-
-static int
-PCXreadhead(FILE *pcxf, PCXHEAD *pcxh)
-{
- pcxh->man = readquarterword(pcxf);
- pcxh->ver = readquarterword(pcxf);
- pcxh->enc = readquarterword(pcxf);
- pcxh->bitperpix = readquarterword(pcxf);
- pcxh->xmin = readhalfword(pcxf);
- pcxh->ymin = readhalfword(pcxf);
- pcxh->xmax = readhalfword(pcxf);
- pcxh->ymax = readhalfword(pcxf);
- pcxh->hres = readhalfword(pcxf);
- pcxh->vres = readhalfword(pcxf);
- fread(pcxh->pal, 1, 48, pcxf);
- pcxh->reserved = readquarterword(pcxf);
- pcxh->colorplanes = readquarterword(pcxf);
- pcxh->byteperline = readhalfword(pcxf);
- pcxh->paltype = readhalfword(pcxf);
- fread(pcxh->fill, 1, 58, pcxf);
-
- if (feof(pcxf))
- return(0); /* fail */
- if (pcxh->man != 0x0a)
- return(0); /* fail */
- if (pcxh->enc != 0x1)
- return(0); /* fail */
- return(1); /* success */
- }
-
-static int
-PCXreadline(FILE *pcxf,
- unsigned char *pcxbuf,
- unsigned int byteperline)
-{
- int n;
- int c;
- int i;
-
- n = 0;
- memset(pcxbuf,0,byteperline);
- do {
- c = fgetc(pcxf);
- if ((c & 0xc0) == 0xc0) {
- i = c & 0x3f;
- c = fgetc(pcxf) & 0xff;
- while ((i--) && (n < byteperline)) pcxbuf[n++] = c;
- }
- else {
- pcxbuf[n++] = c & 0xff;
- }
- } while (n < byteperline);
- if (c==EOF) n=0;
- return(n);
-}
-
-static void
-PCXgetpalette(FILE *pcxf, PCXHEAD *pcxh,
- unsigned char *r,
- unsigned char *g,
- unsigned char *b)
-{
- int i;
-
- /* clear palette */
- for (i=0; i < 256; i++) {
- r[i] = 0;
- g[i] = 0;
- b[i] = 0;
- }
-
- switch (pcxh->ver) {
- case 0:
- /* version 2.5 of PC Paint Brush */
- for (i=0; i < 16; i++) {
- r[i] = pcxh->pal[i*3];
- g[i] = pcxh->pal[i*3+1];
- b[i] = pcxh->pal[i*3+2];
- }
- break;
- case 2:
- if (pcxh->colorplanes != 1) {
- /* version 2.8 of PC Paint Brush with valid Palette */
- for (i=0; i < 16; i++) {
- r[i] = pcxh->pal[i*3];
- g[i] = pcxh->pal[i*3+1];
- b[i] = pcxh->pal[i*3+2];
- }
- }
- else { /* not sure if this is correct - rjl */
- /* mono palette */
- r[0] = 0x00; g[0] = 0x00; b[0] = 0x00;
- r[1] = 0xff; g[1] = 0xff; b[1] = 0xff;
- }
- break;
- case 3:
- /* version 2.8 of PC Paint Brush with no valid Palette */
- /* either mono or default */
-
- if (pcxh->colorplanes != 1) {
- /* Color default palette - should be checked */
- r[0] = 0x00; g[0] = 0x00; b[0] = 0x00;
- r[1] = 0x80; g[1] = 0x00; b[1] = 0x00;
- r[2] = 0x00; g[2] = 0x80; b[2] = 0x00;
- r[3] = 0x80; g[3] = 0x80; b[3] = 0x00;
- r[4] = 0x00; g[4] = 0x00; b[4] = 0x80;
- r[5] = 0x80; g[5] = 0x00; b[5] = 0x80;
- r[6] = 0x00; g[6] = 0x80; b[6] = 0x80;
- r[7] = 0x80; g[7] = 0x80; b[7] = 0x80;
- r[8] = 0xc0; g[8] = 0xc0; b[8] = 0xc0;
- r[9] = 0xff; g[9] = 0x00; b[9] = 0x00;
- r[10] = 0x00; g[10] = 0xff; b[10] = 0x00;
- r[11] = 0xff; g[11] = 0xff; b[11] = 0x00;
- r[12] = 0x00; g[12] = 0x00; b[12] = 0xff;
- r[13] = 0xff; g[13] = 0x00; b[13] = 0xff;
- r[14] = 0x00; g[14] = 0xff; b[14] = 0xff;
- r[15] = 0xff; g[15] = 0xff; b[15] = 0xff;
- }
- else {
- /* mono palette */
- r[0] = 0x00; g[0] = 0x00; b[0] = 0x00;
- r[1] = 0xff; g[1] = 0xff; b[1] = 0xff;
- }
- break;
- case 5:
- default:
- /* version 3.0 of PC Paint Brush or Better */
- fseek(pcxf, -769L, SEEK_END);
- /* if signature byte is correct then read the palette */
- /* otherwise copy the existing palette */
- if (fgetc(pcxf) == 12) {
- for (i=0; i < 256; i++) {
- r[i] = fgetc(pcxf);
- g[i] = fgetc(pcxf);
- b[i] = fgetc(pcxf);
- }
- }
- else {
- for (i=0; i < 16; i++) {
- r[i] = pcxh->pal[i*3];
- g[i] = pcxh->pal[i*3+1];
- b[i] = pcxh->pal[i*3+2];
- }
- }
- break;
- }
-}
-
-static void
-PCXshowpicture(FILE *pcxf, int wide, int high, int bytes,
- int cp, int bp, unsigned char *r,
- unsigned char *g, unsigned char *b)
-{
- int x;
- int y;
- int c;
- unsigned char *rowa[4]; /* row array */
- unsigned char *row;
- int p;
- unsigned char *pshexa;
- int xdiv, xmod, xbit;
- int width;
- int bytewidth;
-
- bytewidth = tobyte(wide);
- width = bytewidth * 8;
-
- /* output the postscript image size preamble */
- cmdout("/picstr ");
- numout((integer)tobyte(wide));
- cmdout("string def");
-
- numout((integer)width);
- numout((integer)high);
- numout((integer)1);
- newline();
-
- cmdout("[");
- numout((integer)width);
- numout((integer)0);
- numout((integer)0);
- numout((integer)-high);
- numout((integer)0);
- numout((integer)0);
- cmdout("]");
-
- nlcmdout("{currentfile picstr readhexstring pop} image");
-
- /* allocate the postscript hex output array */
- pshexa = (unsigned char *) mymalloc((integer)bytewidth);
-
- /* make sure that you start at the right point in the file */
- fseek(pcxf, (long) sizeof(PCXHEAD), SEEK_SET);
-
- /* malloc the lines */
- row = (unsigned char *) mymalloc((integer)bytes * cp);
- for (c = 0; c < cp; c++)
- rowa[c] = row + bytes*c;
-
- for (y = 0; y < high; y++) {
- /* clear the postscript hex array */
- memset(pshexa,0xff,bytewidth);
-
- /* read in all the color planes for a row of pixels */
- PCXreadline(pcxf, rowa[0], bytes*cp);
-
- /* process each pixel */
- for (x = 0; x < wide; x++) {
- /* build up the pixel value from color plane entries */
- p = 0;
- xdiv = x>>3;
- xmod = 7 - (x&7);
- xbit = 1 << xmod;
- switch(bp) {
- case 1:
- for (c = 0; c < cp; c++) {
- row = rowa[c];
- p |= ( (unsigned)(row[xdiv] & xbit) >> xmod ) << c;
- }
- break;
- case 4: /* untested - most programs use 1 bit/pixel, 4 planes */
- row = rowa[0]; /* assume single plane */
- p = ( x & 1 ? row[xdiv] : row[xdiv]>>4 ) & 0x0f;
- break;
- case 8:
- row = rowa[0]; /* assume single plane */
- p = (unsigned) (row[x]);
- break;
- default:
- fprintf(stderr, "em:graph: Unable to Decode this PCX file\n");
- return;
- }
- if ((r[p] < 0xff) || (g[p] < 0xff) || (b[p] < 0xff))
- pshexa[xdiv] &= (~xbit);
- else
- pshexa[xdiv] |= xbit;
- }
- newline();
- mhexout(pshexa,(long)bytewidth);
- }
- free(pshexa);
- free(rowa[0]);
-}
-
-static void
-imagehead(char *filename, int wide, int high,
- float emwidth, float emheight)
-{
- char *fullname = NULL, *name;
- if (!quiet) {
-#ifdef KPATHSEA
- fullname = (char *)kpse_find_file (filename, pictpath, 0);
-#endif
- if (!fullname)
- name = filename;
- else
- name = fullname;
- if (strlen(name) + prettycolumn > STDOUTSIZE) {
- fprintf(stderr,"\n");
- prettycolumn = 0;
- }
- fprintf_str(stderr,"<%s",name);
- fflush(stderr);
- prettycolumn += 2+strlen(name);
- if (fullname) free (fullname);
- }
- hvpos();
- nlcmdout("@beginspecial @setspecial");
- if (!disablecomments) {
- cmdout("%%BeginDocument: em:graph");
- cmdout(filename);
- newline();
- }
- /* set the image size */
- if (emwidth <= 0.0) emwidth = (float)wide;
- if (emheight <= 0.0) emheight = (float)high;
- floatout(emwidth*72/actualdpi);
- floatout(emheight*72/vactualdpi);
- newline();
- cmdout("scale");
-#ifdef DEBUG
- if (dd(D_SPECIAL)) {
- fprintf(stderr,
- "\nem:graph: %s width %d pixels scaled to %.1f pixels\n",
- filename, wide, emwidth);
- fprintf_str(stderr,
- "em:graph: %s height %d pixels scaled to %.1f pixels\n",
- filename, high, emheight);
- }
-#endif
-}
-
-static void
-imagetail(void)
-{
- if (!disablecomments) {
- fprintf(bitfile, "\n%%%%EndDocument\n");
- linepos = 0;
- }
- nlcmdout("@endspecial");
- if (!quiet) {
- fprintf(stderr,">");
- fflush(stderr);
- }
-}
-
-static void
-pcxgraph(FILE *pcxf, char *filename,
- float emwidth, float emheight /* dimension in pixels */ )
-{
- PCXHEAD pcxh;
- unsigned char red[256];
- unsigned char green[256];
- unsigned char blue[256];
- int wide;
- int high;
- int bytes;
- int cp;
- int bpp;
-
- if (!PCXreadhead(pcxf, &pcxh)) {
- sprintf(errbuf,"em:graph: Unable to Read Valid PCX Header");
- specerror(errbuf);
- }
- PCXgetpalette(pcxf, &pcxh, red, green, blue);
-
- /* picture size calculation */
- wide = (pcxh.xmax - pcxh.xmin) + 1;
- high = (pcxh.ymax - pcxh.ymin) + 1;
- bytes = pcxh.byteperline;
- cp = pcxh.colorplanes;
- bpp = pcxh.bitperpix;
-
- imagehead(filename,wide,high,emwidth,emheight);
- PCXshowpicture(pcxf, wide, high, bytes, cp, bpp, red, green, blue);
- imagetail();
-}
-
-/* Microsoft Paint routines */
-struct wpnt_1 {
- quarterword id[4];
- halfword width;
- halfword high;
- halfword x_asp;
- halfword y_asp;
- halfword x_asp_prn;
- halfword y_asp_prn;
- halfword width_prn;
- halfword high_prn;
- integer chk_sum;
- halfword chk_head;
-};
-
-#define WPAINT_1 1
-#define WPAINT_2 2
-
-static void
-MSP_2_ps(FILE *f, int wide, int high)
-{
- char *line;
- char *l;
- int i;
- int j;
- unsigned char a, b, c;
- int d;
- int width;
- halfword *linelen;
-
- /* an undocumented format - based on a type of run length encoding */
- /* the format is made up of a list of line lengths, followed by a set */
- /* of lines. Each line is made up of 2 types of entries: */
- /* 1) A 3 term entry (0 a b): the byte b is repeated a times */
- /* 2) A variable length entry (a xxxx....xxxx): a bytes are read */
- /* from the file. */
- /* These entries are combined to build up a line */
-
- width = tobyte(wide)*8;
-
- /* output the postscript image size preamble */
- cmdout("/picstr");
- numout((integer)tobyte(wide));
- cmdout("string def");
-
- numout((integer)width);
- numout((integer)high);
- numout((integer)1);
-
- cmdout("[");
- numout((integer)width);
- numout((integer)0);
- numout((integer)0);
- numout((integer)-high);
- numout((integer)0);
- numout((integer)0);
- cmdout("]");
-
- nlcmdout("{currentfile picstr readhexstring pop} image");
-
- fseek(f, 32, SEEK_SET);
-
- /* read in the table of line lengths */
- linelen = (halfword *) mymalloc((integer)sizeof(halfword) * high);
- for (i = 0; i < high; i++) {
- linelen[i] = readhalfword(f);
- if (feof(f))
- return;
- }
-
- line = (char *) mymalloc((integer)tobyte(wide));
- for (i = 0; i < high; i++) {
- memset(line, 0xff, tobyte(wide));
- l = line;
- if (linelen[i] != 0) {
- d = linelen[i];
- while (d) {
- a = fgetc(f);
- d--;
- if (a == 0) {
- b = fgetc(f);
- c = fgetc(f);
- d -= 2;
- for (j = 0; j < b; j++)
- *l++ = c;
- }
- else {
- for (j = 0; j < a; j++)
- *l++ = fgetc(f);
- d -= j;
- }
- }
- }
- newline();
- mhexout((unsigned char *) line,(long)tobyte(wide));
- }
- free(linelen);
- free(line);
-}
-
-static void
-MSP_1_ps(FILE *f, int wide, int high)
-{
- char *line;
- int i;
- int width;
-
- width = tobyte(wide)*8;
- /* an partly documented format - see The PC Sourcebook */
- /* the format is made up of a simple bitmap. */
-
- /* output the postscript image size preamble */
- cmdout("/picstr");
- numout((integer)tobyte(wide));
- cmdout("string def");
-
- numout((integer)width);
- numout((integer)high);
- numout((integer)1);
-
- cmdout("[");
- numout((integer)width);
- numout((integer)0);
- numout((integer)0);
- numout((integer)-high);
- numout((integer)0);
- numout((integer)0);
- cmdout("]");
-
- nlcmdout("{currentfile picstr readhexstring pop} image");
-
- fseek(f, 32, SEEK_SET);
-
- line = (char *) mymalloc((integer)tobyte(wide));
- for (i = 0; i < high; i++) {
- fread(line, 1, tobyte(wide), f);
- newline();
- mhexout((unsigned char *) line,(long)tobyte(wide));
- }
- free(line);
-}
-
-
-static void
-mspgraph(FILE *f, char *filename, float emwidth, float emheight)
-{
- struct wpnt_1 head;
- int paint_type = 0;
-
- /* read the header of the file and figure out what it is */
- fread(head.id, 1, 4, f);
- head.width = readhalfword(f);
- head.high = readhalfword(f);
- head.x_asp = readhalfword(f);
- head.y_asp = readhalfword(f);
- head.x_asp_prn = readhalfword(f);
- head.y_asp_prn = readhalfword(f);
- head.width_prn = readhalfword(f);
- head.high_prn = readhalfword(f);
- head.chk_sum = readinteger(f);
- head.chk_head = readhalfword(f);
-
- if (feof(f)) {
- fprintf(stderr, "em:graph: Unable to Read Valid MSP Header\n");
- return;
- }
-
- /* check the id bytes */
- if (!memcmp(head.id, "DanM", 4))
- paint_type = WPAINT_1;
- if (!memcmp(head.id, "LinS", 4))
- paint_type = WPAINT_2;
-
-
- imagehead(filename,head.width,head.high,emwidth,emheight);
- switch (paint_type) {
- case WPAINT_1:
- MSP_1_ps(f, head.width, head.high);
- break;
- case WPAINT_2:
- MSP_2_ps(f, head.width, head.high);
- break;
- default:
- sprintf(errbuf, "em:graph: Unknown MSP File Type");
- specerror(errbuf);
- }
- imagetail();
-}
-
-/* ------------------------------------------------------------------------ */
-/* .BMP file structures */
-struct rgbquad {
- char blue;
- char green;
- char red;
- char res;
-};
-
-struct bitmapinfoheader {
- integer size;
- integer width;
- integer height;
- halfword planes; /* must be set to 1 */
- halfword bitcount; /* 1, 4, 8 or 24 */
- integer compression;
- integer sizeimage;
- integer xpelspermeter;
- integer ypelspermeter;
- integer clrused;
- integer clrimportant;
-};
-
-#ifdef WIN32
-#undef RGB
-#endif
-
-/* constants for the compression field */
-#define RGB 0L
-#define RLE8 1L
-#define RLE4 2L
-
-struct bitmapfileheader {
- char type[2];
- integer size;
- halfword reserved1;
- halfword reserved2;
- integer offbits;
-};
-
-static void
-rgbread(FILE *f, int w, int b, char *s)
-{
- int i;
-
- /* set the line to white */
- memset(s, 0xff, ((w*b)/8)+1);
-
- /* read in all the full bytes */
- for (i = 0; i < (w * b) / 8; i++)
- *s++ = fgetc(f);
-
- /* read in a partly filled byte */
- if ((w * b) % 8) {
- i++;
- *s++ = fgetc(f);
- }
-
- /* check that we are on a 32 bit boundary; otherwise align */
- while (i % 4 != 0) {
- fgetc(f);
- i++;
- }
-}
-
-unsigned rle_dx = 0; /* delta command horizontal offset */
-unsigned rle_dy = 0; /* delta command vertical offset */
-
-/* checked against output from Borland Resource Workshop */
-static void
-rle4read(FILE *f, int w, int b, char *s)
-{
- int i;
- int limit;
- int ch;
- unsigned cnt;
- int hi;
-
- limit = (w*b)/8;
- i = 0;
- hi = TRUE;
- /* set the line to white */
- memset(s, 0xff, limit+1);
-
- if (rle_dy) {
- rle_dy--;
- return;
- }
-
- if (rle_dx) {
- for (; rle_dx>1; rle_dx-=2) {
- s++;
- i++;
- }
- if (rle_dx)
- hi = FALSE;
- }
-
- while (i<=limit) {
- cnt = fgetc(f);
- ch = fgetc(f);
- if (cnt == 0) { /* special operation */
- switch(ch) {
- case 0: /* EOL */
- return; /* this is our way out */
- case 1: /* End of Bitmap */
- return;
- case 2: /* Delta */ /* untested */
- rle_dx = fgetc(f) + i*2 + (hi ? 1 : 0);
- rle_dy = fgetc(f);
- return;
- default: /* next cnt bytes are absolute */
- /* must be aligned on word boundary */
- if (!hi)
- fprintf(stderr,"em:graph: RLE4 absolute is not byte aligned\n");
- for (cnt = ch; cnt>0 && i<=limit; cnt-=2) {
- i++;
- *s++ = fgetc(f);
- }
- if (ch % 4) /* word align file */
- fgetc(f);
- }
- }
- else { /* cnt is repeat count */
- if (!hi) { /* we are about to place the low 4 bits */
- ch = ((ch>>4)&0x0f) | ((ch<<4)&0xf0); /* swap order */
- i++;
- *s = (*s & 0xf0) | (ch & 0x0f);
- s++;
- hi = TRUE;
- cnt--;
- }
- /* we are about to place the high 4 bits */
- for (; cnt>1 && i<=limit; cnt-=2) { /* place the whole bytes */
- i++;
- *s++ = ch;
- }
- if (cnt) { /* place the partial byte */
- *s = (*s & 0x0f) | (ch & 0xf0);
- hi = FALSE;
- }
- }
- }
-}
-
-/* untested */
-static void
-rle8read(FILE *f, int w, int b, char *s)
-{
- int i;
- int limit;
- int ch;
- unsigned cnt;
-
- limit = (w*b)/8;
- i = 0;
- /* set the line to white */
- memset(s, 0xff, limit+1);
-
- if (rle_dy) {
- rle_dy--;
- return;
- }
-
- if (rle_dx) {
- for (; rle_dx > 0; rle_dx--) {
- s++;
- i++;
- }
- }
-
- while (i<=limit) {
- cnt = fgetc(f);
- ch = fgetc(f);
- if (cnt == 0) { /* special operation */
- switch(ch) {
- case 0: /* EOL */
- return; /* this is our way out */
- case 1: /* End of Bitmap */
- return;
- case 2: /* Delta */ /* untested */
- rle_dx = fgetc(f) + i;
- rle_dy = fgetc(f);
- return;
- default: /* next cnt bytes are absolute */
- for (cnt = ch; cnt>0 && i<=limit; cnt--) {
- i++;
- *s++ = fgetc(f);
- }
- if (ch % 2) /* word align file */
- fgetc(f);
- }
- }
- else { /* cnt is repeat count */
- for (; cnt>0 && i<=limit; cnt--) {
- i++;
- *s++ = ch;
- }
- }
- }
-}
-
-static void
-bmpgraph(FILE *f, char *filename, float emwidth, float emheight)
-{
- struct bitmapfileheader bmfh;
- struct bitmapinfoheader bmih;
-
- #define ISBLACKSIZ 256
- unsigned char isblack[ISBLACKSIZ];
- unsigned char rr;
- unsigned char gg;
- unsigned char bb;
- unsigned char c = 0;
-
- char *line;
- char *pshexa;
-
- int clrtablesize;
- int i;
- int j;
-
- unsigned char omask;
- int oroll;
-
- unsigned char emask = 0;
- integer ewidth = 0;
- int isOS2;
-
- /* read the header of the file */
- fread(bmfh.type, 1, 2, f);
- bmfh.size = readinteger(f);
- bmfh.reserved1 = readhalfword(f);
- bmfh.reserved2 = readhalfword(f);
- bmfh.offbits = readinteger(f);
- if (feof(f)) {
- sprintf(errbuf, "em:graph: Unable to Read Valid BMP Header\n");
- specerror(errbuf);
- return;
- }
-
- bmih.size = readinteger(f);
- if (bmih.size == 12) { /* OS2 bitmap */
- isOS2 = TRUE;
- bmih.width = readhalfword(f);
- bmih.height = readhalfword(f);
- bmih.planes = readhalfword(f);
- bmih.bitcount = readhalfword(f);
- /* the following don't exist in OS2 format so fill with 0's */
- bmih.compression = RGB;
- bmih.sizeimage = 0;
- bmih.xpelspermeter = 0;
- bmih.ypelspermeter = 0;
- bmih.clrused = 0;
- bmih.clrimportant = 0;
- }
- else { /* Windows bitmap */
- isOS2 = FALSE;
- bmih.width = readinteger(f);
- bmih.height = readinteger(f);
- bmih.planes = readhalfword(f);
- bmih.bitcount = readhalfword(f);
- bmih.compression = readinteger(f);
- bmih.sizeimage = readinteger(f);
- bmih.xpelspermeter = readinteger(f);
- bmih.ypelspermeter = readinteger(f);
- bmih.clrused = readinteger(f);
- bmih.clrimportant = readinteger(f);
- }
-
- if (feof(f)) {
- sprintf(errbuf, "em:graph: Unable to Read Valid BMP Info");
- specerror(errbuf);
- return;
- }
-
- if (memcmp(bmfh.type, "BM", 2)) {
- sprintf(errbuf, "em:graph: Unknown BMP File Type");
- specerror(errbuf);
- return;
- }
-
- if ((bmih.compression == RLE4) && (bmih.bitcount != 4)) {
- sprintf(errbuf, "em:graph: Can't do BMP RLE4 with %d bits per pixel",
- bmih.bitcount);
- specerror(errbuf);
- return;
- }
-
- if ((bmih.compression == RLE8) && (bmih.bitcount != 8)) {
- sprintf(errbuf, "em:graph: Can't do BMP RLE8 with %d bits per pixel\n",
- bmih.bitcount);
- specerror(errbuf);
- return;
- }
-
- imagehead(filename,(int)bmih.width,(int)bmih.height,emwidth,emheight);
-
- /* determine the size of the color table to read */
- clrtablesize = 0;
- if (bmih.clrused == 0) {
- switch (bmih.bitcount) {
- case 1:
- clrtablesize = 2;
- break;
- case 4:
- clrtablesize = 16;
- break;
- case 8:
- clrtablesize = 256;
- break;
- case 24:
- break;
- }
- }
- else
- clrtablesize = bmih.clrused;
-
- if (clrtablesize > ISBLACKSIZ) {
- /* This is wrong, since we won't read the whole file below.
- But we can't give correct output without more work,
- and it's unlikely these specials are still in use. */
- sprintf(errbuf,
- "em color table size (%d) larger than %d; output incorrect",
- clrtablesize, ISBLACKSIZ);
- specerror(errbuf);
- clrtablesize = ISBLACKSIZ;
- }
-
- /* read in the color table */
- for (i = 0; i < clrtablesize; i++) {
- bb = fgetc(f);
- gg = fgetc(f);
- rr = fgetc(f);
- isblack[i] = (rr < 0xff) || (gg < 0xff) || (bb < 0xff);
- if (!isOS2)
- (void) fgetc(f);
- }
-
- line = (char *) mymalloc((integer)((bmih.width * bmih.bitcount) / 8) + 1);
- pshexa = (char *) mymalloc((integer)tobyte(bmih.width));
-
- /* output the postscript image size preamble */
- cmdout("/picstr");
- numout((integer)tobyte(bmih.width));
- cmdout("string def");
-
- numout((integer)bmih.width);
- numout((integer)bmih.height);
- numout((integer)1);
-
- cmdout("[");
- numout((integer)bmih.width);
- numout((integer)0);
- numout((integer)0);
- numout((integer)bmih.height);
- numout((integer)0);
- numout((integer)bmih.height);
- cmdout("]");
-
- nlcmdout("{currentfile picstr readhexstring pop} image");
-
- if (bmih.bitcount == 1) {
- if (bmih.width%8)
- emask = (1<<(8-(bmih.width%8)))-1; /* mask for edge of bitmap */
- else
- emask = 0;
- ewidth = tobyte(bmih.width);
- }
-
- /* read in all the lines of the file */
- for (i = 0; i < bmih.height; i++) {
- memset(pshexa,0xff,tobyte(bmih.width));
- switch (bmih.compression) {
- case RGB:
- rgbread(f, (int) bmih.width, (int) bmih.bitcount, line);
- break;
- case RLE4:
- rle4read(f, (int) bmih.width, (int) bmih.bitcount, line);
- break;
- case RLE8:
- rle8read(f, (int) bmih.width, (int) bmih.bitcount, line);
- break;
- default:
- sprintf(errbuf,"em:graph: Unknown BMP compression\n");
- specerror(errbuf);
- return;
- }
-
- omask = 0x80;
- oroll = 7;
-
- if (bmih.bitcount == 1) {
- if (isblack[0])
- for (j = 0; j < ewidth; j++)
- pshexa[j] = line[j];
- else
- for (j = 0; j < ewidth; j++)
- pshexa[j] = ~line[j];
- pshexa[ewidth-1] |= emask;
- }
- else {
- for (j = 0; j < bmih.width; j++) {
- switch (bmih.bitcount) {
- case 4:
- c = line[j>>1];
- if (!(j&1))
- c >>= 4;
- c = isblack[ c & 0x0f ];
- break;
- case 8:
- c = isblack[ (int)(line[j]) ];
- break;
- case 24:
- rr = line[j*3];
- gg = line[j*3+1];
- bb = line[j*3+2];
- c = (rr < 0xff) || (gg < 0xff) || (bb < 0xff);
- break;
- }
- if (c)
- pshexa[j/8] &= ~omask;
- else
- pshexa[j/8] |= omask;
- oroll--;
- omask >>= 1;
- if (oroll < 0) {
- omask = 0x80;
- oroll = 7;
- }
- }
- }
- newline();
- mhexout((unsigned char *) pshexa,(long)tobyte(bmih.width));
- }
- imagetail();
- free(pshexa);
- free(line);
-}
-/* ------------------------------------------------------------------------ */
-
-#define PCX 0
-#define MSP 1
-#define BMP 2
-const char *extarr[]=
-{ ".pcx", ".msp", ".bmp", NULL };
-
-static void
-emgraph(char *filename, float emwidth, float emheight)
-{
- char fname[500];
- int filetype;
- FILE *f;
- char *env;
- char id[4];
- int i;
-
- strcpy(fname, filename);
-
- /* find the file */
- f = search(figpath, fname, READBIN);
- if (f == (FILE *)NULL) {
- if ( (env = getenv("DVIDRVGRAPH")) != NULL )
-#ifdef KPATHSEA
- f = search((kpse_file_format_type)env,filename,READBIN);
-#else
- f = search(env,filename,READBIN);
-#endif
- }
- /* if still haven't found it try adding extensions */
- if (f == (FILE *)NULL) {
- i = 0;
- while (extarr[i] != NULL) {
- strcpy(fname, filename);
- strcat(fname, extarr[i]);
- f = search(figpath, fname, READBIN);
- if (f == (FILE *)NULL) {
- if ( (env = getenv("DVIDRVGRAPH")) != NULL )
-#ifdef KPATHSEA
- f = search((kpse_file_format_type)env,filename,READBIN);
-#else
- f = search(env,filename,READBIN);
-#endif
- }
- if (f != (FILE *)NULL)
- break;
- i++;
- }
- }
-
- filetype = -1;
- if (f != (FILE *)NULL) {
- for (i=0; i<4; i++) {
- id[i] = readquarterword(f);
- }
- if ( (id[0] == 0x0a) && (id[2] == 0x01) )
- filetype = PCX;
- if (!memcmp(id, "DanM", 4))
- filetype = MSP;
- if (!memcmp(id, "LinS", 4))
- filetype = MSP;
- if (!memcmp(id, "BM", 2))
- filetype = BMP;
- fseek(f, 0L, SEEK_SET);
- }
-
- switch (filetype) {
- case PCX:
- pcxgraph(f, fname, emwidth, emheight);
- break;
- case MSP:
- mspgraph(f, fname, emwidth, emheight);
- break;
- case BMP:
- bmpgraph(f, fname, emwidth, emheight);
- break;
- default:
- snprintf(fname, sizeof(fname),
- "em:graph: %s: File not found", filename);
- error(fname);
- }
- if (f != (FILE *)NULL)
- close_file(f);
-}
-
-#else
-void
-emspecial(char *p)
-{
- sprintf(errbuf,"emTeX specials not compiled in this version");
- specerror(errbuf);
-}
-#endif /* EMTEX */