nakada@husc8.HARVARD.EDU (Paul Nakada) (07/30/88)
# this is a Gif picture viewer for the Sun 3 computer .. It may work on others,
# butit hasn't been tested on anything besides a Sun 3/60. The code here works
# ok, but it needs some help with the unix interface. I am but a novice
# programmer, so please feel free to delve into it. This program in it's original
# incarnation was written by scott hemphill .. it was then converted to create a
# sun raster file. I hope somebody finds this useful...
# paul nakada
# nakada@husc4.harvard.edu
# nakada@husc4.bitnet
# nakada@husc4.uucp
#
#----------------------------<cut here, save, and sh <filename> >----------
# -------- Makefile --------
echo extracting file Makefile
cat << '#*\\\THE_END//////*#' > Makefile
CFILES = main.c error.c headers.c raster.c
OBJECTS = main.o error.o headers.o raster.o
PRINT = main.c error.c headers.c raster.c
CMD = vg
DESTIN = .
CFLAGS = -O $(DEFS)
DEFS =
LIBS = -lsuntool -lsunwindow -lpixrect
$(CMD) : $(OBJECTS) /lib/libc.a /usr/lib/libsuntool.a /usr/lib/libsunwindow.a /usr/lib/libpixrect.a
ld /lib/crt0.o $(OBJECTS) -o $(CMD) $(LIBS) -lc
depend :
@makedepend $(CFILES)
clean :
-rm $(OBJECTS) $(CMD)
print :
print -h $(PRINT)
lint :
lint $(CFILES)
#*\\\THE_END//////*#
# -------- error.c --------
echo extracting file error.c
cat << '#*\\\THE_END//////*#' > error.c
#include <stdio.h>
#include "viewgif.h"
void usage()
{
fprintf(stderr, "usage: %s [file ... ]\n", progname);
exit(1);
}
void fatal(s)
char *s;
{
fprintf(stderr,"%s: %s\n",progname, s);
exit(-1);
}
#*\\\THE_END//////*#
# -------- headers.c --------
echo extracting file headers.c
cat << '#*\\\THE_END//////*#' > headers.c
#include <stdio.h>
#include <ctype.h>
#include <suntool/sunview.h>
#include <suntool/canvas.h>
#include "viewgif.h"
#include "sunvgif.h"
void checksignature()
{
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");
}
void readscreen()
{
unsigned char buf[7];
xx=yy=0;
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 << globalbits,infile);
}
}
void initcolors(colortable, colormap,ncolors)
char
colortable[256][3];
unsigned char
colormap[256][3];
int ncolors;
{
register unsigned
color;
register
i;
for (i=0; i < ncolors; i++) {
red[i] = colormap[i][0];
green[i] = colormap[i][1];
blue[i] = colormap[i][2];
}
pw_setcmsname(pw, filename);
pw_putcolormap(pw, 0, ncolors, red, green, blue);
}
#*\\\THE_END//////*#
# -------- main.c --------
echo extracting file main.c
cat << '#*\\\THE_END//////*#' > main.c
#include <stdio.h>
#include <ctype.h>
#include <suntool/sunview.h>
#include <suntool/canvas.h>
#include "viewgif.h"
#include "sunvgif.h"
void main(argc, argv)
int
argc;
char
*argv[];
{
extern int
optinf,
opterr;
int i;
bool
used_stdin = FALSE;
opterr = 1;
scale = 2;
progname=argv[0];
argc--;
argv++;
if (argv[0][0]=='-')
if (argv[0][1] >='1' && argv[0][1]<='4') {
scale=argv[0][1]-'0';
argc--;
argv++;
}
for (i=0; i<argc; i++) {
if (strcmp(argv[i],"-") == 0) {
if (used_stdin) {
fprintf(stderr,"standard input used twice\n");
exit(1);
}
else {
used_stdin=TRUE;
}
}
#ifdef unix
else if (access(argv[i],4) == -1) {
fprintf(stderr, "%s: cannot access %s: ",progname, argv[i]);
perror("");
exit(1);
}
#endif unix
}
infile=stdin;
filename="stdin";
i=0;
do {
if (argc > 0) {
infile = fopen(argv[i],"r");
filename=argv[i];
}
do_prog();
(void) fclose(infile);
} while (++i < argc);
exit(0);
}
void draw_loop()
{
int quit = FALSE;
char ch;
do {
ch = getc(infile);
switch (ch) {
case '\0': break; /* this kludge for non-standard files */
case ',': readimage();
break;
case ';': quit = TRUE;
(void) notify_set_itimer_func(frame,draw_loop,
ITIMER_REAL,((struct itimerval *) 0),
((struct itimerval *) 0));
break;
case '!': readextension();
break;
default: fatal("illegal GIF block type");
fprintf(stderr,ch);
break;
}
} while (!quit);
}
void do_prog()
{
checksignature();
readscreen();
frame = window_create(NULL,FRAME,0);
window_set(frame,WIN_HEIGHT,scale*screenheight+28,WIN_WIDTH,scale*screenwidth+14,0);
canvas = window_create(frame,CANVAS,CANVAS_AUTO_SHRINK,FALSE,
CANVAS_WIDTH,screenwidth, CANVAS_HEIGHT,screenheight,
WIN_VERTICAL_SCROLLBAR,scrollbar_create(0),
WIN_HORIZONTAL_SCROLLBAR,scrollbar_create(0),0);
pw = canvas_pixwin(canvas);
(void) notify_set_itimer_func(frame,draw_loop,ITIMER_REAL,&NOTIFY_POLLING_ITIMER,
((struct itimerval *) 0));
window_main_loop(frame);
}
#*\\\THE_END//////*#
# -------- raster.c --------
echo extracting file raster.c
cat << '#*\\\THE_END//////*#' > raster.c
#include <stdio.h>
#include <suntool/sunview.h>
#include <suntool/canvas.h>
#include "viewgif.h"
#include "sunvgif.h"
void outcode(p)
register codetype
*p;
{
int x, y;
if (p->prefix)
outcode(p->prefix);
for (y=0; y < scale; y++) {
for (x=0; x < scale; x++) {
if (interleaved)
pw_put(pw, (left + xx) * scale + x,(interleavetable[yy] + top)
* scale + y, p->suffix);
else
pw_put(pw, (left + xx) * scale + x,(yy + top) * scale + y, p->suffix);
}
}
if (++xx > width-1) {
xx=0;
yy++;
pw_show(pw);
}
}
void process(code)
register
code;
{
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]);
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);
if ((avail & codemask) == 0 && avail < 4096) {
codesize++;
codemask += avail;
}
oldcode = code;
} else {
fatal("illegal code in raster data");
}
}
void readraster(width, height)
unsigned int
width,
height;
{
unsigned char
buf[255];
register bits=0;
register unsigned 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);
}
}
}
exitloop:
free(codetable);
}
/* Read image information (position, size, local color map, etc.) and convert
to postscript. */
void readimage()
{
unsigned char
buf[9];
bool
local;
char
localmap[256][3];
int localbits;
register
row;
register 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<<localbits, infile);
initcolors(colortable, localmap, 1<<localbits);
} else if (global) {
initcolors(colortable, globalmap, 1<<globalbits);
} else {
fatal("no colormap present for image");
}
if (interleaved) {
interleavetable = (int*) malloc(height * sizeof(int));
if (!interleavetable)
fatal("not enough memory for interleave table");
row = 0;
for (i = 0; i < height; i += 8)
interleavetable[row++] = i;
for (i = 4; i < height; i += 8)
interleavetable[row++] = i;
for (i = 2; i < height; i += 4)
interleavetable[row++] = i;
for (i = 1; i < height; i += 2)
interleavetable[row++] = i;
}
pw_batch_on(pw);
readraster(width, height);
pw_batch_off(pw);
}
/* Read a GIF extension block (and do nothing with it). */
void readextension()
{
unsigned char
code,
count;
char
buf[255];
code = getc(infile);
while (count = getc(infile))
fread(buf,1,count,infile);
}
#*\\\THE_END//////*#
# -------- sunvgif.h --------
echo extracting file sunvgif.h
cat << '#*\\\THE_END//////*#' > sunvgif.h
Frame frame;
Canvas canvas;
Pixwin *pw;
#*\\\THE_END//////*#
# -------- viewgif.h --------
echo extracting file viewgif.h
cat << '#*\\\THE_END//////*#' > viewgif.h
#define TIMER_NULL ((struct itimerval *) 0)
#define TRUE 1
#define FALSE 0
typedef int bool;
typedef struct codestruct {
struct codestruct *prefix;
unsigned char first,suffix;
} codetype;
char *malloc();
int strncmp();
FILE *infile, *fopen();
void main(),
usage(),
fatal(),
checksignature(),
readscreen(),
initcolors(),
outcode(),
process(),
readraster(),
readimage(),
readextension(),
draw_loop(),
do_prog();
int scale,
datasize, codesize, codemask,
clear, eoi,
*interleavetable,
globalbits;
unsigned int
screenwidth,
screenheight,
xx,yy,
left,width,
top,height;
bool
global,
interleaved;
char
colortable[256][3],
*progname,
*filename;
unsigned char
red[256], green[256], blue[256],
globalmap[256][3];
codetype
*codetable;
#*\\\THE_END//////*#
echo Done with extraction
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
Paul Nakada '89 #8-) nakada@husc4.harvard.edu
Harvard College nakada@husc4.bitnet
Cambridge, MA {ihnp4!think, seismo, rutgers}!harvard!husc4!nakada
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_