Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!usc!wuarchive!rex!samsung!umich!sharkey!news.iastate.edu!news From: tang@pv7017.vincent.iastate.edu (Tang De-Ming) Newsgroups: comp.lang.postscript Subject: giftops C-source program Message-ID: <1990Dec5.210753.14078@news.iastate.edu> Date: 5 Dec 90 21:07:53 GMT Sender: news@news.iastate.edu (USENET News System) Organization: Iowa State University, Ames, IA Lines: 368 I got this program quite awhile ago. It does not work on MSDOS machine even though the author claims that it is very portable. Someone may want to patch it to fix the memory problem. So far, it has worked for me on a SGI Iris machine. This program has two parts: 1. giftops.h 2. giftops.c I have combined those two files and labelled them by "cut here..." I did not write this program and no question should be directed to me. The author stated before that it is placed in public domain and thus you may distribute it freely to your friends. Deming Tang Iowa State University --------------Cut here and save into a file called giftops.h----------- /* local types */ #define min(x,y) ((x) < (y) ? (x) : (y)) #define FALSE 0 #define TRUE 1 typedef int bool; typedef struct codestruct { struct codestruct *prefix; unsigned char first,suffix; } codetype; /* local prototypes */ void usage(void); void fatal(char *s); void checksignature(void); void initcolors(char colortable[256][3], unsigned char colormap[256][3], int ncolors); void writeheader(unsigned int left, unsigned int top, unsigned int width, unsigned int height); void outcode(codetype *p,unsigned char **fill); void process(int code,unsigned char **fill); void readscreen(void); void rasterize(int row, int width); void readraster(unsigned int width,unsigned int height); void writetrailer(void); void readimage(void); void readextension(void); ------------------------------End of giftops.h--------------------------- ------------Cut here to save below into a file called giftops.c--------- /********************************************* * GIFtoPS Converter * * * * May 16, 1988 by Scott Hemphill * * * * I wrote this program, and hereby place it * * in the public domain, i.e. there are no * * copying restrictions of any kind. * *********************************************/ #include #include "giftops.h" char *malloc(); int strncmp(); FILE *infile; unsigned int screenwidth; /* The dimensions of the screen */ unsigned int screenheight; /* (not those of the image) */ bool global; /* Is there a global color map? */ int globalbits; /* Number of bits of global colors */ unsigned char globalmap[256][3]; /* RGB values for global color map */ char colortable[256][3]; /* Hex intensity strings for an image */ unsigned char *raster; /* Decoded image data */ codetype *codetable; /* LZW compression code data */ int datasize,codesize,codemask; /* Decoder working variables */ int clear,eoi; /* Special code values */ void usage(void) { fprintf(stderr,"usage: giftops input-file > output-file\n"); exit(-1); } void fatal(char *s) { fprintf(stderr,"giftops: %s\n",s); exit(-1); } void checksignature(void) { char buf[6]; fread(buf,1,6,infile); if (strncmp(buf,"GIF",3)) fatal("file is not a GIF file"); if (strncmp(&buf[3],"87a",3)) fatal("unknown GIF version number"); } /* Get information which is global to all the images stored in the file */ void readscreen(void) { unsigned char buf[7]; fread(buf,1,7,infile); screenwidth = buf[0] + (buf[1] << 8); screenheight = buf[2] + (buf[3] << 8); global = buf[4] & 0x80; if (global) { globalbits = (buf[4] & 0x07) + 1; fread(globalmap,3,1<>= 8; colortable[i][0] = hextab[color >> 4]; colortable[i][1] = hextab[color & 15]; colortable[i][2] = '\0'; } } /* Write a postscript header to the standard output. Standard paper size (8.5 by 11) is hard-coded, as is the whole initialization sequence. */ void writeheader(unsigned int left,unsigned int top, unsigned int width,unsigned int height) { double scale; int scaledwidth,scaledheight; scale = min(648.0/screenwidth, 468.0/screenheight); scaledwidth = (int)(scale*screenwidth+0.5); scaledheight = (int)(scale*screenheight+0.5); printf("currentscreen /proc exch def /angle exch def /frequency exch def\n"); printf("/angle 90 def /frequency 60 def\n"); printf("frequency angle /proc load setscreen\n"); printf("/picstr %d string def\n",width); printf("/screen {%d %d 8 [%d 0 0 -%d 0 %d]\n",width,height,width,height,height); printf(" {currentfile picstr readhexstring pop} image} def\n"); printf("%d %d translate 90 rotate %d %d scale screen\n", 306+(scaledheight>>1),396-(scaledwidth>>1), scaledwidth, scaledheight); } /* Output the bytes associated with a code to the raster array */ void outcode(register codetype *p,register unsigned char **fill) { if (p->prefix) outcode(p->prefix,fill); *(*fill)++ = p->suffix; } /* Process a compression code. "clear" resets the code table. Otherwise make a new code table entry, and output the bytes associated with the code. */ void process(register int code,unsigned char **fill) { static avail,oldcode; register codetype *p; if (code == clear) { codesize = datasize + 1; codemask = (1 << codesize) - 1; avail = clear + 2; oldcode = -1; } else if (code < avail) { outcode(&codetable[code],fill); if (oldcode != -1) { p = &codetable[avail++]; p->prefix = &codetable[oldcode]; p->first = p->prefix->first; p->suffix = codetable[code].first; if ((avail & codemask) == 0 && avail < 4096) { codesize++; codemask += avail; } } oldcode = code; } else if (code == avail && oldcode != -1) { p = &codetable[avail++]; p->prefix = &codetable[oldcode]; p->first = p->prefix->first; p->suffix = p->first; outcode(p,fill); if ((avail & codemask) == 0 && avail < 4096) { codesize++; codemask += avail; } oldcode = code; } else { fatal("illegal code in raster data"); } } /* Decode a raster image */ void readraster(unsigned int width,unsigned int height) { unsigned char *fill = raster; unsigned char buf[255]; register int bits=0; register unsigned int count,datum=0; register unsigned char *ch; register int code; datasize = getc(infile); clear = 1 << datasize; eoi = clear+1; codesize = datasize + 1; codemask = (1 << codesize) - 1; codetable = (codetype*)malloc(4096*sizeof(codetype)); if (!codetable) fatal("not enough memory for code table"); for (code = 0; code < clear; code++) { codetable[code].prefix = (codetype*)0; codetable[code].first = code; codetable[code].suffix = code; } for (count = getc(infile); count > 0; count = getc(infile)) { fread(buf,1,count,infile); for (ch=buf; count-- > 0; ch++) { datum += *ch << bits; bits += 8; while (bits >= codesize) { code = datum & codemask; datum >>= codesize; bits -= codesize; if (code == eoi) goto exitloop; /* This kludge put in because some GIF files aren't standard */ process(code,&fill); } } } exitloop: if (fill != raster + width*height) fatal("raster has the wrong size"); free(codetable); } /* Read a row out of the raster image and write it to the output file */ void rasterize(int row,int width) { register unsigned char *scanline; register int i; scanline = raster + row*width; for (i = 0; i < width; i++) { if (i % 40 == 0) printf("\n"); /* break line every 80 chars */ fputs(colortable[*scanline++],stdout); } printf("\n"); } /* write image trailer to standard output */ void writetrailer(void) { printf("showpage\n"); } /* Read image information (position, size, local color map, etc.) and convert to postscript. */ void readimage(void) { unsigned char buf[9]; unsigned int left,top,width,height; bool local,interleaved; unsigned char localmap[256][3]; int localbits; int *interleavetable; register int row; register int i; fread(buf,1,9,infile); left = buf[0] + (buf[1] << 8); top = buf[2] + (buf[3] << 8); width = buf[4] + (buf[5] << 8); height = buf[6] + (buf[7] << 8); local = buf[8] & 0x80; interleaved = buf[8] & 0x40; if (local) { localbits = (buf[8] & 0x7) + 1; fread(localmap,3,1<