Path: utzoo!attcan!uunet!tut.cis.ohio-state.edu!ucbvax!pasteur!miro.Berkeley.EDU!ph From: ph@miro.Berkeley.EDU (Paul Heckbert) Newsgroups: comp.graphics Subject: source code for filtered image zoom, part 3/3 Message-ID: <16205@pasteur.Berkeley.EDU> Date: 11 Aug 89 02:44:38 GMT Sender: news@pasteur.Berkeley.EDU Reply-To: ph@miro.Berkeley.EDU (Paul Heckbert) Organization: University of California at Berkeley Lines: 1622 # to unpack, cut here and run the following shell archive through sh # contents: libpic/pic.3 libpic/pic.h libpic/Makefile libpic/dump.h # libpic/iris.c libpic/iris.h libpic/pic.c libpic/pic_all.c # libpic/pic_file.c libpic/pixel.h libpic/window.c libpic/window.h # libpic/swap.c libpic/iris_pic.c libpic/dump_pic.c libsys/simple.h # libsys/Makefile # echo extracting libpic/pic.3 sed 's/^X//' <<'EOF13117' >libpic/pic.3 X.\" $Header$ X.\" a few macros X.de Cs \" code start X.DS X.ft B X.ta 9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n X.. X.de Ce \" code end X.ft R X.DE X.. X.de Ss \" subroutine definition start X.nf X.ft B X.ta 9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n,+9n X.. X.de Sd \" subroutine documentation X.ft R X.fi X.in +4n X.. X.de Se \" subroutine definition&documentation end X.in -4n X.. X.de DS X.nf X.in +4n X.sp .5v X.. X.de DE X.sp .5v X.in -4n X.fi X.. X.TH PIC 3 "10 August 1989" X.SH NAME Xpic \- subroutines for device-independent picture I/O X.SH OVERVIEW X\fIpic\fP is a package of subroutines for device-independent frame buffer I/O Xand format-independent picture file I/O. XIt is designed to provide a standard subroutine Xinterface for computer graphics and Ximage processing applications that manipulate raster images Xof 8, 24, or 32-bits per pixel. XApplication programs can be more portable if they Xdo all their raster graphics through this layer of routines Xrather than making device or format-dependent calls. XDevice or file format selection can be made at either compile-time or run-time. X.PP XTo use the package, an application program first calls \fIpic_open\fP, Xwhich opens a picture "device" for reading or writing Xand returns a pointer that is passed in all subsequent X\fIpic\fP calls. XSeveral pictures can be open simultaneously so that one could, for example, Xbe reading from two picture devices (or files) of different types, Xand writing to third device simultaneously. XFollowing the \fIpic_open\fP Xcall but before pixel I/O the program typically reads or Xwrites various parameters of the picture. XThe parameters supported by the \fIpic\fP library at present are: X.TP .5i X\fInchan\fP: \fBint nchan;\fP XNumber of channels in the picture: 1, 3, or 4. X1 channel means intensity, perhaps color mapped, X3 channels means RGB, and X4 channels means RGBA, where A=alpha=opacity. X.TP .5i X\fIbox\fP: \fBint xorig, yorig, xsize, ysize;\fP Xorigin and size of picture, where \fI(xorig,yorig)\fP is the upper left corner Xof the box and \fI(xsize,ysize)\fP is its size. X.PP XAfter these parameters are read or written by the application, Xit typically reads or writes pixels. XPixels can be accessed individually or on a scanline basis. XAll devices should support top-down scanline access, Xand some may support random access to pixels and scanlines as well. XThere is one set of routines for reading and writing 1-channel pictures Xand another set for reading and writing 3 or 4-channel pictures. XThree-channel pictures ignore (skip over) the \fIa\fP channel. XIf a picture was opened for reading then only the parameter "get" routines Xand pixel read routines should be called; Xif a picture was opened for writing then most device libraries will Xallow any of the parameter "set" or "get" Xor pixel read or write routines to be called. X.PP XWhen the application is done with a picture, it should call \fIpic_close\fP, Xwhich does device-dependent cleanup, perhaps flushing output buffers and Xclosing the device or file stream. X.PP XConventions: XPicture coordinates have the origin at the upper left, with x pointing right Xand y pointing down. XThe package currently has no notion of pixel aspect ratio, Xgamma correction, or color correction. XIt is an error to set any parameters after pixel writing has Xcommenced on a picture opened for writing. XAll pixel coordinates are in the same coordinate system (not window-relative). XChannels are 8 bits per pixel, with 0=dark and 255=bright. XThe pixel datatypes are: X.Cs Xtypedef unsigned char Pixel1; /* 1-channel picture */ Xtypedef struct {Pixel1 r, g, b, a;} Pixel1_rgba; /* 3 or 4-channel picture */ X.Ce X.SH SUBROUTINES XThe application should think of a picture as an abstract data type Xon which the following operations can be performed: X.Ss X#include X.Sd XShould be included by any application using \fIpic\fP. X.Se X X.Ss XPic *pic_open(name, mode) Xchar *name, *mode; X.Sd XOpen picture with filename \fIname\fP Xwith \fImode\fP=\fB"r"\fP for reading or \fB"w"\fP for writing. XReturns a pointer which must be used in all subsequent operations on the Xpicture. XReturns 0 if unsuccessful. XThis routine uses \fIpic_file_dev\fP to recognize the file's device type. X.Se X X.Ss Xvoid pic_close(p) XPic *p; X.Sd XClose picture, flushing buffers if necessary. XThis should be the last operation done on a picture. X.Se X X.Ss Xvoid pic_catalog() X.Sd XPrint a list of the device libraries linked in with the application. X.Se X X.Ss Xchar *pic_file_dev(file) Xchar *file; X.Sd XDetermine a file's device name by examining its magic number in its first Xfew bytes, if it is a file, or by recognizing the suffix of its name. XReturns 0 if device is unrecognized. XExamples: X.Cs Xpic_file_dev("mandrill.dump") == "dump" Xpic_file_dev("iris") == "iris" X.Ce X.in +4n X.Se X X.Ss Xchar *pic_get_name(p) Xchar *pic_get_dev(p) XPic *p; X.Sd XThese two routines returns the picture's filename or device name, Xrespectively. X.Se X X.Ss Xint pic_get_nchan(p) Xvoid pic_set_nchan(p, nchan) XPic *p; Xint nchan; X.Sd XReturns (\fIpic_get_nchan\fP) or sets (\fIpic_set_nchan\fP) the number Xof channels in the picture: 1, 3, or 4. X.Se X X.Ss Xvoid pic_get_box(p, &ox, &oy, &sx, &sy) Xvoid pic_set_box(p, ox, oy, sx, sy) XPic *p; Xint ox, oy, sx, sy; X.Sd XGet or set the origin \fI(ox,oy)\fP and size \fI(sx,sy)\fP of the device. XWhen a device with no intrinsic resolution (such as a picture file) is opened Xfor writing, its origin is undefined (ox==PIC_UNDEFINED) initially, Xso its box must be set before pixels can be written. X.Se X X.Ss XWindow *pic_get_window(p, win) Xvoid pic_set_window(p, win) XPic *p; XWindow *w; X.Sd XThis is an alternative scheme for getting or setting the box of a picture, Xredundant with the box routines above. XThe \fBWindow\fP structure is: X.Cs Xtypedef struct { /* WINDOW: A DISCRETE 2-D RECTANGLE */ X int x0, y0; /* xmin and ymin */ X int x1, y1; /* xmax and ymax (inclusive) */ X} Window; X.Ce X.in +4n XThe relation between box and window is: X\fI(x0,y0)=(ox,oy)\fP, \fI(x1,y1)=(ox+sx-1,oy+sy-1)\fP. X\fIpic_get_window\fP returns its window argument. X.Se X X.Ss XPixel1 pic_read_pixel(p, x, y) Xvoid pic_write_pixel(p, x, y, pv) XPic *p; Xint x, y; XPixel1 pv; X.Sd XRead or write a pixel from a 1-channel picture. X\fIpv\fP is the pixel value to write. X.Se X X.Ss Xvoid pic_read_pixel_rgba(p, x, y, pv) Xvoid pic_write_pixel_rgba(p, x, y, r, g, b, a) XPic *p; Xint x, y; XPixel1 r, g, b, a; XPixel1_rgba *pv; X.Sd XRead or write a pixel at \fI(x,y)\fP from a 3 or 4-channel picture. X.Se X X.Ss Xvoid pic_read_row(p, y, x0, nx, buf) Xvoid pic_write_row(p, y, x0, nx, buf) XPic *p; Xint y, x0, nx; XPixel1 *buf; X.Sd XRead or write a portion of the 1-channel scanline at y=\fIy\fP Xstarting at x=\fIx0\fP, Xextending \fInx\fP pixels to the right, from or to the array \fIbuf\fP, Xwhich has room for \fInx\fP 1-channel pixels. X.Se X X.Ss Xvoid pic_read_row_rgba(p, y, x0, nx, buf) Xvoid pic_write_row_rgba(p, y, x0, nx, buf) XPic *p; Xint y, x0, nx; XPixel1_rgba *buf; X.Sd XRead or write a portion of the 3 or 4-channel scanline at y=\fIy\fP Xstarting at x=\fIx0\fP, Xextending \fInx\fP pixels to the right, from or to the array \fIbuf\fP, Xwhich has room for \fInx\fP 4-channel pixels. X.Se X X.Ss Xvoid pic_read_block(p, x0, y0, nx, ny, buf) Xvoid pic_write_block(p, x0, y0, nx, ny, buf) Xvoid pic_read_block_rgba(p, x0, y0, nx, ny, buf_rgba) Xvoid pic_write_block_rgba(p, x0, y0, nx, ny, buf_rgba) XPic *p; Xint x0, y0, nx, ny; XPixel1 *buf; XPixel1_rgba *buf_rgba; X.Sd XSimilar to the row routines, but these read or write a rectangular block Xof pixels with upper left corner \fI(x0,y0)\fP and size \fI(nx,ny)\fP. XThe buffers are effectively of dimension \fI[ny][nx]\fP. X.Se X X.Ss Xvoid pic_clear(p, pv) XPic *p; XPixel1 pv; X.Sd XClear all pixels of the 1-channel picture to pixel value \fIpv\fP. X.Se X X.Ss Xvoid pic_clear_rgba(p, r, g, b, a) XPic *p; XPixel1 r, g, b, a; X.Sd XClear all pixels of the 3 or 4-channel picture to pixel value \fI(r,g,b,a)\fP. X.Se X X.Ss XPic *pic_load(name1, name2) Xchar *name1, *name2; X.Sd XCopy picture from file \fIname1\fP into file \fIname2\fP, Xand return the descriptor of the latter picture, Xopened for writing. X.Se X X.Ss Xvoid pic_save(p, name) XPic *p; Xchar *name; X.Sd XCopy the picture in \fIp\fP into a new picture in file \fIname\fP. XPicture \fIp\fP is not closed. X.Se X X.Ss Xvoid pic_copy(p, q) XPic *p, *q; X.Sd XCopy picture \fIp\fP into picture \fIq\fP. XNeither one is closed. X.Se X.SH LINKING XThe code within \fIpic\fP consists of two layers: the top layer of Xdevice-independent code, Xand the bottom layer of device-dependent "device libraries", Xwith one library for each device class known. XAn application using \fIpic\fP has control at compile time of which device Xlibraries are linked in to its executable file. XSome programs will be run on just one device, so it is wasteful of disk Xspace to link in more than the one device library, while other programs Xneed to read and write a variety of device types, so they will want to link Xin all device libraries. XLinking is controlled through the global array \fBpic_list\fP. XIf the application declares its own \fBpic_list\fP then it has Xexplicit control of the device libraries linked; Xotherwise the linker will pick up the default \fBpic_list\fP from X\fBpic_file.o\fP in \fBlibpic.a\fP and link in all device libraries. XTo create your own \fBpic_list\fP, put lines similar to the following Xin your application source code: X.Cs Xextern Pic pic_dump, pic_foo; XPic *pic_list[PIC_LISTMAX] = {&pic_dump, &pic_foo, 0}; X.Ce XThis will cause the "dump" and "foo" device libraries to be linked in. XNote: the "0" terminating \fBpic_list\fP is vital. XThe subroutine \fIpic_catalog()\fP prints \fBpic_list\fP. X.SH EXAMPLE XThe following program illustrates the use of the \fIpic\fP package: X.Cs X#include X#include X X/* pic_lum: take the luminance of afile and write it into bfile X * afile is expected to be 3 or 4-channel, bfile is written as 1-channel */ X Xpic_lum(afile, bfile) Xchar *afile, *bfile; X{ X int x, y, dx, dy; X Pic *a, *b; X Window win; X Pixel1_rgba *rgb; X Pixel1 *lum; X X a = pic_open(afile, "r"); X if (!a) die("can't read %s\en", afile); X b = pic_open(bfile, "w"); X if (!a) die("can't write %s\en", bfile); X if (pic_get_nchan(a)<3) die("%s is not 3 channel\en", afile); X X pic_set_nchan(b, 1); X pic_set_window(b, pic_get_window(a, &win)); X dx = win.x1-win.x0+1; X dy = win.y1-win.y0+1; X printf("%s->%s, res=%dx%d, origin=(%d,%d)\en", X afile, bfile, dx, dy, win.x0, win.y0); X X rgb = (Pixel1_rgba *)malloc(dx*sizeof(Pixel1_rgba)); X lum = (Pixel1 *)malloc(dx*sizeof(Pixel1)); X for (y=0; ylibpic/pic.h X/* X * pic.h: definitions for device-independent picture package X * X * Paul Heckbert, ph@miro.berkeley.edu Sept 1988 X * X * Copyright (c) 1989 Paul S. Heckbert X * This source may be used for peaceful, nonprofit purposes only, unless X * under licence from the author. This notice should remain in the source. X */ X X#ifndef PIC_HDR X#define PIC_HDR X X/* $Header: pic.h,v 2.1 88/11/01 21:09:58 ph Locked $ */ X#include X#include X Xtypedef struct { /* PICTURE PROCEDURE POINTERS */ X char *(*open)(/* name, mode */); X void (*close)(/* p */); X X char *(*get_name)(/* p */); X void (*clear)(/* p, pv */); X void (*clear_rgba)(/* p, r, g, b, a */); X X void (*set_nchan)(/* p, nchan */); X void (*set_box)(/* p, ox, oy, dx, dy */); X void (*write_pixel)(/* p, x, y, v */); X void (*write_pixel_rgba)(/* p, x, y, r, g, b, a */); X void (*write_row)(/* p, y, x0, nx, buf */); X void (*write_row_rgba)(/* p, y, x0, nx, buf */); X X int (*get_nchan)(/* p */); X void (*get_box)(/* p, ox, oy, dx, dy */); X Pixel1 (*read_pixel)(/* p, x, y */); X void (*read_pixel_rgba)(/* p, x, y, pv */); X void (*read_row)(/* p, y, x0, nx, buf */); X void (*read_row_rgba)(/* p, y, x0, nx, buf */); X} Pic_procs; X Xtypedef struct { /* PICTURE INFO */ X char *dev; /* device/filetype name */ X Pic_procs *procs; /* structure of generic procedure pointers */ X char *data; /* device-dependent data (usually ptr to structure) */ X} Pic; X X#define PIC_LISTMAX 20 Xextern Pic *pic_list[PIC_LISTMAX]; /* list of known picture devices */ Xextern int pic_npic; /* #pics in pic_list, set by pic_init */ X X#define PIC_UNDEFINED PIXEL_UNDEFINED /* used for unknown nchan */ X XPic *pic_open(/* name, mode */); XPic *pic_open_dev(/* dev, name, mode */); Xvoid pic_close(/* p */); X X#define pic_get_name(p) \ X (*(p)->procs->get_name)((p)->data) X#define pic_clear(p, pv) \ X (*(p)->procs->clear)((p)->data, pv) X#define pic_clear_rgba(p, r, g, b, a) \ X (*(p)->procs->clear_rgba)((p)->data, r, g, b, a) X X#define pic_set_nchan(p, nchan) \ X (*(p)->procs->set_nchan)((p)->data, nchan) X#define pic_set_box(p, ox, oy, dx, dy) \ X (*(p)->procs->set_box)((p)->data, ox, oy, dx, dy) X X#define pic_write_pixel(p, x, y, pv) \ X (*(p)->procs->write_pixel)((p)->data, x, y, pv) X#define pic_write_pixel_rgba(p, x, y, r, g, b, a) \ X (*(p)->procs->write_pixel_rgba)((p)->data, x, y, r, g, b, a) X#define pic_write_row(p, y, x0, nx, buf) \ X (*(p)->procs->write_row)((p)->data, y, x0, nx, buf) X#define pic_write_row_rgba(p, y, x0, nx, buf) \ X (*(p)->procs->write_row_rgba)((p)->data, y, x0, nx, buf) X X#define pic_get_nchan(p) \ X (*(p)->procs->get_nchan)((p)->data) X#define pic_get_box(p, ox, oy, dx, dy) \ X (*(p)->procs->get_box)((p)->data, ox, oy, dx, dy) X X#define pic_read_pixel(p, x, y) \ X (*(p)->procs->read_pixel)((p)->data, x, y) X#define pic_read_pixel_rgba(p, x, y, pv) \ X (*(p)->procs->read_pixel_rgba)((p)->data, x, y, pv) X#define pic_read_row(p, y, x0, nx, buf) \ X (*(p)->procs->read_row)((p)->data, y, x0, nx, buf) X#define pic_read_row_rgba(p, y, x0, nx, buf) \ X (*(p)->procs->read_row_rgba)((p)->data, y, x0, nx, buf) X X Xvoid pic_init(/* p */); Xvoid pic_catalog(); X#define pic_get_dev(p) (p)->dev XPic *pic_load(/* name1, name2 */); Xvoid pic_save(/* p, name */); Xvoid pic_copy(/* p, q */); Xvoid pic_set_window(/* p, win */); Xvoid pic_write_block(/* p, x0, y0, nx, ny, buf */); Xvoid pic_write_block_rgba(/* p, x0, y0, nx, ny, buf */); XWindow *pic_get_window(/* p, win */); Xvoid pic_read_block(/* p, x0, y0, nx, ny, buf */); Xvoid pic_read_block_rgba(/* p, x0, y0, nx, ny, buf */); X Xchar *pic_file_dev(/* file */); X X#endif EOF13118 echo extracting libpic/Makefile sed 's/^X//' <<'EOF13119' >libpic/Makefile X# $Header: Makefile,v 2.2 88/12/23 20:59:08 ph Locked $ X XDEST = .. XL = $(DEST)/lib XCOPTS = -g $(FLOATOPT) XIPATH = -I. -I$(DEST)/include XCFLAGS = $(IPATH) $(COPTS) X XSRC = window.c pic.c pic_all.c pic_file.c swap.c \ X dump.c dump_pic.c \ X iris.c iris_pic.c X XOBJ = window.o pic.o pic_all.o pic_file.o swap.o \ X dump.o dump_pic.o \ X iris.o iris_pic.o X XHDR = pixel.h window.h pic.h \ X dump.h iris.h X X.SUFFIXES: .o .s .i .c X X.c.i: X $(CC) $(CFLAGS) -P $*.c X cat -s <$*.i >temp X mv temp $*.i X Xall: libpic.a X Xlibpic.a: $(OBJ) X ar cu libpic.a $(OBJ) X ranlib libpic.a X Xinstall: libpic.a X mv libpic.a $L X# cp -p $(HDR) $(DEST)/include X cp $(HDR) $(DEST)/include X Xlibpic.lint: GHOST X lint $(IPATH) $(SRC) >libpic.lint X Xclean: X -rm -f libpic.a *.o *.lint X XGHOST: X Xpic.o: pic.h pixel.h Xwindow.o: window.h Xpic_all.o: pic.h Xpic_file.o: pic.h X Xdump.o: dump.h pixel.h Xiris.o: iris.h pixel.h X Xdump_pic.o: dump.h pic.h Xiris_pic.o: iris.h pic.h EOF13119 echo extracting libpic/dump.h sed 's/^X//' <<'EOF13120' >libpic/dump.h X#ifndef DUMP_HDR X#define DUMP_HDR X X/* $Header: dump.h,v 2.1 88/11/01 21:09:45 ph Locked $ */ X#include X#include X#define DUMP_NAMEMAX 80 X Xtypedef struct { X short magic; /* magic number */ X short nchan; /* number of channels (1=monochrome, 3=RGB) */ X short dx, dy; /* width and height of picture in pixels */ X} Dump_head; X Xtypedef struct { X char name[DUMP_NAMEMAX]; /* picture name */ X Dump_head h; /* file header */ X FILE *fp; /* stream for current file */ X int headsize; /* size of head in bytes (for fseek) */ X int headwritten; /* has header been written? */ X int curx, cury; /* current x and y */ X} Dump; X X#define DUMP_MAGIC 0x5088 /* dump magic number */ X XDump *dump_open(/* file, mode */); Xvoid dump_close(/* p */); X Xchar *dump_get_name(/* p */); Xvoid dump_clear(/* p, pv */); Xvoid dump_clear_rgba(/* p, r, g, b, a */); X Xvoid dump_set_nchan(/* p, nchan */); Xvoid dump_set_box(/* p, ox, oy, dx, dy */); Xvoid dump_write_pixel(/* p, x, y, pv */); Xvoid dump_write_pixel_rgba(/* p, x, y, r, g, b, a */); Xvoid dump_write_row(/* p, y, x0, nx, buf */); Xvoid dump_write_row_rgba(/* p, y, x0, nx, buf */); X Xint dump_get_nchan(/* p */); Xvoid dump_get_box(/* p, ox, oy, dx, dy */); XPixel1 dump_read_pixel(/* p, x, y */); Xvoid dump_read_pixel_rgba(/* p, x, y, pv */); Xvoid dump_read_row(/* p, y, x0, nx, buf */); Xvoid dump_read_row_rgba(/* p, y, x0, nx, buf */); X Xvoid dump_jump_to_pixel(/* p, x, y */); Xvoid dump_advance(/* p, nx */); X X#endif EOF13120 echo extracting libpic/iris.c sed 's/^X//' <<'EOF13121' >libpic/iris.c X/* X * iris: subroutine package to read and write iris pictures X * we flip y so to the user it points down X * note: this implementation is currently quite crufty: doesn't handle X * iris window events and doesn't allow pixel reading. X * X * Paul Heckbert 27 July 1989 X */ X Xstatic char rcsid[] = "$Header$ "; X X#include X X#include X#include "iris.h" X X#define XMAX 1280 /* screen size */ X#define YMAX 1024 X#define XFUDGE 5 X#define YFUDGE -25 X#define UNDEF PIXEL_UNDEFINED X X#define CHECK_UNINIT(p, subrname) { \ X if ((p)->init) { \ X fprintf(stderr, "%s: can't change state once writing commences\n", \ X subrname); \ X exit(1); \ X } \ X} X#define CHECK_INIT(p, subrname) \ X if (!(p)->init) iris_init(p, subrname); else X Xstatic Colorindex sbuf[XMAX]; Xstatic RGBvalue rbuf[XMAX]; Xstatic RGBvalue gbuf[XMAX]; Xstatic RGBvalue bbuf[XMAX]; X XIris *iris_open_write(); X XIris *iris_open(file, mode) Xchar *file, *mode; X{ X if (str_eq(mode, "w")) return iris_open_write(file); X fprintf(stderr, "iris_open: can't do mode %s\n", mode); X exit(1); /*NOTREACHED*/ X} X Xstatic Iris *iris_open_write(file) Xchar *file; X{ X Iris *p; X X ALLOC(p, Iris, 1); X p->nchan = 3; X /* p->ox = p->oy = UNDEF; */ X /* p->dx = p->dy = UNDEF; */ X p->ox = 0; X p->oy = 0; X p->dx = XMAX; X p->dy = YMAX; X strcpy(p->name, file); X p->init = 0; X return p; X} X Xstatic iris_init(p, subrname) XIris *p; Xchar *subrname; X{ X if (p->dx==UNDEF) { X fprintf(stderr, "%s: size of %s is uninitialized\n", subrname, p->name); X exit(1); X } X foreground(); /* keeps process from being forked */ X if (p->ox!=UNDEF) { X printf("prefposition(%d,%d, %d,%d)\n", X XFUDGE+p->ox, XFUDGE+p->ox+p->dx-1, X YFUDGE+YMAX-p->oy-p->dy, YFUDGE+YMAX-1-p->oy); X prefposition(XFUDGE+p->ox, XFUDGE+p->ox+p->dx-1, X YFUDGE+YMAX-p->oy-p->dy, YFUDGE+YMAX-1-p->oy); X } X /* window size & position for winopen */ X else prefsize(p->dx, p->dy);/* window size for winopen */ X p->id = winopen(p->name); /* create a screen window */ X if (p->nchan>=3) { X RGBmode(); /* window is 3-channel (not 1) */ X gconfig(); X RGBcolor(0, 0, 0); X } X else X color(0); X clear(); X printf("%s: %dx%d %d-chan\n", p->name, p->dx, p->dy, p->nchan); X p->init = 1; X} X Xvoid iris_close(p) XIris *p; X{ X /* KLUDGE so window doesn't disappear when process dies! */ X for (;;) sleep(9999); X X /* if (p->init) winclose(p->id); */ X /* free(p); */ X} X Xchar *iris_get_name(p) XIris *p; X{ X return p->name; X} X Xvoid iris_clear(p, pv) XIris *p; XPixel1 pv; X{ X color(pv); X clear(); X} X Xvoid iris_clear_rgba(p, r, g, b, a) XIris *p; XPixel1 r, g, b, a; X{ X RGBcolor(r, g, b); X clear(); X} X X/*-------------------- file writing routines --------------------*/ X Xvoid iris_set_nchan(p, nchan) XIris *p; Xint nchan; X{ X CHECK_UNINIT(p, "iris_set_nchan"); X if (nchan!=1 && nchan!=3) { X fprintf(stderr, "iris_set_nchan: can't handle nchan=%d\n", nchan); X exit(1); X } X p->nchan = nchan; X} X Xvoid iris_set_box(p, ox, oy, dx, dy) XIris *p; Xint ox, oy, dx, dy; X{ X CHECK_UNINIT(p, "iris_set_box"); X p->ox = ox; X p->oy = oy; X p->dx = dx; X p->dy = dy; X} X Xvoid iris_write_pixel(p, x, y, pv) XIris *p; Xint x, y; XPixel1 pv; X{ X Colorindex pv2; X X CHECK_INIT(p, "iris_write_row"); X cmov2i(x, p->dy-1-y); X pv2 = pv; X writepixels(1, &pv2); X} X Xvoid iris_write_pixel_rgba(p, x, y, r, g, b, a) XIris *p; Xint x, y; XPixel1 r, g, b, a; X{ X CHECK_INIT(p, "iris_write_row"); X /* note: RGBvalue is an unsigned char, just like Pixel1 */ X cmov2i(x, p->dy-1-y); X writeRGB(1, &r, &g, &b); X} X Xvoid iris_write_row(p, y, x0, nx, buf) XIris *p; Xint y, x0, nx; Xregister Pixel1 *buf; X{ X register int i; X register Colorindex *s; X X CHECK_INIT(p, "iris_write_row"); X for (s=sbuf, i=nx; i>0; i--) X *s++ = *buf++; X cmov2i(x0, p->dy-1-y); X writepixels(nx, sbuf); X} X Xvoid iris_write_row_rgba(p, y, x0, nx, buf) XIris *p; Xint y, x0, nx; Xregister Pixel1_rgba *buf; X{ X register int i; X register RGBvalue *r, *g, *b; X X CHECK_INIT(p, "iris_write_row_rgba"); X for (r=rbuf, g=gbuf, b=bbuf, i=nx; i>0; i--, buf++) { X *r++ = buf->r; X *g++ = buf->g; X *b++ = buf->b; X } X cmov2i(x0, p->dy-1-y); X writeRGB(nx, rbuf, gbuf, bbuf); X} X X/*-------------------- file reading routines --------------------*/ X Xint iris_get_nchan(p) XIris *p; X{ X return p->nchan; X} X Xvoid iris_get_box(p, ox, oy, dx, dy) XIris *p; Xint *ox, *oy, *dx, *dy; X{ X *ox = p->ox; X *oy = p->oy; X *dx = p->dx; X *dy = p->dy; X} X XPixel1 iris_read_pixel(p, x, y) XIris *p; Xint x, y; X{ X fprintf(stderr, "iris_read_pixel: unimplemented\n"); X} X Xvoid iris_read_pixel_rgba(p, x, y, pv) XIris *p; Xint x, y; XPixel1_rgba *pv; X{ X fprintf(stderr, "iris_read_pixel_rgba: unimplemented\n"); X} X Xvoid iris_read_row(p, y, x0, nx, buf) XIris *p; Xint y, x0, nx; XPixel1 *buf; X{ X fprintf(stderr, "iris_read_row: unimplemented\n"); X} X Xvoid iris_read_row_rgba(p, y, x0, nx, buf) XIris *p; Xint y, x0, nx; XPixel1_rgba *buf; X{ X fprintf(stderr, "iris_read_row_rgba: unimplemented\n"); X} EOF13121 echo extracting libpic/iris.h sed 's/^X//' <<'EOF13122' >libpic/iris.h X#ifndef IRIS_HDR X#define IRIS_HDR X X/* $Header$ */ X#include X#include X#define IRIS_NAMEMAX 80 X Xtypedef struct { X char name[IRIS_NAMEMAX]; /* picture name */ X short nchan; /* number of channels (1=monochrome, 3=RGB) */ X short ox, oy; /* origin (upper left corner) of screen */ X short dx, dy; /* width and height of picture in pixels */ X short init; /* window initialized yet? */ X long id; /* iris window number */ X} Iris; X XIris *iris_open(/* file, mode */); Xvoid iris_close(/* p */); X Xchar *iris_get_name(/* p */); Xvoid iris_clear(/* p, pv */); Xvoid iris_clear_rgba(/* p, r, g, b, a */); X Xvoid iris_set_nchan(/* p, nchan */); Xvoid iris_set_box(/* p, ox, oy, dx, dy */); Xvoid iris_write_pixel(/* p, x, y, pv */); Xvoid iris_write_pixel_rgba(/* p, x, y, r, g, b, a */); Xvoid iris_write_row(/* p, y, x0, nx, buf */); Xvoid iris_write_row_rgba(/* p, y, x0, nx, buf */); X Xint iris_get_nchan(/* p */); Xvoid iris_get_box(/* p, ox, oy, dx, dy */); XPixel1 iris_read_pixel(/* p, x, y */); Xvoid iris_read_pixel_rgba(/* p, x, y, pv */); Xvoid iris_read_row(/* p, y, x0, nx, buf */); Xvoid iris_read_row_rgba(/* p, y, x0, nx, buf */); X X#endif EOF13122 echo extracting libpic/pic.c sed 's/^X//' <<'EOF13123' >libpic/pic.c X/* pic: device-independent picture package */ X Xstatic char rcsid[] = "$Header: pic.c,v 2.1 88/11/01 21:09:56 ph Locked $"; X X#include X#include "pic.h" X Xint pic_npic = -1; X Xvoid pic_init() X{ X /* count the pic device types to set npic */ X for (pic_npic=0; pic_npicdev); i++); X if (i>=pic_npic) { X fprintf(stderr, "unknown pic device: %s\n", dev); X return 0; X } X q = pic_list[i]; X data = (*q->procs->open)(name, mode); X if (!data) return 0; X X /* copy the Pic structure before modifying it */ X ALLOC(p, Pic, 1); X *p = *q; X p->data = data; X return p; X} X Xvoid pic_close(p) XPic *p; X{ X (*p->procs->close)(p->data); X free(p); X} X X/* pic_catalog: print list of known (linked) device libraries */ X Xvoid pic_catalog() X{ X int i; X X if (pic_npic<0) pic_init(); X printf("picture devices/file formats known:"); X for (i=0; idev); X printf("\n"); X} X XPic *pic_load(name1, name2) Xchar *name1, *name2; X{ X Pic *p, *q; X X p = pic_open(name1, "r"); X if (!p) { X fprintf(stderr, "pic_load: can't open %s\n", name1); X return 0; X } X q = pic_open(name2, "w"); X if (!q) { X fprintf(stderr, "pic_load: can't open %s\n", name2); X pic_close(p); X return 0; X } X pic_copy(p, q); X pic_close(p); X return q; X} X Xvoid pic_save(p, name) XPic *p; Xchar *name; X{ X Pic *q; X X q = pic_open(name, "w"); X if (!q) { X fprintf(stderr, "pic_save: can't create %s\n", name); X return; X } X pic_copy(p, q); X pic_close(q); X} X Xvoid pic_copy(p, q) Xregister Pic *p, *q; X{ X int nchan, dx, y; X Window w; X Pixel1 *buf; X Pixel1_rgba *buf4; X X nchan = pic_get_nchan(p); X pic_set_nchan(q, nchan); X pic_set_window(q, pic_get_window(p, &w)); X dx = w.x1-w.x0+1; X switch (nchan) { X case 1: X ALLOC(buf, Pixel1, dx); X break; X case 3: X case 4: X ALLOC(buf4, Pixel1_rgba, dx); X break; X default: X fprintf(stderr, "pic_copy: can't handle nchan=%d\n", nchan); X return; X } X for (y=w.y0; y<=w.y1; y++) X switch (nchan) { X case 1: X pic_read_row(p, y, w.x0, dx, buf); X pic_write_row(q, y, w.x0, dx, buf); X break; X case 3: X case 4: X pic_read_row_rgba(p, y, w.x0, dx, buf4); X pic_write_row_rgba(q, y, w.x0, dx, buf4); X break; X } X if (nchan==1) free(buf); else free(buf4); X} X Xvoid pic_set_window(p, win) XPic *p; XWindow *win; X{ X pic_set_box(p, win->x0, win->y0, win->x1-win->x0+1, win->y1-win->y0+1); X} X Xvoid pic_write_block(p, x0, y0, nx, ny, buf) XPic *p; Xint x0, y0, nx, ny; XPixel1 *buf; X{ X int y; X X for (y=0; yx0, &win->y0, &dx, &dy); X win->x1 = win->x0+dx-1; X win->y1 = win->y0+dy-1; X return win; X} X Xvoid pic_read_block(p, x0, y0, nx, ny, buf) XPic *p; Xint x0, y0, nx, ny; XPixel1 *buf; X{ X int y; X X for (y=0; ylibpic/pic_all.c Xstatic char rcsid[] = "$Header: pic_all.c,v 2.2 88/12/23 20:59:02 ph Locked $"; X#include X Xextern Pic X pic_dump, pic_iris; X X/* X * A pic_list for those programs that want everything. X * If the application doesn't define space for pic_list then the X * linker will grab this. X */ X XPic *pic_list[PIC_LISTMAX] = { X &pic_dump, &pic_iris, X0}; EOF13124 echo extracting libpic/pic_file.c sed 's/^X//' <<'EOF13125' >libpic/pic_file.c Xstatic char rcsid[] = "$Header: pic_file.c,v 1.2 88/12/23 20:59:00 ph Locked $"; X X#include X#include X#include X X#include X#include "pic.h" X Xtypedef enum {DUNNO, SHORT, LONG} Magic_type; Xtypedef enum {NA, LITTLE_ENDIAN, BIG_ENDIAN} Magic_byteorder; X X#ifdef vax X# define MACHINE_BYTEORDER LITTLE_ENDIAN X#else X# define MACHINE_BYTEORDER BIG_ENDIAN X#endif X Xint amg_recog(), dat_recog(), ais_recog(), rad_recog(); X Xtypedef struct { X char *dev; /* device name */ X char *suffix; /* file suffix */ X long magic; /* magic number */ X Magic_type type; /* type of magic number (DUNNO|SHORT|LONG) */ X Magic_byteorder byteorder; /* NA, LITTLE_ENDIAN, or BIG_ENDIAN */ X int (*recogproc)(); /* procedure to recognize, if needed */ X} Dev_info; X Xstatic Dev_info dev[] = { X /* DEV SUFFIX MAGIC# TYPE BYTEORDER RECOGPROC */ X X "dump", "dump", 0x5088, SHORT, BIG_ENDIAN, 0, X "iris", "iris", 0, DUNNO, NA, 0, X}; X#define NDEV (sizeof dev / sizeof dev[0]) X X/* X * pic_file_dev: given file name, try to determine its device type. X * First examine the file (if it exists); X * then try special type-specific recognizers, X * if those fail look at file suffix. X * Returns 0 if unrecognized. X */ X Xchar *pic_file_dev(file) Xchar *file; X{ X char *suffix; X union { X unsigned short s; X long l; X } u, v; X Dev_info *d; X FILE *fp; X struct stat sb; X X /* first try examining the file */ X if ((fp = fopen(file, "r")) != NULL && fstat(fileno(fp), &sb) == 0 && X (sb.st_mode&S_IFMT) == S_IFREG) { X if (fread(&u, sizeof u, 1, fp) != 1) X u.l = 0; /* no magic number */ X fclose(fp); X for (d=dev; dbyteorder != NA) { /* check file's magic number */ X if (d->type == SHORT) { /* short magic number */ X v.s = u.s; X /* if file byte order diff. from machine's then swap: */ X if (d->byteorder != MACHINE_BYTEORDER) X swap_short(&v.s); X if (v.s==d->magic) return d->dev; X } X else { /* long magic number */ X v.l = u.l; X /* if file byte order diff. from machine's then swap: */ X if (d->byteorder != MACHINE_BYTEORDER) X swap_long(&v.l); X if (v.l==d->magic) return d->dev; X } X } X } X } X X /* if magic number didn't identify, try type-specific recognizers: */ X for (d=dev; drecogproc) /* call device's recognition proc */ X if ((*d->recogproc)(file, d)) return d->dev; X X /* if we couldn't recognize by file contents, try file name */ X suffix = strrchr(file, '.'); X if (suffix) suffix++; X else { X suffix = strrchr(file, '/'); X suffix = suffix ? suffix+1 : file; X } X for (d=dev; dsuffix, suffix)) return d->dev; X X /* else failure */ X return 0; X} EOF13125 echo extracting libpic/pixel.h sed 's/^X//' <<'EOF13126' >libpic/pixel.h X/* pixel.h: pixel data types */ X X#ifndef PIXEL_HDR X#define PIXEL_HDR X X/* $Header: pixel.h,v 2.0 88/10/10 13:46:26 ph Locked $ */ X X/* X * we have pixel data types for various channel types and numbers of channels: X * channel types: 1 byte int., 2 byte int., 4 byte int., 4 byte float X * number of channels: 1 (monochrome), 3 (rgb), 4 (rgba) X */ X Xtypedef unsigned char Pixel1; Xtypedef struct {Pixel1 r, g, b;} Pixel1_rgb; Xtypedef struct {Pixel1 r, g, b, a;} Pixel1_rgba; X#define PIXEL1_MIN 0 X#define PIXEL1_MAX 255 X Xtypedef short Pixel2; Xtypedef struct {Pixel2 r, g, b;} Pixel2_rgb; Xtypedef struct {Pixel2 r, g, b, a;} Pixel2_rgba; X#define PIXEL2_MIN -32768 X#define PIXEL2_MAX 32767 X Xtypedef long Pixel4; Xtypedef struct {Pixel4 r, g, b;} Pixel4_rgb; Xtypedef struct {Pixel4 r, g, b, a;} Pixel4_rgba; X Xtypedef float Pixelf; Xtypedef struct {Pixelf r, g, b;} Pixelf_rgb; Xtypedef struct {Pixelf r, g, b, a;} Pixelf_rgba; X X#define PIXEL_UNDEFINED -239 /* to flag undefined vbls in various places */ X X#endif EOF13126 echo extracting libpic/window.c sed 's/^X//' <<'EOF13127' >libpic/window.c X#include X#include "window.h" X Xstatic char rcsid[] = "$Header: window.c,v 2.0 88/10/10 13:46:29 ph Locked $"; X Xwindow_set(x0, y0, x1, y1, a) Xint x0, y0, x1, y1; Xregister Window *a; X{ X a->x0 = x0; X a->y0 = y0; X a->x1 = x1; X a->y1 = y1; X} X Xwindow_clip(a, b) /* a=intersect(a,b), return overlap bit */ Xregister Window *a, *b; X{ X int overlap; X X overlap = window_overlap(a, b); X window_intersect(a, b, a); X return overlap; X} X Xwindow_intersect(a, b, c) /* c = intersect(a,b) */ Xregister Window *a, *b, *c; X{ X c->x0 = MAX(a->x0, b->x0); X c->y0 = MAX(a->y0, b->y0); X c->x1 = MIN(a->x1, b->x1); X c->y1 = MIN(a->y1, b->y1); X} X Xwindow_overlap(a, b) Xregister Window *a, *b; X{ X return a->x0<=b->x1 && a->x1>=b->x0 && a->y0<=b->y1 && a->y1>=b->y0; X} X Xwindow_print(str, a) Xchar *str; XWindow *a; X{ X printf("%s{%d,%d,%d,%d}%dx%d", X str, a->x0, a->y0, a->x1, a->y1, a->x1-a->x0+1, a->y1-a->y0+1); X} X X/*----------------------------------------------------------------------*/ X Xwindow_box_intersect(a, b, c) Xregister Window_box *a, *b, *c; X{ X c->x0 = MAX(a->x0, b->x0); X c->y0 = MAX(a->y0, b->y0); X c->x1 = MIN(a->x1, b->x1); X c->y1 = MIN(a->y1, b->y1); X window_box_set_size(c); X} X Xwindow_box_print(str, a) Xchar *str; XWindow_box *a; X{ X printf("%s{%d,%d,%d,%d}%dx%d", X str, a->x0, a->y0, a->x1, a->y1, a->nx, a->ny); X} X Xwindow_box_set_max(a) Xregister Window_box *a; X{ X a->x1 = a->x0+a->nx-1; X a->y1 = a->y0+a->ny-1; X} X Xwindow_box_set_size(a) Xregister Window_box *a; X{ X a->nx = a->x1-a->x0+1; X a->ny = a->y1-a->y0+1; X} EOF13127 echo extracting libpic/window.h sed 's/^X//' <<'EOF13128' >libpic/window.h X#ifndef WINDOW_HDR X#define WINDOW_HDR X X/* $Header: window.h,v 2.0 88/10/10 13:46:30 ph Locked $ */ X Xtypedef struct { /* WINDOW: A DISCRETE 2-D RECTANGLE */ X int x0, y0; /* xmin and ymin */ X int x1, y1; /* xmax and ymax (inclusive) */ X} Window; X Xtypedef struct { /* WINDOW_BOX: A DISCRETE 2-D RECTANGLE */ X int x0, y0; /* xmin and ymin */ X int x1, y1; /* xmax and ymax (inclusive) */ X int nx, ny; /* xsize=x1-x0+1 and ysize=y1-y0+1 */ X} Window_box; X X/* X * note: because of the redundancy in the above structure, nx and ny should X * be recomputed with window_box_set_size() when they cannot be trusted X */ X X/* caution: we exploit positional coincidences in the following: */ X#define window_box_overlap(a, b) \ X window_overlap((Window_box *)(a), (Window_box *)(b)) X X#endif EOF13128 echo extracting libpic/swap.c sed 's/^X//' <<'EOF13129' >libpic/swap.c Xstatic char rcsid[] = "$Header: swap.c,v 1.4 88/10/20 23:21:30 ph Locked $"; X X#include X Xswap_long(p) Xregister char *p; X{ X char t; X X SWAP(p[0], p[3], t); X SWAP(p[1], p[2], t); X} X Xswap_short(p) Xregister char *p; X{ X char t; X X SWAP(p[0], p[1], t); X} EOF13129 echo extracting libpic/iris_pic.c sed 's/^X//' <<'EOF13130' >libpic/iris_pic.c X/* pic_iris: hooking iris package into pic package */ X Xstatic char rcsid[] = "$Header$ "; X X#include "pic.h" X#include "iris.h" X Xstatic Pic_procs pic_iris_procs = { X (char *(*)())iris_open, iris_close, X iris_get_name, X iris_clear, iris_clear_rgba, X X iris_set_nchan, iris_set_box, X iris_write_pixel, iris_write_pixel_rgba, X iris_write_row, iris_write_row_rgba, X X iris_get_nchan, iris_get_box, X iris_read_pixel, iris_read_pixel_rgba, X iris_read_row, iris_read_row_rgba, X}; X XPic pic_iris = {"iris", &pic_iris_procs}; EOF13130 echo extracting libpic/dump_pic.c sed 's/^X//' <<'EOF13131' >libpic/dump_pic.c X/* pic_dump: hooking dump package into pic package */ X Xstatic char rcsid[] = "$Header: pic_dump.c,v 2.1 88/11/01 21:10:02 ph Locked $"; X X#include "pic.h" X#include "dump.h" X Xstatic Pic_procs pic_dump_procs = { X (char *(*)())dump_open, dump_close, X dump_get_name, X dump_clear, dump_clear_rgba, X X dump_set_nchan, dump_set_box, X dump_write_pixel, dump_write_pixel_rgba, X dump_write_row, dump_write_row_rgba, X X dump_get_nchan, dump_get_box, X dump_read_pixel, dump_read_pixel_rgba, X dump_read_row, dump_read_row_rgba, X}; X XPic pic_dump = {"dump", &pic_dump_procs}; EOF13131 echo extracting libsys/simple.h sed 's/^X//' <<'EOF13132' >libsys/simple.h X/* simple.h: definitions of some simple, common constants and macros */ X X#ifndef SIMPLE_HDR X#define SIMPLE_HDR X X/* $Header: simple.h,v 1.6 89/04/26 11:32:51 ph Locked $ */ X X#include X X/* better than standard assert.h: doesn't gag on 'if (p) assert(q); else r;' */ X#ifndef NDEBUG X# define assert(p) if (!(p)) \ X { \ X fprintf(stderr, "Assertion failed: %s line %d: p\n", __FILE__, __LINE__); \ X exit(1); \ X } \ X else X# else X# define assert(p) X#endif X X#define str_eq(a, b) (strcmp(a, b) == 0) X#define MIN(a, b) ((a)<(b) ? (a) : (b)) X#define MAX(a, b) ((a)>(b) ? (a) : (b)) X#define ABS(a) ((a)>=0 ? (a) : -(a)) X#define SWAP(a, b, t) {t = a; a = b; b = t;} X#define LERP(t, a, b) ((a)+(t)*((b)-(a))) X#define ALLOC(ptr, type, n) assert(ptr = (type *)malloc((n)*sizeof(type))) X#define ALLOC_ZERO(ptr, type, n) assert(ptr = (type *)calloc(n, sizeof(type))) X X#define PI 3.14159265358979323846264338 X#define RAD_TO_DEG(x) ((x)*(180./PI)) X#define DEG_TO_RAD(x) ((x)*(PI/180.)) X X/* note: the following are machine dependent! (ifdef them if possible) */ X#define MINSHORT -32768 X#define MINLONG -2147483648 X#define MININT MINLONG X#ifndef MAXINT /* sgi has these in values.h */ X# define MAXSHORT 32767 X# define MAXLONG 2147483647 X# define MAXINT MAXLONG X#endif X X X#ifdef hpux /* hp's unix doesn't have bzero */ X# define bzero(a, n) memset(a, 0, n) X#endif X X#endif EOF13132 echo extracting libsys/Makefile sed 's/^X//' <<'EOF13133' >libsys/Makefile X# Makefile for libsys: miscellaneous systems-ish routines X XDEST = .. XHDR = simple.h X Xinstall: X cp $(HDR) $(DEST)/include X Xclean: EOF13133 exit