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);
}