diff options
Diffstat (limited to 'Build/source/texk/dvipsk/emspecial.c')
-rw-r--r-- | Build/source/texk/dvipsk/emspecial.c | 1469 |
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 */ |