eesnyder@boulder.Colorado.EDU (Eric E. Snyder) (04/10/91)
I am looking for a GIF viewer for an SGI IRIS. From what I can tell, the distribution stuff (showimage) appears only to handle the .rgb format such as that produced by the demo, dragon. Have I not found something I already have? Can I pick up such a program from an ftp site? Thanks! --------------------------------------------------------------------------- TTGATTGCTAAACACTGGGCGGCGAATCAGGGTTGGGATCTGAACAAAGACGGTCAGATTCAGTTCGTACTGCTG Eric E. Snyder Department of MCD Biology ...making feet for childrens' shoes. University of Colorado, Boulder Boulder, Colorado 80309-0347 LeuIleAlaLysHisTrpAlaAlaAsnGlnGlyTrpAspLeuAsnLysAspGlyGlnIleGlnPheValLeuLeu ---------------------------------------------------------------------------
asilver@eniac.seas.upenn.edu (Andy Silverman) (04/10/91)
-- +-----------------------------------+-----------------------------------------+ | Andy Silverman | Internet: asilver@grad1.cis.upenn.edu | | "Only x^y days till graduation..."| Compu$erve: 72261,531 Prodigy: JCSB27A | +-----------------------------------+-----------------------------------------+
thant@horus.esd.sgi.com (Thant Tessman) (04/11/91)
Here's a hack. It comes with NO guarantees, and NO support: /* * gifpaste - * display a GIF file on an IRIS * * written by Kipp Hickman @ Silicon Graphics - 1990 * * based on 'fromgif' by Paul Haeberli @ Silicon Graphics - 1989 * * * To compile on an IRIS: * * cc gifpaste.c -o gifpaste -lgl_s -lm * * */ #include "stdio.h" #include "math.h" #include "gl.h" #include "device.h" extern int getopt(int, const char **, const char *); extern char * optarg; extern int optind; extern int opterr; #define GIFGAMMA (1.5) /* smaller makes output image brighter */ short gamtab[256]; makegamtab(gam) float gam; { int i; for(i=0; i<256; i++) gamtab[i] = 255*pow(i/255.0,gam)+0.5; } short rbuf[4096]; short gbuf[4096]; short bbuf[4096]; #define COLSIZE 256 unsigned char *stackp; unsigned int prefix[4096]; unsigned char suffix[4096]; unsigned char stack[4096]; int datasize,codesize,codemask; /* Decoder working variables */ int clr,eoi; /* Special code values */ int avail, oldcode; FILE *infile; int global; /* Is there a global color map? */ int globalbits; /* Number of bits of global colors */ unsigned char globalmap[COLSIZE][3];/* RGB values for global color map */ char bgcolor; /* background color */ unsigned char *raster; /* Decoded image data */ unsigned int width, height; unsigned char red[COLSIZE]; unsigned char green[COLSIZE]; unsigned char blue[COLSIZE]; char *filename; Boolean noBorder = FALSE; main(int argc, char** argv) { int errs = 0; int opt; while ((opt = getopt(argc, argv, "n")) != -1) { switch (opt) { case 'n': noBorder = TRUE; break; default: errs++; break; } } if (optind < argc) { makegamtab(GIFGAMMA); filename = argv[optind]; if ((infile = fopen(filename,"r")) == NULL) { perror(filename); exit(1); } convert(); fclose(infile); exit(0); } fprintf(stderr, "Usage: %s [-n] file\n", argv[0]); exit(-1); } convert() { char ch; if (checksignature()) return; readscreen(); while ((ch = getc(infile)) != ';' && ch != EOF) { switch (ch) { case '\0': break; /* this kludge for non-standard files */ case ',': if (readgifimage()) return; break; case '!': readextension(); break; default: fprintf(stderr, "illegal GIF block type\n"); return; break; } } } checksignature() { char buf[6]; fread(buf,1,6,infile); if (strncmp(buf,"GIF",3)) { fprintf(stderr, "file is not a GIF file\n"); return 1; } if (strncmp(&buf[3],"87a",3)) { fprintf(stderr, "unknown GIF version number\n"); return 1; } return 0; } /* * readscreen - * Get information which is global to all the images stored * in the file */ readscreen() { unsigned char buf[7]; unsigned int screenwidth; /* The dimensions of the screen */ unsigned int screenheight; /* (not those of the image) */ unsigned int rscreenwidth; /* The dimensions of the raster */ fread(buf,1,7,infile); screenwidth = buf[0] + (buf[1] << 8); rscreenwidth = screenwidth + screenwidth%2; /* compensate odd widths */ screenheight = buf[2] + (buf[3] << 8); global = buf[4] & 0x80; if (global) { globalbits = (buf[4] & 0x07) + 1; fread(globalmap,3,1<<globalbits,infile); } bgcolor = buf[5]; } readgifimage() { unsigned char buf[9]; int local, interleaved; char localmap[256][3]; int localbits; unsigned int left,top; register row; register i; if (fread(buf, 1, 9, infile) == 0) { perror(filename); exit(1); } 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 == 0 && global == 0) { fprintf(stderr, "no colormap present for image\n"); return 1; } if ((raster = (unsigned char*) malloc(width*height+1000)) == NULL) { fprintf(stderr, "not enough memory for image\n"); return 1; } if (readraster(width, height)) return 1; if (local) { localbits = (buf[8] & 0x7) + 1; fprintf(stderr, " local colors: %d\n", 1<<localbits); fread(localmap, 3, 1<<localbits, infile); initcolors(localmap, 1<<localbits, bgcolor); } else if (global) { initcolors(globalmap, 1<<globalbits, bgcolor); } rasterize(interleaved, raster); free(raster); return 0; } /* * readextension - * Read a GIF extension block (and do nothing with it). * */ readextension() { unsigned char code; int count; char buf[255]; code = getc(infile); while (count = getc(infile)) fread(buf, 1, count, infile); } /* * readraster - * Decode a raster image * */ readraster(width, height) unsigned width,height; { unsigned char *fill = raster; unsigned char buf[255]; register bits=0; register unsigned datum=0; register unsigned char *ch; register int count, code; datasize = getc(infile); clr = 1 << datasize; eoi = clr + 1; avail = clr + 2; oldcode = -1; codesize = datasize + 1; codemask = (1 << codesize) - 1; for (code = 0; code < clr; code++) { prefix[code] = 0; suffix[code] = code; } stackp = stack; 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) { /* This kludge put in */ #ifdef DEBUG fprintf(stderr, "found eoi code\n"); #endif goto exitloop; /* because some GIF files*/ } /* aren't standard */ if (process(code, &fill)) { goto exitloop; } } } if (fill >= raster + width*height) { fprintf(stderr, "raster full before eoi code\n"); goto exitloop; } } exitloop: if (fill != raster + width*height) { fprintf(stderr, "warning: wrong rastersize: %ld bytes\n", (long) (fill-raster)); fprintf(stderr, " instead of %ld bytes\n", (long) width*height); return 0; /* can still draw a picture ... */ } return 0; } /* * process - * Process a compression code. "clear" resets the code table. * Otherwise make a new code table entry, and output the bytes * associated with the code. */ process(code, fill) register code; unsigned char **fill; { int incode; static unsigned char firstchar; if (code == clr) { codesize = datasize + 1; codemask = (1 << codesize) - 1; avail = clr + 2; oldcode = -1; return 0; } if (oldcode == -1) { *(*fill)++ = suffix[code]; firstchar = oldcode = code; return 0; } if (code > avail) { fprintf(stderr, "code % d to large for %d\n", code, avail); return 1; } incode = code; if (code == avail) { /* the first code is always < avail */ *stackp++ = firstchar; code = oldcode; } while (code > clr) { *stackp++ = suffix[code]; code = prefix[code]; } *stackp++ = firstchar = suffix[code]; prefix[avail] = oldcode; suffix[avail] = firstchar; avail++; if (((avail & codemask) == 0) && (avail < 4096)) { codesize++; codemask += avail; } oldcode = incode; do { *(*fill)++ = *--stackp; } while (stackp > stack); return 0; } /* * initcolors - * Convert a color map (local or global) to arrays with R, G and B * values. * */ initcolors(colormap, ncolors, bgcolor) unsigned char colormap[COLSIZE][3]; int ncolors; int bgcolor; { register i, k; for (i = 0; i < ncolors; i++) { red[i] = gamtab[colormap[i][0]]; green[i] = gamtab[colormap[i][1]]; blue[i] = gamtab[colormap[i][2]]; } } rastertoimg(raster,xsize,ysize) unsigned char *raster; int xsize, ysize; { int x, y, ind; long* bits; long* lp; char buf[100]; lp = bits = (long*) malloc(sizeof(long) * xsize * ysize+1000); for(y=0; y<ysize; y++) { lp = &bits[(ysize-y-1)*xsize]; for(x=0; x<xsize; x++) { ind = *raster++; *lp++ = (red[ind]<<0)|(green[ind]<<8)|(blue[ind]<<16); } } prefsize(xsize, ysize); if (noBorder) noborder(); winopen("gifpaste"); RGBmode(); gconfig(); sprintf(buf, "gifpaste %s", filename); wintitle(buf); lrectwrite(0, 0, xsize-1, ysize-1, bits); swapbuffers(); qdevice(ESCKEY); qdevice(WINQUIT); qdevice(WINSHUT); for (;;) { short t, v; t = qread(&v); switch (t) { case REDRAW: reshapeviewport(); lrectwrite(0, 0, xsize-1, ysize-1, bits); swapbuffers(); break; case ESCKEY: case WINQUIT: case WINSHUT: winpop(); doublebuffer(); gconfig(); frontbuffer(TRUE); color(0); clear(); exit(0); } } } /* * rasterize - * Read a row out of the raster image and write it to the screen * */ rasterize(interleaved, raster) int interleaved; register unsigned char *raster; { register row, col; register unsigned char *rr; unsigned char *newras; #define DRAWSEGMENT(offset, step) \ for (row = offset; row < height; row += step) { \ rr = newras + row*width; \ bcopy(raster, rr, width); \ raster += width; \ } if ((newras = (unsigned char*) malloc(width*height+1000)) == NULL) { fprintf(stderr, "not enough memory for image\n"); return 1; } rr = newras; if (interleaved) { DRAWSEGMENT(0, 8); DRAWSEGMENT(4, 8); DRAWSEGMENT(2, 4); DRAWSEGMENT(1, 2); } else DRAWSEGMENT(0, 1); rastertoimg(newras,width,height); free(newras); }