don@CS.UMD.EDU (Don Hopkins) (05/30/90)
This is a program that uses a shared memory canvas in the X11/NeWS server to quickly animate a sequence of raster images on the screen. The input file should contain a sequence of raw 8 bit images, no headers, no colormaps, just the the uncompressed pixel values. It read the images from the input file into shared memory, and tells the NeWS server to "imagecanvas" each frame on the screen, then waits for it to finish, plus a specified delay, before reading and displaying the next frame. I don't know how it'll deal with the strange framebuffer colormap situation in OpenWindows 2.0. It should work slowly in monochrome because "imagecanvas" has to dither the images, but it should be easy to modify it to animate 1 bit deep images. -Don --- DELETE EVERYTHING ABOVE & INCLUDING THIS LINE, AND RUN THROUGH SH --- : Run this shell script with "sh" not "csh" PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH export PATH all=false if [ x$1 = x-a ]; then all=true fi echo Extracting Makefile sed 's/^X//' <<'//go.sysin dd *' >Makefile XCFLAGS = -O4 X#CFLAGS = -g XNEWSHOME = /usr/NeWS XLIBCPS = ${NEWSHOME}/lib/libcps.a X Xmapper: mapper.o X cc ${CFLAGS} mapper.o ${LIBCPS} -o mapper X Xmapper.o: mapper.c mapper.h X cc ${CFLAGS} -I${NEWSHOME}/include -c mapper.c X Xmapper.h: mapper.cps X cps mapper.cps X Xclean: X rm -f mapper mapper.o mapper.h *.BAK *~ core //go.sysin dd * if [ `wc -c < Makefile` != 311 ]; then made=false echo error transmitting Makefile -- echo length should be 311, not `wc -c < Makefile` else made=true fi if $made; then chmod 644 Makefile echo -n ' '; ls -ld Makefile fi echo Extracting mapper.c sed 's/^X//' <<'//go.sysin dd *' >mapper.c X/* X * mapper.c X * Copyright (C) 1990 by Don Hopkins X * X * SunOS 4.0 memory mapping client for X11/NeWS X * X * mapper InputFile SharedFile Width Height USleep SkipBytes X */ X X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/file.h> X#include <sys/mman.h> X#include <sys/vadvise.h> X#include <stdio.h> X#include "mapper.h" X Xchar *InputFile; Xchar *SharedFile; Xint X, Y, Width, Height; Xint USleep; Xint SkipBytes; Xint ImageBytes; Xint RowBytes; Xint Input; Xchar *Image; Xchar *Padding; X Xchar *mmap_sharedfile(); Xint unmap_sharedfile(); X Xmain (argc, argv) Xint argc; Xchar *argv[]; X{ X if (argc != 9) { X fprintf(stderr, X "usage: mapper InputFile SharedFile X Y Width Height USleep SkipBytes\n"); X exit(1); X } X X InputFile = argv[1]; X SharedFile = argv[2]; X X = atoi(argv[3]); X Y = atoi(argv[4]); X Width = atoi(argv[5]); X Height = atoi(argv[6]); X USleep = atoi(argv[7]); X SkipBytes = atoi(argv[8]); X X ImageBytes = Width * Height; X X if (strcmp(InputFile, "-") == 0) { X Input = fileno(stdin); X } else if ((Input = open(InputFile, O_RDONLY, 0)) < 0) { X fprintf(stderr, "Can't open input file %s\n", InputFile); X exit(1); X } X X ps_open_PostScript(); X ps_initialize(SharedFile, Width, Height, &RowBytes); X X if ((Image = mmap_sharedfile(SharedFile, ImageBytes)) == (char *)-1) { X fprintf(stderr, "Can't mmap %d byte file %\n", ImageBytes, SharedFile); X } X X Padding = (char *)malloc(SkipBytes); X X pump(); X} X X/* X * mmap_sharedfile - mmap the given absolute filename for memlen number X * of bytes rounded to page boundary. File will be mapped R/W. X * Caller should check for validity of returned pointer. X */ X Xchar * Xmmap_sharedfile(absfn, memlen) X char *absfn; X int memlen; X{ X struct stat statbuf; X char *buf; X register int wtemp, fd; X register int pagesize; X static char ar[] = {0x0}; X X pagesize = getpagesize(); X memlen = pagesize * ((memlen + pagesize - 1) / pagesize); X X if (!(fd = open(absfn, O_RDWR, 0666))) X return((char *)-1); X /* check out the filesize, extend if needed */ X if (stat(absfn, &statbuf)) X return((char *)-1); X if (statbuf.st_size < memlen) { X wtemp = lseek(fd, (off_t)(memlen-1), L_SET); X if (wtemp == -1) { X close(fd); X return((char *)-1); X } X if (write(fd, ar, 1) != 1) { X close(fd); X return((char *)-1); X } X } X X /* Map the file pages */ X buf = (char *)mmap((caddr_t)0, memlen, PROT_READ|PROT_WRITE, X MAP_SHARED, fd, (off_t)0); X close(fd); X return(buf); X} X X X/* X * unmap_sharedfile - munmap the given pointer for memlen number of X * bytes rounded to page boundary. Caller should check for return X * value. X */ X Xint Xunmap_sharedfile(buf, memlen) X caddr_t buf; X int memlen; X{ X register int pagesize; X X pagesize = getpagesize(); X memlen = pagesize * ((memlen + pagesize - 1) / pagesize); X X if (msync(buf, memlen, MS_INVALIDATE) < 0) X return(-1); X if (munmap(buf, memlen) < 0) X return(-1); X X return(0); X} X Xpump() X{ X char *p; X int syncin, syncout; X int n; X int dontseek = 0; X X vadvise(VA_SEQL); X X while (1) { X if (!dontseek && X (lseek(Input, (off_t)SkipBytes, L_INCR) < 0)) { X fprintf(stderr, "Seek failed -- trying to read instead!\n"); X dontseek = 1; X } X if (dontseek && X ((n = read(Input, Padding, SkipBytes)) != SkipBytes)) { X fprintf(stderr, "Read %d/%d skip bytes -- exiting!\n", n, SkipBytes); X break; X } X X if ((n = read(Input, Image, ImageBytes)) == ImageBytes) { X ps_splat(X, Y); X ps_sync(syncin,&syncout); X syncin++; X usleep(USleep); X } else { X fprintf(stderr, "Read %d/%d image bytes -- exiting!\n", n, ImageBytes); X break; X } X } X} //go.sysin dd * if [ `wc -c < mapper.c` != 3671 ]; then made=false echo error transmitting mapper.c -- echo length should be 3671, not `wc -c < mapper.c` else made=true fi if $made; then chmod 644 mapper.c echo -n ' '; ls -ld mapper.c fi echo Extracting mapper.cps sed 's/^X//' <<'//go.sysin dd *' >mapper.cps XC: #define ROWBYTES_TAG 1 XC: #define SYNC_TAG 2 X#define ROWBYTES_TAG 1 X#define SYNC_TAG 2 X Xcdef ps_initialize(string SharedFile, Width, Height, LineBytes) X => ROWBYTES_TAG(LineBytes) X X /height Height def X /width Width def X /sharedfile SharedFile def X /canvas X width height 8 [width 0 0 height neg 0 height] null buildimage X def X canvas /RowBytes get ROWBYTES_TAG tagprint typedprint X canvas /SharedFile sharedfile put X Xcdef ps_splat(x, y) X gsave X framebuffer setcanvas X x y translate X width height scale X canvas imagecanvas X grestore X Xcdef ps_sync(In, Out) => SYNC_TAG(Out) X SYNC_TAG tagprint In typedprint //go.sysin dd * if [ `wc -c < mapper.cps` != 634 ]; then made=false echo error transmitting mapper.cps -- echo length should be 634, not `wc -c < mapper.cps` else made=true fi if $made; then chmod 644 mapper.cps echo -n ' '; ls -ld mapper.cps fi