[comp.graphics] source code for filtered image zoom, part 3/3

ph@miro.Berkeley.EDU (Paul Heckbert) (08/11/89)

# 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 <pic.h>
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 <simple.h>
X#include <pic.h>
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; y<dy; y++) {
X	pic_read_row_rgba(a, win.y0+y, win.x0, dx, rgb);
X	for (x=0; x<dx; x++)
X	    lum[x] = .30*rgb[x].r + .59*rgb[x].g + .11*rgb[x].b;
X	pic_write_row(b, win.y0+y, win.x0, dx, lum);
X    }
X    free(rgb);
X    free(lum);
X    pic_close(a);
X    pic_close(b);
X}
X
Xstatic die(control, arg)
Xchar *control, *arg;
X{
X    fprintf(stderr, control, arg);
X    exit(1);
X}
X.Ce
X.SH CREATING A DEVICE LIBRARY
XTo add a new device library to \fIpic\fP for a hypothetical file or device
Xtype called "foo",
Xyou would write the following subroutines:
X.Cs
XFoo	*foo_open(file, mode)
Xvoid	foo_close(d)
X
Xchar	*foo_get_name(d)
Xvoid	foo_clear(d, pv)
Xvoid	foo_clear_rgba(d, r, g, b, a)
X
Xvoid	foo_set_nchan(d, nchan)
Xvoid	foo_set_box(d, ox, oy, dx, dy)
Xvoid	foo_write_pixel(d, x, y, pv)
Xvoid	foo_write_pixel_rgba(d, x, y, r, g, b, a)
Xvoid	foo_write_row(d, y, x0, nx, buf)
Xvoid	foo_write_row_rgba(d, y, x0, nx, buf)
X
Xint	foo_get_nchan(d)
Xvoid	foo_get_box(d, ox, oy, dx, dy)
XPixel1	foo_read_pixel(d, x, y)
Xvoid	foo_read_pixel_rgba(d, x, y, pv)
Xvoid	foo_read_row(d, y, x0, nx, buf)
Xvoid	foo_read_row_rgba(d, y, x0, nx, buf)
X.Ce
Xwhere the arguments are identical to those of the \fIpic\fP subroutines,
Xexcept that the first argument to these routines is a pointer to the private
Xdata for this device,
X.Cs
XFoo *d;
X.Ce
XThis private data is a structure of your own design, containing whatever state
Xinformation is needed to perform the above operations.
XIf an operation is difficult on your device then politely punt, e.g.:
X.Cs
XPixel1 foo_read_pixel(p, x, y) Foo *p; int x, y; {
X    fprintf(stderr, "foo_read_pixel: unimplemented\en");
X}
X.Ce
X.PP
XAfter the above routines are written they need to be registered by
Xcollecting their addresses into a global \fBPic_procs\fP structure
Xand creating a prototype \fBPic\fP structure containing the device's name
Xand \fBPic_procs\fP pointer.
XFor our device class "foo", we'd declare:
X.Cs
Xstatic Pic_procs pic_foo_procs = {
X    (char *(*)())foo_open, foo_close,
X    foo_get_name,
X    foo_clear, foo_clear_rgba,
X    foo_set_nchan, foo_set_box,
X    foo_write_pixel, foo_write_pixel_rgba,
X    foo_write_row, foo_write_row_rgba,
X    foo_get_nchan, foo_get_box,
X    foo_read_pixel, foo_read_pixel_rgba,
X    foo_read_row, foo_read_row_rgba,
X};
X
XPic pic_foo = {"foo", &pic_foo_procs};
X.Ce
XBy convention, the device library for device "foo" goes in a source file
Xcalled \fBfoo.c\fP that does not #include pic.h,
Xand the above global structures go in a small file called \fBfoo_pic.c\fP
Xthat does #include pic.h.
X.PP
XThere are three global files that must be modified slightly to register your
Xnew device with the \fIpic\fP library:
XAdd the address of your prototype \fBPic\fP structure to the list of all
Xknown devices in \fBpic_all.c\fP.
XAdd magic number or recognition code to \fIpic_file_dev\fP in \fBpic_file.c\fP.
XModify \fBMakefile\fP.
XRun \fBmake install\fP.
XFor further examples of this process, see the files
X\fBdump.h\fP, \fBdump.c\fP, \fBdump_pic.c\fP.
X.SH AUTHOR
XPaul Heckbert, UC Berkeley, August 1989.
Xph@miro.berkeley.edu
EOF13117
echo extracting libpic/pic.h
sed 's/^X//' <<'EOF13118' >libpic/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 <pixel.h>
X#include <window.h>
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 <stdio.h>
X#include <pixel.h>
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 <gl.h>
X
X#include <simple.h>
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 <stdio.h>
X#include <pixel.h>
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 <simple.h>
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_npic<PIC_LISTMAX && pic_list[pic_npic]; pic_npic++);
X}
X
XPic *pic_open(file, mode)
Xchar *file, *mode;
X{
X    return pic_open_dev(pic_file_dev(file), file, mode);
X}
X
XPic *pic_open_dev(dev, name, mode)
Xchar *dev, *name, *mode;
X{
X    int i;
X    char *data;
X    Pic *p, *q;
X
X    if (pic_npic<0) pic_init();
X    if (!dev) {			/* probably comes from pic_file_dev */
X	fprintf(stderr, "unknown pic device on %s\n", name);
X	return 0;
X    }
X    for (i=0; i<pic_npic && !str_eq(dev, pic_list[i]->dev); 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; i<pic_npic; i++)
X	printf(" %s", pic_list[i]->dev);
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; y<ny; y++, buf+=nx)
X	pic_write_row(p, y0+y, x0, nx, buf);
X}
X
Xvoid pic_write_block_rgba(p, x0, y0, nx, ny, buf)
XPic *p;
Xint x0, y0, nx, ny;
XPixel1_rgba *buf;
X{
X    int y;
X
X    for (y=0; y<ny; y++, buf+=nx)
X	pic_write_row_rgba(p, y0+y, x0, nx, buf);
X}
X
XWindow *pic_get_window(p, win)
XPic *p;
XWindow *win;
X{
X    int dx, dy;
X
X    if (!win) ALLOC(win, Window, 1);
X    pic_get_box(p, &win->x0, &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; y<ny; y++, buf+=nx)
X	pic_read_row(p, y0+y, x0, nx, buf);
X}
X
Xvoid pic_read_block_rgba(p, x0, y0, nx, ny, buf)
XPic *p;
Xint x0, y0, nx, ny;
XPixel1_rgba *buf;
X{
X    int y;
X
X    for (y=0; y<ny; y++, buf+=nx)
X	pic_read_row_rgba(p, y0+y, x0, nx, buf);
X}
EOF13123
echo extracting libpic/pic_all.c
sed 's/^X//' <<'EOF13124' >libpic/pic_all.c
Xstatic char rcsid[] = "$Header: pic_all.c,v 2.2 88/12/23 20:59:02 ph Locked $";
X#include <pic.h>
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 <string.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#include <simple.h>
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; d<dev+NDEV; d++) {
X		if (d->byteorder != 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; d<dev+NDEV; d++)
X	if (d->recogproc)		/* 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; d<dev+NDEV; d++)
X	if (str_eq(d->suffix, 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 <simple.h>
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 <simple.h>
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 <stdio.h>
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