]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Initial revision
authorGuido van Rossum <guido@python.org>
Wed, 30 Oct 1991 11:52:48 +0000 (11:52 +0000)
committerGuido van Rossum <guido@python.org>
Wed, 30 Oct 1991 11:52:48 +0000 (11:52 +0000)
13 files changed:
Demo/sgi/video/README [new file with mode: 0644]
Demo/sgi/video/cam.py [new file with mode: 0755]
Demo/sgi/video/camcorder.py [new file with mode: 0755]
Demo/sgi/video/squash.c [new file with mode: 0755]
Demo/sgi/video/squash2.c [new file with mode: 0755]
Demo/sgi/video/statit.py [new file with mode: 0755]
Demo/sgi/video/syncaudio.py [new file with mode: 0755]
Demo/sgi/video/tomono.c [new file with mode: 0755]
Demo/sgi/video/tv.py [new file with mode: 0755]
Demo/sgi/video/v2i.c [new file with mode: 0755]
Demo/sgi/video/video.py [new file with mode: 0755]
Demo/sgi/video/vinfo.py [new file with mode: 0755]
Demo/sgi/video/vtime.py [new file with mode: 0755]

diff --git a/Demo/sgi/video/README b/Demo/sgi/video/README
new file mode 100644 (file)
index 0000000..8b87582
--- /dev/null
@@ -0,0 +1,56 @@
+This directory contains Python and C code we wrote while we had a
+framegrabber board on loan from SGI.
+
+       --Guido and Jack
+
+cam.py         network real-time tv broadcast; see tv.py
+               usage: cam [packfactor [host]]
+               specifying 'all' for host broadcasts
+
+camcorder.py   record video movies or make snapshots (in movie format)
+               usage: camcorder [-c] [-a audiohost [-s]] [moviefile]
+               -c              color (default b/w, packfactor = 2)
+               -a audiohost    syncaudio is running on audiohost
+               -s              start syncaudio (on audiohost)
+               moviefile       (default film.video)
+               keyboard commands:
+               s       stop grabbing (single step if already stopped)
+               c       continuous grabbing
+               r       start recording
+               p       pause recording (record single frame if paused)
+               ESC     quit
+
+statit.py      various statistics operations on movie files
+
+syncaudio.py   record audio synchronized with camcorder -a
+               usage: syncaudio videohost soundfile
+               soundfile format: 16 bits, 16khz, mono
+
+tv.py          receiver for transmissions from cam.py
+
+video.py       player for movies recorded by camcorder.py
+               usage: video [moviefile [soundfile]]
+               default moviefile is film.video
+               default sound is no sound
+
+vinfo.py       print a summary of a movie file
+
+vtime.py       virtual time module imported by syncaudio.py and camcorder.py
+
+
+These are C programs, either for efficiency or because they need to
+link with a C library.
+
+squash.c       make a movie smaller by averaging pixels
+               usage: squash factor [bits] <moviefile >newmoviefile
+               factor          x and y compression factor
+               bits            #bits left per sample in result (default 8)
+
+squash2.c      make a movie smaller by dropping pixels
+               usage: squash2 factor <moviefile >newmoviefile
+               factor          x and y compression factor
+
+tomono.c       like squash2 but outputs a monochrome movie
+
+v2i.c          convert the first image of a movie file to SGI .rgb format
+               link with -limage
diff --git a/Demo/sgi/video/cam.py b/Demo/sgi/video/cam.py
new file mode 100755 (executable)
index 0000000..f30e1e0
--- /dev/null
@@ -0,0 +1,129 @@
+import sys
+from socket import *
+from gl import *
+from GL import *
+from DEVICE import *
+from time import millitimer
+
+HS = 40 # Header size (must be same as in tv.py)
+
+# Rely on UDP packet (de)fragmentation for smoother images
+# (Changed for broadcast)
+MAX = 16000
+
+PF = 2 # Default packfactor
+
+# Default receiver station is voorn.
+# Kwik has no yellow pages, so...
+HOST = '192.16.201.121'
+PORT = 5555
+
+if sys.argv[1:]:
+       PF = eval(sys.argv[1])
+
+if sys.argv[2:]:
+       HOST = sys.argv[2]
+       if HOST = 'all':
+               HOST = '<broadcast>'
+               MAX = 1400
+
+PF2 = PF*PF
+
+def main():
+       centerx, centery = 400, 300
+
+       foreground()
+       wid = winopen('cam')
+       RGBmode()
+       doublebuffer()
+       gconfig()
+       qdevice(ESCKEY)
+
+       w, h = getsize()
+       ortho2(0, w, 0, h)
+       w = w/PF*PF
+       h = h/PF*PF
+
+       readsource(SRC_FRAMEGRABBER)
+
+       s = socket(AF_INET, SOCK_DGRAM)
+       if HOST = '<broadcast>':
+               s.allowbroadcast(1)
+       addr = HOST, PORT
+
+       bytesperline = w/PF2
+       linesperchunk = MAX/bytesperline
+       linesperchunk = linesperchunk/PF*PF
+       nchunks = (h+linesperchunk-1)/linesperchunk
+
+       print 'MAX=', MAX,
+       print 'linesperchunk=', linesperchunk,
+       print 'nchunks=', nchunks,
+       print 'w=', w, 'h=', h
+
+       x1, x2 = 0, w-1
+
+       t1 = millitimer()
+       nframes = 0
+       fps = 0
+
+       msg = ''
+
+       while 1:
+               while qtest():
+                       dev, val = qread()
+                       if dev = REDRAW:
+                               reshapeviewport()
+                               w, h = getsize()
+                               ortho2(0, w, 0, h)
+                               w = w/PF*PF
+                               h = h/PF*PF
+
+                               bytesperline = w/PF2
+                               linesperchunk = MAX/bytesperline
+                               linesperchunk = linesperchunk/PF*PF
+                               nchunks = (h+linesperchunk-1)/linesperchunk
+
+                               print 'MAX=', MAX,
+                               print 'linesperchunk=', linesperchunk,
+                               print 'nchunks=', nchunks,
+                               print 'w=', w, 'h=', h
+
+                               x1, x2 = 0, w-1
+
+                               fps = 0
+
+                       elif dev = ESCKEY:
+                               winclose(wid)
+                               return
+
+               readsource(SRC_FRAMEGRABBER)
+
+               nframes = nframes+1
+               if nframes >= fps:
+                       t2 = millitimer()
+                       if t2 <> t1:
+                               fps = int(10000.0*nframes/(t2-t1)) * 0.1
+                               msg = `fps` +  ' frames/sec'
+                               t1 = t2
+                               nframes = 0
+
+               RGBcolor(255,255,255)
+               cmov2i(9,9)
+               charstr(msg)
+
+               swapbuffers()
+               rectcopy(centerx-w/2, centery-w/2, centerx+w/2, centery+w/2, 0, 0)
+
+               for i in range(nchunks):
+                       y1 = i*linesperchunk
+                       y2 = y1 + linesperchunk-1
+                       if y2 >= h: y2 = h-1
+                       data = lrectread(x1, y1, x2, y2)
+                       data2 = packrect(x2-x1+1, y2-y1+1, PF, data)
+                       prefix = `w, h, PF, x1, y1, x2, y2`
+                       prefix = prefix + ' ' * (HS-len(prefix))
+                       data3 = prefix + data2
+                       s.sendto(data3, addr)
+
+main()
diff --git a/Demo/sgi/video/camcorder.py b/Demo/sgi/video/camcorder.py
new file mode 100755 (executable)
index 0000000..a6b7f4a
--- /dev/null
@@ -0,0 +1,197 @@
+#!/ufs/guido/bin/sgi/python3.3
+from gl import *
+from GL import *
+from DEVICE import *
+import time
+import sys
+import getopt
+import socket
+import posix
+import vtime
+
+SYNCPORT = 10000
+CTLPORT = 10001
+
+VP_GBXORG = 0x1000001
+VP_GBYORG = 0x1000002
+VP_FBXORG = 0x1000003
+VP_FBYORG = 0x1000004
+VP_WIDTH =  0x1000005
+VP_HEIGHT = 0x1000006
+
+class Struct(): pass
+epoch = Struct()
+
+def getvideosize():
+    w = getvideo(VP_WIDTH)
+    h = getvideo(VP_HEIGHT)
+    print getvideo(VP_GBXORG), getvideo(VP_GBYORG)
+    print getvideo(VP_FBXORG), getvideo(VP_FBYORG)
+    x = 0
+    y = 0
+    return x,y,w,h
+def saveframe(f,x,y,w,h,pf, notime):
+    readsource(SRC_FRONT)
+    if pf:
+       w = w/pf*pf
+       h = h/pf*pf
+    data = None
+    data = lrectread(x,y,x+w-1,y+h-1)
+    if pf: data = packrect(w,h,pf,data)
+    if notime: t = 0
+    else: t = time.millitimer()-epoch.epoch
+    f.write(`t` + ',' + `len(data)` + '\n')
+    f.write(data)
+    readsource(SRC_FRAMEGRABBER)
+def drawframe(x,y,w,h,col):
+    drawmode(OVERDRAW)
+    color(col)
+    bgnline()
+    v2i(x-1,y-1) ; v2i(x+w,y-1); v2i(x+w,y+h); v2i(x-1,y+h); v2i(x-1,y-1)
+    endline()
+    drawmode(NORMALDRAW)
+def main():
+    foreground()
+    pf = 2
+    ausync = 0
+    austart = 0
+    optlist, args = getopt.getopt(sys.argv[1:],'ca:s')
+    for opt, arg in optlist:
+       if opt = '-c':
+           pf = 0
+       elif opt = '-a':
+           ausync = 1
+           aumachine = arg
+       elif opt = '-s':
+           austart = 1
+       else:
+           print 'Usage: camcorder [-c] [-a audiomachine [-s]]'
+           sys.exit(1)
+    if austart:
+       if not ausync:
+           print 'Cannot use -s without -a'
+           sys.exit(1)
+       print 'Starting audio recorder...'
+       posix.system('rsh '+aumachine+' syncrecord '+socket.gethostname()+' &')
+    if ausync:
+       print 'Syncing to audio recorder...'
+       globtime = vtime.VTime().init(1,aumachine,SYNCPORT)
+       ctl = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+       ctl.bind((socket.gethostname(),CTLPORT))
+       aua = (socket.gethostbyname(aumachine), CTLPORT)
+       print 'Done.'
+    vidx, vidy, w, h = getvideosize()
+    prefsize(w,h)
+    win = winopen('Camcorder')
+    if len(args) > 1:
+        f = open(args, 'w')
+    else:
+        f = open('film.video', 'w')
+    w, h = getsize()
+    realw, realh = w, h
+    doublebuffer()
+    RGBmode()
+    gconfig()
+    qdevice(LEFTMOUSE)
+    qdevice(RKEY)
+    qdevice(SKEY)
+    qdevice(CKEY)
+    qdevice(PKEY)
+    qdevice(ESCKEY)
+    inrunning = 1
+    outrunning = 0
+    stop = 'stop'
+    readsource(SRC_FRAMEGRABBER)
+    mousing = 0
+    epoch.epoch = time.millitimer()
+    stoptime = epoch.epoch
+    sizewritten = 0
+    x, y = realw/4, realh/4
+    w, h = w/2, h/2
+    drawframe(x,y,w,h,1)
+    nframe = 0
+    try:
+       num = 0
+       while 1:
+           insingle = 0
+           outsingle = 0
+           if mousing:
+               drawframe(x,y,w,h,0)
+               ox, oy = getorigin()
+               if sizewritten:
+                   x = getvaluator(MOUSEX)-ox
+                   y = getvaluator(MOUSEY)-oy
+               else:
+                   w = getvaluator(MOUSEX)-x-ox
+                   h = getvaluator(MOUSEY)-y-oy
+               drawframe(x,y,w,h,1)
+           if qtest():
+               ev, val = qread()
+               if ev = LEFTMOUSE and val = 1:
+                   drawframe(x,y,w,h,0)
+                   mousing = 1
+                   ox, oy = getorigin()
+                   x = getvaluator(MOUSEX)-ox
+                   y = getvaluator(MOUSEY)-oy
+               elif ev = LEFTMOUSE and val = 0:
+                   mousing = 0
+                   if not sizewritten:
+                       f.write('CMIF video 1.0\n')
+                       f.write(`w,h,pf` + '\n')
+                       sizewritten = 1
+               if ev = RKEY and val = 1:
+                   if not inrunning:
+                       ringbell()
+                   else:
+                       outrunning = 1
+                       wasstopped = time.millitimer() - stoptime
+                       epoch.epoch = epoch.epoch + wasstopped
+                       nframe = 0
+                       starttime = time.millitimer()
+                       if ausync:
+                           ctl.sendto(`(1,starttime)`, aua)
+               elif ev = PKEY and val = 1 and outrunning:
+                   outrunning = 0
+                   stoptime = time.millitimer()
+                   if ausync:
+                       ctl.sendto(`(0,stoptime)`, aua)
+                   nf =  nframe * 1000.0 / (time.millitimer()-starttime)
+                   drawmode(OVERDRAW)
+                   color(0)
+                   clear()
+                   color(1)
+                   cmov2i(5,5)
+                   charstr('Recorded ' + `nf` + ' frames/sec')
+                   drawmode(NORMALDRAW)
+               elif ev = PKEY and val = 1 and not outrunning:
+                       outsingle = 1
+               elif ev = CKEY and val = 1:
+                       inrunning = 1
+               elif ev = SKEY and val = 1:
+                       if outrunning:
+                           ringbell()
+                       elif inrunning:
+                           inrunning = 0
+                       else:
+                           insingle = 1
+               elif ev = ESCKEY:
+                   if ausync:
+                       ctl.sendto(`(2,time.millitimer())`, aua)
+                   raise stop
+           if inrunning or insingle:
+               rectcopy(vidx,vidy,realw,realh,0,0)
+               swapbuffers()
+           if outrunning or outsingle:
+               nframe = nframe + 1
+               if not sizewritten:
+                   f.write('CMIF video 1.0\n')
+                   f.write(`w,h,pf` + '\n')
+                   sizewritten = 1
+               saveframe(f, x, y, w, h, pf, outsingle)
+    except stop:
+       pass
+    drawmode(OVERDRAW)
+    color(0)
+    clear()
+#
+main()
diff --git a/Demo/sgi/video/squash.c b/Demo/sgi/video/squash.c
new file mode 100755 (executable)
index 0000000..c045084
--- /dev/null
@@ -0,0 +1,120 @@
+#include <stdio.h>
+
+long *bm;
+long h, w;
+long factor;
+
+#define OC(x,xi) ((x)*factor+(xi))
+#define BM(x,xi,y,yi) bm[OC(y,yi)*w+OC(x,xi)]
+
+#define COMP(r,g,b) ((r) | ((g)<<8) | ((b) << 16))
+
+#define R(comp) ((comp) & 0xff)
+#define G(comp) (((comp)>>8) & 0xff)
+#define B(comp) (((comp)>>16) & 0xff)
+
+main(argc, argv)
+    char **argv;
+{
+    char lbuf[100];
+    int nh, nw;
+    int x, y, xi, yi;
+    int num;
+    int r, g, b;
+    long data;
+    long *nbm, *nbmp;
+    int i;
+    int bits, mask, roundbit, addbit;
+    int pf;
+    int newfmt = 0;
+
+    if( argc != 2 && argc != 3) {
+       fprintf(stderr, "Usage: squash factor [bits]\n");
+       exit(1);
+    }
+    factor = atoi(argv[1]);
+    if ( argc > 2 ) {
+       bits = atoi(argv[2]);
+       mask = (1 << bits) - 1;
+       mask <<= (8-bits);
+       roundbit = 1 << (7-bits);
+       addbit = 1 << (8-bits);
+       fprintf(stderr, "%x %x %x\n", mask, roundbit, addbit);
+    } else {
+       mask = 0xff;
+       roundbit = 0;
+       addbit = 0;
+    }
+    gets(lbuf);
+    if ( strncmp( lbuf, "CMIF", 4) == 0 ) {
+       newfmt = 1;
+       gets(lbuf);
+       if( sscanf(lbuf, "(%d,%d,%d)", &w, &h, &pf) != 3) {
+           fprintf(stderr, "%s: bad size spec: %s\n", argv[0], lbuf);
+           exit(1);
+       }
+       if ( pf != 0 ) {
+           fprintf(stderr, "%s: packed file\n", argv[0]);
+           exit(1);
+       }
+    } else {
+       if ( sscanf(lbuf, "(%d,%d)", &w, &h) != 2) {
+           fprintf(stderr, "%s: bad size spec: %s\n", argv[0], lbuf);
+           exit(1);
+       }
+    }
+    nh = h / factor;
+    nw = w / factor;
+    if ( newfmt )
+       printf("CMIF video 1.0\n(%d,%d,%d)\n", nw, nh, 0);
+    else
+       printf("(%d,%d)\n", nw, nh);
+    if ( (bm = (long *)malloc(h*w*sizeof(long))) == 0) {
+       fprintf(stderr, "%s: No memory\n", argv[0]);
+       exit(1);
+    }
+    if ( (nbm = (long *)malloc(nh*nw*sizeof(long))) == 0) {
+       fprintf(stderr, "%s: No memory\n", argv[0]);
+       exit(1);
+    }
+    while( !feof(stdin) ) {
+       gets(lbuf);
+       if ( feof(stdin) ) break;
+       puts(lbuf);
+       fprintf(stderr, "Reading %d\n", h*w*sizeof(long));
+       if ( (i=fread(bm, 1, h*w*sizeof(long), stdin)) != h*w*sizeof(long)) {
+           fprintf(stderr, "%s: short read, %d wanted %d\n", argv[0],
+               i, h*w*sizeof(long));
+           exit(1);
+       }
+       nbmp = nbm;
+       for( y=0; y<nh; y++) {
+           for ( x=0; x<nw; x++) {
+               r = g = b = 0;
+               num = 0;
+               for( xi=0; xi<factor; xi++ ) {
+                   for(yi=0; yi<factor; yi++) {
+                       if ( y*factor+yi < h && x*factor+xi < w ) {
+                           num++;
+                           data = BM(x,xi,y,yi);
+                           r += R(data);
+                           g += G(data);
+                           b += B(data);
+                       }
+                       else fprintf(stderr, "skip %d %d %d %d\n", x, xi, y, yi);
+                   }
+               }
+               r = r/num; g = g/num; b = b/num;
+               if ( (r & mask) != mask && ( r & roundbit) ) r += addbit;
+               if ( (g & mask) != mask && ( g & roundbit) ) g += addbit;
+               if ( (b & mask) != mask && ( b & roundbit) ) b += addbit;
+               data = COMP(r, g, b);
+               *nbmp++ = data;
+           }
+       }
+       if (nbmp - nbm != nh * nw ) fprintf(stderr, "%d %d\n", nbmp-nbm, nh*nw);
+       fprintf(stderr, "Writing %d\n", (nbmp-nbm)*sizeof(long));
+       fwrite(nbm, 1, (nbmp-nbm)*sizeof(long), stdout);
+    }
+    exit(0);
+}
diff --git a/Demo/sgi/video/squash2.c b/Demo/sgi/video/squash2.c
new file mode 100755 (executable)
index 0000000..c4d03e9
--- /dev/null
@@ -0,0 +1,72 @@
+#include <stdio.h>
+
+long *bm;
+long h, w;
+long factor;
+
+#define OC(x,xi) ((x)*factor+(xi))
+#define BM(x,xi,y,yi) bm[OC(y,yi)*w+OC(x,xi)]
+
+#define COMP(r,g,b) ((r) | ((g)<<8) | ((b) << 16))
+
+#define R(comp) ((comp) & 0xff)
+#define G(comp) (((comp)>>8) & 0xff)
+#define B(comp) (((comp)>>16) & 0xff)
+
+main(argc, argv)
+    char **argv;
+{
+    char lbuf[100];
+    int nh, nw;
+    int x, y, xi, yi;
+    int num;
+    int r, g, b;
+    long data;
+    long *nbm, *nbmp;
+    int i;
+
+    if( argc != 2) {
+       fprintf(stderr, "Usage: squash factor\n");
+       exit(1);
+    }
+    factor = atoi(argv[1]);
+    gets(lbuf);
+    if ( sscanf(lbuf, "(%d,%d)", &w, &h) != 2) {
+       fprintf(stderr, "%s: bad size spec: %s\n", argv[0], lbuf);
+       exit(1);
+    }
+    nh = h / factor;
+    nw = w / factor;
+    printf("(%d,%d)\n", nw, nh);
+    if ( (bm = (long *)malloc(h*w*sizeof(long))) == 0) {
+       fprintf(stderr, "%s: No memory\n", argv[0]);
+       exit(1);
+    }
+    if ( (nbm = (long *)malloc(nh*nw*sizeof(long))) == 0) {
+       fprintf(stderr, "%s: No memory\n", argv[0]);
+       exit(1);
+    }
+    while( !feof(stdin) ) {
+       gets(lbuf);
+       if ( feof(stdin) ) break;
+       puts(lbuf);
+       fprintf(stderr, "Reading %d\n", h*w*sizeof(long));
+       if ( (i=fread(bm, 1, h*w*sizeof(long), stdin)) != h*w*sizeof(long)) {
+           fprintf(stderr, "%s: short read, %d wanted %d\n", argv[0],
+               i, h*w*sizeof(long));
+           exit(1);
+       }
+       nbmp = nbm;
+       for( y=0; y<nh; y++) {
+           for ( x=0; x<nw; x++) {
+               r = g = b = 0;
+               num = 0;
+               *nbmp++ = BM(x,0,y,0);
+           }
+       }
+       if (nbmp - nbm != nh * nw ) fprintf(stderr, "%d %d\n", nbmp-nbm, nh*nw);
+       fprintf(stderr, "Writing %d\n", (nbmp-nbm)*sizeof(long));
+       fwrite(nbm, 1, (nbmp-nbm)*sizeof(long), stdout);
+    }
+    exit(0);
+}
diff --git a/Demo/sgi/video/statit.py b/Demo/sgi/video/statit.py
new file mode 100755 (executable)
index 0000000..360e49e
--- /dev/null
@@ -0,0 +1,115 @@
+import sys
+from time import millitimer
+
+def main():
+       filename = 'film2.video'
+       if sys.argv[1:]: filename = sys.argv[1]
+       f = open(filename, 'r')
+
+       line = f.readline()
+       w, h = eval(line[:-1])
+       w2, h2 = w/2, h/2
+       size = w2 * h2
+
+       data = data2 = t = t0 = t1 = None
+       nframes = 0
+       t0 = millitimer()
+       while 1:
+               line = f.readline()
+               if not line: break
+               t = eval(line[:-1])
+               data = None
+               data = f.read(size)
+               if len(data) <> size:
+                       raise EOFError
+               dostat(w2, h2, data)
+               nframes = nframes+1
+       t1 = millitimer()
+       
+       t = 0.001 * (t1-t0)
+       fps = 0.1 * int(10*nframes/t)
+       print nframes, 'frames in', t, 'sec. =', fps, 'frames/sec.'
+
+def dostat(w, h, data):
+       print
+       stat3(w, h, data)
+
+# Statistic op 1: frequencies of byte values
+def stat1(w, h, data):
+       bins = [0]*256
+       for c in data:
+               i = ord(c)
+               bins[i] = bins[i]+1
+       prbins(bins)
+
+def prbins(bins):
+       import string
+       s = ''
+       tot = 0
+       for i in range(256):
+               tot = tot + bins[i]
+               s = s + string.rjust(`bins[i]`, 4)
+               if len(s) >= 4*16:
+                       print s, string.rjust(`tot`, 7)
+                       s = ''
+                       tot = 0
+
+# Statistic op 2: run lengths
+def stat2(w, h, data):
+       runs = []
+       for y in range(h):
+               count, value = 0, ord(data[y*w])
+               for c in data[y*w : y*w+w]:
+                       i = ord(c)
+                       if i <> value:
+                               runs.append(count, value)
+                               count, value = 0, i
+                       count = count+1
+               runs.append(count, value)
+       print len(runs), 'runs =', 0.1 * (10*w*h/len(runs)), 'bytes/run'
+
+# Statistic op 3: frequencies of byte differences
+def stat3(w, h, data):
+       bins = [0]*256
+       prev = 0
+       for c in data:
+               i = ord(c)
+               delta = divmod(i-prev, 256)[1]
+               prev = i
+               bins[delta] = bins[delta]+1
+       prbins(bins)
+
+# Try packing
+def packblock(w, h, data):
+       res = ''
+       for y in range(h):
+               res = res + packline(data[y*w : y*w+w])
+       return res
+
+def packline(line):
+       bytes = []
+       for c in line:
+               bytes.append(ord(c))
+       prev = bytes[0]
+       i, n = 1, len(bytes)
+       while i < n:
+               for pack in (0, 2, 4, 8):
+                       if pack = 0:
+                               lo, hi = 0, 0
+                       else:
+                               hi = pow(2, pack-1)-1
+                               lo = -hi-1
+                       p = prev
+                       j = i
+                       count = 0
+                       while j < n:
+                               x = bytes[j]
+                               delta = byte(x-p)
+                               if not lo <= delta <= hi:
+                                       break
+                               p = x
+                               j = j+1
+
+def byte(x): return divmod(x, 256)[1]
+
+main()
diff --git a/Demo/sgi/video/syncaudio.py b/Demo/sgi/video/syncaudio.py
new file mode 100755 (executable)
index 0000000..742a433
--- /dev/null
@@ -0,0 +1,94 @@
+import AL
+import al
+import sys
+import vtime
+import socket
+import time
+
+
+SLEEPTIME = 500                # 500 ms sleeps
+SAMPLEFREQ = 16000     # 16Khz samples
+SAMPLERATE = AL.RATE_16000
+NEEDBUFFERED = SAMPLEFREQ      # Buffer 1 second of sound
+BUFFERSIZE = NEEDBUFFERED*4    # setqueuesize() par for 2 second sound
+
+AVSYNCPORT = 10000     # Port for time syncing
+AVCTLPORT = 10001      # Port for record start/stop
+
+def main():
+    if len(sys.argv) <> 3:
+       print 'Usage: ', sys.argv[0], 'videohostname soundfile'
+       sys.exit(1)
+    #
+    ofile = open(sys.argv[2], 'w')
+    #
+    globaltime = vtime.VTime().init(0,sys.argv[1],AVSYNCPORT)
+    #
+    ctl = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+    ctl.bind((socket.gethostname(),AVCTLPORT))
+    #
+    inp = openmic()
+    #
+    out = 0            # Open aiff file
+    #
+    while 1:
+       if mainloop(None, ctl, inp, out, globaltime):
+           break
+       if mainloop(ofile, ctl, inp, out, globaltime):
+           break
+    pass       # Close aiff file
+    sys.exit(0)
+#
+def openmic():
+    conf = al.newconfig()
+    conf.setqueuesize(BUFFERSIZE)
+    conf.setwidth(AL.SAMPLE_16)
+    conf.setchannels(AL.MONO)
+    return al.openport('micr','r',conf)
+#
+def mainloop(ofile, ctl, inp, out, globaltime):
+    #
+    # Wait for sync packet, keeping 1-2 seconds of sound in the
+    # buffer
+    #
+    totsamps = 0
+    totbytes = 0
+    starttime = time.millitimer()
+    while 1:
+       time.millisleep(SLEEPTIME)
+       if ctl.avail():
+           break
+       nsamples = inp.getfilled()-NEEDBUFFERED
+       if nsamples>0:
+           data = inp.readsamps(nsamples)
+           totsamps = totsamps + nsamples
+           totbytes = totbytes + len(data)
+           if ofile <> None:
+               ofile.write(data)
+    #
+    # Compute his starttime and the timestamp of the first byte in the
+    # buffer. Discard all buffered data upto his starttime
+    #
+    startstop,histime = eval(ctl.recv(100))
+    if (ofile = None and startstop = 0) or \
+                          (ofile <> None and startstop = 1):
+       print 'Sync error: saving=',save,' request=',startstop
+       sys.exit(1)
+    filllevel = inp.getfilled()
+    filltime = time.millitimer()
+    filltime = filltime - filllevel / (SAMPLEFREQ/1000)
+    starttime = globaltime.his2mine(histime)
+    nsamples = starttime - filltime
+    if nsamples < 0:
+       print 'Start/stop signal came too late'
+       sys.exit(1)
+    nsamples = nsamples * (SAMPLEFREQ / 1000)
+    data = inp.readsamps(nsamples)
+    totsamps = totsamps + nsamples
+    totbytes = totbytes + len(data)
+    print 'Time: ', time.millitimer()-starttime, ', Bytes: ', totbytes, ', Samples: ', totsamps
+    if ofile <> None:
+       ofile.write(data)
+    return (startstop = 2)
+
+main()
diff --git a/Demo/sgi/video/tomono.c b/Demo/sgi/video/tomono.c
new file mode 100755 (executable)
index 0000000..546af68
--- /dev/null
@@ -0,0 +1,165 @@
+#include <stdio.h>
+
+long *bm;
+long *nbm;
+long h, w;
+int nh, nw;
+long factor;
+
+#define OC(x,xi) ((x)*factor+(xi))
+#define BM(x,xi,y,yi) bm[OC(y,yi)*w+OC(x,xi)]
+
+#define COMP(r,g,b) ((r) | ((g)<<8) | ((b) << 16))
+
+#define R(comp) ((comp) & 0xff)
+#define G(comp) (((comp)>>8) & 0xff)
+#define B(comp) (((comp)>>16) & 0xff)
+
+#define CHOICEFUNC(np1, np2) ( random() & 1 )
+
+int inlevels = 3*255;
+int outlevels = 1;
+
+main(argc, argv)
+    char **argv;
+{
+    char lbuf[100];
+    int x, y, xi, yi;
+    int num;
+    int r, g, b;
+    long data;
+    int i;
+    double greyness;
+    int inpixels, outpixels;
+    int resid;
+
+    setvbuf(stdout, 0, _IOFBF, 1024*128);
+    if( argc != 2) {
+       fprintf(stderr, "Usage: tomono factor\n");
+       exit(1);
+    }
+    factor = atoi(argv[1]);
+    gets(lbuf);
+    if ( sscanf(lbuf, "(%d,%d)", &w, &h) != 2) {
+       fprintf(stderr, "%s: bad size spec: %s\n", argv[0], lbuf);
+       exit(1);
+    }
+    nh = h / factor;
+    nw = w / factor;
+    printf("(%d,%d)\n", nw, nh);
+    if ( (bm = (long *)malloc(h*w*sizeof(long))) == 0) {
+       fprintf(stderr, "%s: No memory\n", argv[0]);
+       exit(1);
+    }
+    if ( (nbm = (long *)malloc(nh*nw*sizeof(long))) == 0) {
+       fprintf(stderr, "%s: No memory\n", argv[0]);
+       exit(1);
+    }
+    while( !feof(stdin) ) {
+       gets(lbuf);
+       if ( feof(stdin) ) break;
+       puts(lbuf);
+       fprintf(stderr, "Reading %d\n", h*w*sizeof(long));
+       if ( (i=fread(bm, 1, h*w*sizeof(long), stdin)) != h*w*sizeof(long)) {
+           fprintf(stderr, "%s: short read, %d wanted %d\n", argv[0],
+               i, h*w*sizeof(long));
+           exit(1);
+       }
+       /*
+       ** Compute picture blackness.
+       */
+       inpixels = 0;
+       inpixels = countpixels(0,0,w,h);
+       greyness = (double)inpixels/(h*w*inlevels);
+       fprintf(stderr, "%3.1f%% grey\n", 100.0*greyness);
+       outpixels = (int)(greyness*outlevels*nh*nw);
+       fprintf(stderr, "Inpixels: %d (%d) Outpixels %d\n", inpixels, inpixels/inlevels, outpixels);
+       resid = fillpixels(0,0,nw,nh,0,0,w,h,outpixels);
+       if ( resid > 1 ) fprintf(stderr, "Residue: %d pixels\n", resid);
+       fprintf(stderr, "Writing %d\n", (nh*nw)*sizeof(long));
+       fwrite(nbm, 1, (nh*nw)*sizeof(long), stdout);
+    }
+    exit(0);
+}
+
+countpixels(x0,y0,x1,y1)
+{
+    int x, y, tot, data;
+
+    tot = 0;
+    for( y=y0; y<y1; y++)
+       for(x=x0; x<x1; x++) {
+           data = bm[y*w+x];
+           tot += R(data);
+           tot += G(data);
+           tot += B(data);
+    }
+    return tot;
+}
+
+fillpixels(x0,y0,x1,y1,ox0,oy0,ox1,oy1,npixels)
+{
+    int m, om, p1, p2, np1, np2, rp, resid;
+
+    if ( npixels == 0 ) return 0;
+    if ( x0+1 >= x1 && y0+1 >= y1 ) {
+       if ( npixels ) {
+           nbm[y0*nw+x0] = 0xffffff;
+/*         fprintf(stderr, "->%d,%d\n", x0,y0); */
+           return npixels - 1;
+       }
+       return 0;
+    }
+    if ( x1-x0 < y1-y0 ) {
+       if ( y1 - y0 <= 2 )
+           m = y0 + 1;
+       else
+           m = y0+1+(random()%(y1-y0-1));
+/*     fprintf(stderr,"%d,%d %d,%d Y %d\n", x0, x1, y0, y1, m); */
+       /* om = (oy0+oy1)/2; */ om = m;
+       p1 = countpixels(ox0,oy0,ox1,om);
+       p2 = countpixels(ox0,om,ox1,oy1);
+       np1 = (int)(((float)p1/(p1+p2))*npixels);
+       np2 = (int)(((float)p2/(p1+p2))*npixels);
+       rp = npixels - np1 - np2;
+       if ( rp ) {
+           np1 += rp/2;
+           rp = rp - rp/2;
+           np2 += rp;
+       }
+       resid = 0;
+       if ( CHOICEFUNC(np1, np2) ) {
+           resid = fillpixels(x0,y0,x1,m,ox0,oy0,ox1,om,np1+resid);
+           resid = fillpixels(x0,m,x1,y1,ox0,om,ox1,oy1,np2+resid);
+       } else {
+           resid = fillpixels(x0,m,x1,y1,ox0,om,ox1,oy1,np2+resid);
+           resid = fillpixels(x0,y0,x1,m,ox0,oy0,ox1,om,np1+resid);
+       }
+    } else {
+       if ( x1 - x0 <= 2 )
+           m = x0 + 1;
+       else
+           m = x0+1+(random()%(x1-x0-1));
+/*     fprintf(stderr,"%d,%d %d,%d X %d\n", x0, x1, y0, y1, m); */
+       /* om = (ox0+ox1)/2; */ om = m;
+       p1 = countpixels(ox0,oy0,om,oy1);
+       p2 = countpixels(om,oy0,ox1,oy1);
+       np1 = (int)(((float)p1/(p1+p2))*npixels);
+       np2 = (int)(((float)p2/(p1+p2))*npixels);
+       rp = npixels - np1 - np2;
+       if ( rp ) {
+           np1 += rp/2;
+           rp = rp - rp/2;
+           np2 += rp;
+       }
+       resid = 0;
+       if ( CHOICEFUNC(np1, np2) ) {
+           resid = fillpixels(x0,y0,m,y1,ox0,oy0,om,oy1,np1+resid);
+           resid = fillpixels(m,y0,x1,y1,om,oy0,ox1,oy1,np2+resid);
+       } else {
+           resid = fillpixels(m,y0,x1,y1,om,oy0,ox1,oy1,np2+resid);
+           resid = fillpixels(x0,y0,m,y1,ox0,oy0,om,oy1,np1+resid);
+       }
+    }
+    return resid;
+}
diff --git a/Demo/sgi/video/tv.py b/Demo/sgi/video/tv.py
new file mode 100755 (executable)
index 0000000..621740c
--- /dev/null
@@ -0,0 +1,79 @@
+import string
+
+from socket import *
+from gl import *
+from GL import *
+from DEVICE import *
+from time import millisleep, millitimer
+
+PORT = 5555
+
+PF = 2 # packfactor
+HS = 40 # Header size
+
+def testimage():
+       RGBcolor(0, 0, 0)
+       clear()
+       RGBcolor(0, 255, 0)
+       cmov2i(10, 10)
+       charstr('Waiting...')
+
+def reshape():
+       reshapeviewport()
+       w, h = getsize()
+       ortho2(0, w, 0, h)
+       testimage()
+       return w, h
+
+def main():
+       s = socket(AF_INET, SOCK_DGRAM)
+       s.bind('', PORT)
+
+       foreground()
+       wid = winopen('tv')
+       RGBmode()
+       gconfig()
+       qdevice(ESCKEY)
+
+       oldw, oldh = getsize()
+       ortho2(0, oldw, 0, oldh)
+       testimage()
+
+       t1 = millitimer()
+
+       while 1:
+               if qtest():
+                       dev, val = qread()
+                       if dev = ESCKEY:
+                               winclose(wid)
+                               return
+                       elif dev = REDRAW:
+                               oldw, oldh = reshape()
+               elif s.avail():
+                       data = s.recv(17000)
+                       header = string.strip(data[:HS])
+                       w, h, pf, x1, y1, x2, y2 = eval(header)
+                       if (w, h) <> (oldw, oldh):
+                               x, y = getorigin()
+                               x, y = x-1, y+21 # TWM correction
+                               winposition(x, x+w-1, y+oldh-h, y+oldh-1)
+                               oldw, oldh = reshape()
+                       data2 = data[HS:]
+                       dx = (x2-x1+1)/pf
+                       dy = (y2-y1+1)/pf
+                       data3 = unpackrect(dx, dy, 1, data2)
+                       rectzoom(pf, pf)
+                       lrectwrite(x1, y1, x1+dx-1, y1+dy-1, data3)
+                       t1 = millitimer()
+               else:
+                       t2 = millitimer()
+                       if t2-t1 >= 5000:
+                               testimage()
+                               t1 = t2
+                       else:
+                               millisleep(10)
+
+       winclose(wid)
+       return data
+
+main()
diff --git a/Demo/sgi/video/v2i.c b/Demo/sgi/video/v2i.c
new file mode 100755 (executable)
index 0000000..41589d4
--- /dev/null
@@ -0,0 +1,63 @@
+#include <stdio.h>
+#include <gl/image.h>
+
+long bm[1280];
+short rb[1280], gb[1280], bb[1280];
+long h, w;
+
+#define R(comp) ((comp) & 0xff)
+#define G(comp) (((comp)>>8) & 0xff)
+#define B(comp) (((comp)>>16) & 0xff)
+
+main(argc, argv)
+    char **argv;
+{
+    char lbuf[100];
+    int x, y;
+    int i;
+    IMAGE * of;
+    int pmask;
+
+    if( argc != 3 && argc != 4) {
+       fprintf(stderr, "Usage: v2i videofile imgfile [planemask]\n");
+       exit(1);
+    }
+    if ( argc == 4)
+       pmask = atoi(argv[3]);
+    else
+       pmask = 7;
+    if ( freopen(argv[1], "r", stdin) == NULL ) {
+       perror(argv[1]);
+       exit(1);
+    }
+    gets(lbuf);
+    if ( sscanf(lbuf, "(%d,%d)", &w, &h) != 2) {
+       fprintf(stderr, "%s: bad size spec: %s\n", argv[0], lbuf);
+       exit(1);
+    }
+    gets(lbuf);                /* Skip time info */
+    if ( w > 1280 ) {
+       fprintf(stderr, "%s: Sorry, too wide\n", argv[0]);
+       exit(1);
+    }
+    if ( (of=iopen(argv[2], "w", RLE(1), 3, w, h, 3)) == 0) {
+       perror(argv[2]);
+       exit(1);
+    }
+    for( y=0; y<h; y++) {
+       if( fread(bm, sizeof(long), w, stdin) != w) {
+           fprintf(stderr, "%s: short read\n", argv[0]);
+           exit(1);
+       }
+       for( x=0; x<w; x++) {
+           if ( pmask & 1) rb[x] = R(bm[x]);
+           if ( pmask & 2) gb[x] = G(bm[x]);
+           if ( pmask & 4) bb[x] = B(bm[x]);
+       }
+       putrow(of, rb, y, 0);
+       putrow(of, gb, y, 1);
+       putrow(of, bb, y, 2);
+    }
+    iclose(of);
+    exit(0);
+}
diff --git a/Demo/sgi/video/video.py b/Demo/sgi/video/video.py
new file mode 100755 (executable)
index 0000000..05c6794
--- /dev/null
@@ -0,0 +1,112 @@
+from gl import *
+from GL import *
+from DEVICE import *
+import time
+import sys
+import al
+import AL
+
+BUFFERSIZE = 32000
+
+class Struct(): pass
+epoch = Struct()
+EndOfFile = 'End of file'
+bye = 'bye'
+
+def openspkr():
+    conf = al.newconfig()
+    conf.setqueuesize(BUFFERSIZE)
+    conf.setwidth(AL.SAMPLE_16)
+    conf.setchannels(AL.MONO)
+    return al.openport('spkr','w',conf)
+def openvideo(name):
+    f = open(name, 'r')
+    line = f.readline()
+    if not line: raise EndOfFile
+    if line[:4] = 'CMIF': line = f.readline()
+    x = eval(line[:-1])
+    if len(x) = 3: w, h, pf = x
+    else: w, h = x; pf = 2
+    return f, w, h, pf
+def loadframe(f,w,h,pf,af,spkr):
+    line = f.readline()
+    if line = '':
+       raise EndOfFile
+    x = eval(line[:-1])
+    if type(x) = type(0) or type(x) = type(0.0):
+       tijd = x
+       if pf = 0:
+               size = w*h*4
+       else:
+               size = (w/pf) * (h/pf)
+    else:
+       tijd, size = x
+    data = f.read(size)
+    if len(data) <> size:
+       raise EndOfFile
+    if pf:
+       rectzoom(pf, pf)
+       w = w/pf
+       h = h/pf
+       data = unpackrect(w, h, 1, data)
+    lrectwrite(0,0,w-1,h-1,data)
+    # This is ugly here, but the only way to get the two
+    # channels started in sync
+    #if af <> None:
+    #  playsound(af,spkr)
+    ct = time.millitimer() - epoch.epoch
+    if tijd > 0 and ct < tijd:
+       time.millisleep(tijd-ct)
+    swapbuffers()
+    return tijd
+def playsound(af, spkr):
+    nsamp = spkr.getfillable()
+    data = af.read(nsamp*2)
+    spkr.writesamps(data)
+def main():
+    if len(sys.argv) > 1:
+       f, w, h, pf = openvideo(sys.argv[1])
+    else:
+       f, w, h, pf = openvideo('film.video')
+    af = None
+    spkr = None
+    if len(sys.argv) > 2:
+       af = open(sys.argv[2], 'r')
+       spkr = openspkr()
+    if len(sys.argv) > 3:
+       data = af.read(eval(sys.argv[3]))
+       del data
+    foreground()
+    prefsize(w,h)
+    win = winopen('Video player')
+    RGBmode()
+    doublebuffer()
+    gconfig()
+    qdevice(ESCKEY)
+    running = 1
+    epoch.epoch = time.millitimer()
+    nframe = 0
+    tijd = 1
+    try:
+       while 1:
+           if running:
+               try:
+                   tijd = loadframe(f, w, h, pf, af, spkr)
+                   nframe = nframe + 1
+               except EndOfFile:
+                   running = 0
+                   t = time.millitimer()
+                   if tijd > 0:
+                           print 'Recorded at ', nframe * 1000.0 / tijd,
+                           print 'frames/second (', tijd, 'ms total)'
+                   print 'Played at', nframe * 1000.0 / (t-epoch.epoch),
+                   print 'frames/second'
+           if af <> None:
+               playsound(af,spkr)
+           if qtest():
+               if qread() = (ESCKEY,1):
+                   raise bye
+    except bye:
+       pass
+
+main()
diff --git a/Demo/sgi/video/vinfo.py b/Demo/sgi/video/vinfo.py
new file mode 100755 (executable)
index 0000000..98b29fa
--- /dev/null
@@ -0,0 +1,55 @@
+#!/ufs/guido/bin/sgi/python3.3
+from gl import *
+from GL import *
+from DEVICE import *
+import time
+import sys
+
+class Struct(): pass
+epoch = Struct()
+EndOfFile = 'End of file'
+bye = 'bye'
+
+def openvideo(name):
+    f = open(name, 'r')
+    w, h = eval(f.readline()[:-1])
+    return f, w, h
+def loadframe(f, w, h):
+    tijd = f.readline()
+    if tijd = '':
+       raise EndOfFile
+    tijd = eval(tijd[:-1])
+    f.seek(w*h*4,1)
+    return tijd
+def saveframe(name, w, h, tijd, data):
+    f = open(name, 'w')
+    f.write(`w,h` + '\n')
+    f.write(`tijd` + '\n')
+    f.write(data)
+    f.close()
+def main():
+       if len(sys.argv) > 1:
+               names = sys.argv[1:]
+       else:
+               names = ['film.video']
+       for name in names:
+           f, w, h = openvideo(name)
+           print name+': '+`w`+'x'+`h`
+           num = 0
+           try:
+               while 1:
+                   try:
+                       tijd = loadframe(f, w, h)
+                       print '\t', tijd,
+                       num = num + 1
+                       if num % 8 = 0:
+                               print
+                   except EndOfFile:
+                       raise bye
+           except bye:
+               pass
+           if num % 8 <> 0:
+               print
+           f.close()
+
+main()
diff --git a/Demo/sgi/video/vtime.py b/Demo/sgi/video/vtime.py
new file mode 100755 (executable)
index 0000000..00d821e
--- /dev/null
@@ -0,0 +1,106 @@
+#
+# Module vtime - Keep virtual time between two nodes.
+#
+# We try for synchronised clocks by sending a packet of the for
+# (1,mytime,0) to the other side, and waiting (at most) a second for
+# a reply. This reply has the form (2,mytime,histime), and we can
+# estimate the time difference by defining histime to be exactly half-way
+# between the time we sent our message and got our reply. We send a
+# final (3,mynewtime,histime) message to allow the other side to do the
+# same computations.
+#
+# Note that the protocol suffers heavily from the 2-army problem.
+# It'll have to do until I can read up on time-sync protocols, though.
+#
+from socket import *
+import time
+
+MSGSIZE = 100
+MSGTIMEOUT = 1000
+
+recv_timeout = 'receive timeout'
+bad_connect = 'Bad connection'
+
+def timeavg(a,b):
+    return int((long(a)+b)/2L)
+def tryrecv(s):
+    cnt = 0
+    while 1:
+       if s.avail():
+           return s.recvfrom(MSGSIZE)
+       time.millisleep(100)
+       cnt = cnt + 100
+       if cnt > MSGTIMEOUT:
+           raise recv_timeout
+
+class VTime():
+    def init(self,(client,host,port)):
+       s = socket(AF_INET, SOCK_DGRAM)
+       host = gethostbyname(host)
+       localhost = gethostbyname(gethostname())
+       raddr = (host,port)
+       s.bind((localhost,port))
+       if client:
+           #
+           # We loop here because we want the *second* measurement
+           # for accuracy
+           for loopct in (0,2):
+               curtijd = time.millitimer()
+               check = `(loopct,curtijd,0)`
+               s.sendto(check,raddr)
+               while 1:
+                   try:
+                       if loopct:
+                           data, other = s.recvfrom(MSGSIZE)
+                       else:
+                           data, other = tryrecv(s)
+                       newtijd = time.millitimer()
+                       if other <> raddr:
+                           print 'Someone else syncing to us: ', other
+                           raise bad_connect
+                       data = eval(data)
+                       if data[:2] = (loopct+1,curtijd):
+                           break
+                       if data[0] <> 2:
+                           print 'Illegal sync reply: ', data
+                           raise bad_connect
+                   except recv_timeout:
+                       curtijd = time.millitimer()
+                       check = `(loopct,curtijd,0)`
+                       s.sendto(check,raddr)
+           histime = data[2]
+           s.sendto(`(4,newtijd,histime)`,raddr)
+           mytime = timeavg(curtijd,newtijd)
+           #mytime = curtijd
+           self.timediff = histime - mytime
+       else:
+           while 1:
+               data,other = s.recvfrom(MSGSIZE)
+               if other <> raddr:
+                   print 'Someone else syncing to us: ', other, ' Wanted ', raddr
+                   raise bad_connect
+               data = eval(data)
+               if data[0] in (0,2):
+                   curtijd = time.millitimer()
+                   s.sendto(`(data[0]+1,data[1],curtijd)`,raddr)
+               elif data[0] = 4:
+                   newtijd = time.millitimer()
+                   histime = data[1]
+                   mytime = timeavg(curtijd,newtijd)
+                   #mytime = curtijd
+                   self.timediff = histime-mytime
+                   break
+               else:
+                   print 'Funny data: ', data
+                   raise bad_connect
+       return self
+       #
+    def his2mine(self,tijd):
+       return tijd - self.timediff
+    #
+    def mine2his(self, tijd):
+       return tijd + self.timediff
+
+def test(clt, host, port):
+    xx = VTime().init(clt,host,port)
+    print 'Time diff: ', xx.his2mine(0)