diff options
author | Guido van Rossum <guido@python.org> | 1992-02-28 15:59:23 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1992-02-28 15:59:23 (GMT) |
commit | 2080b347f4aceea0ed0559c1ec7f809e33f899a9 (patch) | |
tree | e73d5ac8cdece04bf6bba01498974cedd73b32c8 | |
parent | 444db07d3cb58e2161bb1e314eb0a4d8137ff64c (diff) | |
download | cpython-2080b347f4aceea0ed0559c1ec7f809e33f899a9.zip cpython-2080b347f4aceea0ed0559c1ec7f809e33f899a9.tar.gz cpython-2080b347f4aceea0ed0559c1ec7f809e33f899a9.tar.bz2 |
Added class VoutFile.
Added rgb8 support.
Added cache of frame offsets to VinFile.
Misc hacks to grab rgb8 data.
-rwxr-xr-x | Demo/sgi/video/VFile.py | 261 |
1 files changed, 230 insertions, 31 deletions
diff --git a/Demo/sgi/video/VFile.py b/Demo/sgi/video/VFile.py index 6d67543..1711b4b 100755 --- a/Demo/sgi/video/VFile.py +++ b/Demo/sgi/video/VFile.py @@ -9,6 +9,9 @@ import colorsys Error = 'VFile.Error' # Exception +# Missing from GL.py: +DMRGB = 0 + MAXMAP = 4096 - 256 def conv_grey(l,x,y): return colorsys.yiq_to_rgb(l,0,0) @@ -17,6 +20,12 @@ def conv_hls (l,h,s): return colorsys.hls_to_rgb(h,l,s) def conv_hsv (v,h,s): return colorsys.hsv_to_rgb(h,s,v) def conv_rgb (r,g,b): raise Error, 'Attempt to make RGB colormap' +def conv_rgb8(rgb,d1,d2): + rgb = int(rgb*255.0) + r = (rgb >> 5) & 0x07 + g = (rgb ) & 0x07 + b = (rgb >> 3) & 0x03 + return (r/7.0, g/7.0, b/3.0) # Class VinFile represents a video file used for input. # @@ -39,6 +48,7 @@ def conv_rgb (r,g,b): # These writable data members provide additional parametrization: # magnify # xorigin, yorigin +# fallback class VinFile(): @@ -54,6 +64,8 @@ class VinFile(): self.colormapinited = 0 self.magnify = 1.0 self.xorigin = self.yorigin = 0 + self.fallback = 1 + self.skipchrom = 0 self.fp = fp self.filename = filename # @@ -90,7 +102,11 @@ class VinFile(): try: self.format, rest = eval(line[:-1]) if self.format == 'rgb': - pass + self.offset = 0 + self.c0bits = 0 + self.c1bits = 0 + self.c2bits = 0 + self.chrompack = 0 elif self.format == 'grey': self.offset = 0 self.c0bits = rest @@ -121,9 +137,34 @@ class VinFile(): self.packfactor = 2 except: raise Error, self.filename + ': bad (w,h,pf) info' + self.frameno = 0 + self.framecache = [] + self.hascache = 0 # return self + def warmcache(self): + if self.hascache: return + n = 0 + try: + while 1: + void = self.skipnextframe() + n = n + 1 + except EOFError: + pass + if not self.hascache: + raise Error, 'Cannot warm cache' + + + # + # getinfo returns all info pertaining to a film. The returned tuple + # can be passed to VoutFile.setinfo() + # + def getinfo(self): + return (self.format, self.width, self.height, self.packfactor,\ + self.c0bits, self.c1bits, self.c2bits, self.offset, \ + self.chrompack) + # rewind() raises Error if the header is bad (which can only # happen if the file was written to since opened). @@ -131,6 +172,11 @@ class VinFile(): self.fp.seek(0) x = self.initfp(self.fp, self.filename) + def position(self): + if self.frameno >= len(self.framecache): + raise EOFError + self.fp.seek(self.framecache[self.frameno][0]) + # getnextframe() raises EOFError (built-in) if there is no next frame, # or if the next frame is broken. # So to getnextframeheader(), getnextframedata() and skipnextframe(). @@ -141,6 +187,9 @@ class VinFile(): return time, data, chromdata def getnextframedata(self, (size, chromsize)): + if self.hascache: + self.position() + self.frameno = self.frameno + 1 data = self.fp.read(size) if len(data) <> size: raise EOFError if chromsize: @@ -157,6 +206,9 @@ class VinFile(): return time def skipnextframedata(self, (size, chromsize)): + if self.hascache: + self.frameno = self.frameno + 1 + return # Note that this won't raise EOFError for a partial frame. try: self.fp.seek(size + chromsize, 1) # Relative seek @@ -165,8 +217,13 @@ class VinFile(): dummy = self.fp.read(size + chromsize) def getnextframeheader(self): + if self.hascache: + if self.frameno >= len(self.framecache): + raise EOFError + return self.framecache[self.frameno][1] line = self.fp.readline() if not line: + self.hascache = 1 raise EOFError # w, h, pf = self.width, self.height, self.packfactor @@ -191,6 +248,8 @@ class VinFile(): time, size, chromsize = x except: raise Error, self.filename + ': bad frame header' + cdata = (self.fp.tell(), (time, size, chromsize)) + self.framecache.append(cdata) return time, size, chromsize def shownextframe(self): @@ -204,7 +263,7 @@ class VinFile(): self.initcolormap() factor = self.magnify if pf: factor = factor * pf - if chromdata: + if chromdata and not self.skipchrom: cp = self.chrompack cw = (w+cp-1)/cp ch = (h+cp-1)/cp @@ -232,49 +291,188 @@ class VinFile(): return gl.cmode() gl.gconfig() + self.skipchrom = 0 sys.stderr.write('Initializing color map...') - initcmap(self.convcolor, self.c0bits, self.c1bits, \ - self.c2bits, self.chrompack, self.offset) + self.initcmap() sys.stderr.write(' Done.\n') if self.offset == 0: gl.color(0x800) + gl.clear() self.mask = 0x7ff else: self.mask = 0xfff gl.clear() -def initcmap(convcolor, c0bits, c1bits, c2bits, chrompack, offset): - if c0bits+c1bits+c2bits > 11: - raise Error, 'Sorry, 11 bits max' - maxc0 = 1 << c0bits - maxc1 = 1 << c1bits - maxc2 = 1 << c2bits - if offset == 0: - offset = 2048 - for i in range(offset, MAXMAP): - gl.mapcolor(i, 0, 255, 0) - for c0 in range(maxc0): - c0v = c0/float(maxc0-1) - for c1 in range(maxc1): - if maxc1 == 1: - c1v = 0 + def initcmap(self): + maxbits = gl.getgdesc(GL.GD_BITS_NORM_SNG_CMODE) + if maxbits > 11: + maxbits = 11 + c0bits, c1bits, c2bits = self.c0bits, self.c1bits, self.c2bits + if c0bits+c1bits+c2bits > maxbits: + if self.fallback and c0bits < maxbits: + # Cannot display film in this mode, use mono + self.skipchrom = 1 + c1bits = c2bits = 0 + self.convcolor = conv_grey else: - c1v = c1/float(maxc1-1) - for c2 in range(maxc2): - if maxc2 == 1: - c2v = 0 + raise Error, 'Sorry, '+`maxbits`+ \ + ' bits max on this machine' + maxc0 = 1 << c0bits + maxc1 = 1 << c1bits + maxc2 = 1 << c2bits + if self.offset == 0 and maxbits == 11: + offset = 2048 + else: + offset = self.offset + if maxbits <> 11: + offset = offset & ((1<<maxbits)-1) + #for i in range(512, MAXMAP): + # gl.mapcolor(i, 0, 0, 0) + #void = gl.qtest() # Should be gl.gflush() + for c0 in range(maxc0): + c0v = c0/float(maxc0-1) + for c1 in range(maxc1): + if maxc1 == 1: + c1v = 0 else: - c2v = c2/float(maxc2-1) - index = offset + c0 + \ - (c1<<c0bits) + (c2 << (c0bits+c1bits)) - rv, gv, bv = convcolor(c0v, c1v, c2v) - r, g, b = \ - int(rv*255.0), int(gv*255.0), int(bv*255.0) - if index < MAXMAP: - gl.mapcolor(index, r, g, b) + c1v = c1/float(maxc1-1) + for c2 in range(maxc2): + if maxc2 == 1: + c2v = 0 + else: + c2v = c2/float(maxc2-1) + index = offset + c0 + (c1<<c0bits) + \ + (c2 << (c0bits+c1bits)) + rv, gv, bv = self.convcolor( \ + c0v, c1v, c2v) + r, g, b = int(rv*255.0), \ + int(gv*255.0), int(bv*255.0) + if index < MAXMAP: + gl.mapcolor(index, r, g, b) + void = gl.gflush() + +# +# A set of routines to grab images from windows +# +def grab_rgb(w, h, pf): + if gl.getdisplaymode() <> DMRGB: + raise Error, 'Sorry, can only grab rgb in single-buf rgbmode' + if pf <> 1 and pf <> 0: + raise Error, 'Sorry, only grab with packfactor=1' + return gl.lrectread(0, 0, w-1, h-1), None + +def grab_rgb8(w, h, pf): + if gl.getdisplaymode() <> DMRGB: + raise Error, 'Sorry, can only grab rgb in single-buf rgbmode' + if pf <> 1 and pf <> 0: + raise Error, 'Sorry, can only grab with packfactor=1' + r = gl.getgdesc(GL.GD_BITS_NORM_SNG_RED) + g = gl.getgdesc(GL.GD_BITS_NORM_SNG_GREEN) + b = gl.getgdesc(GL.GD_BITS_NORM_SNG_BLUE) + if (r,g,b) <> (3,3,2): + raise Error, 'Sorry, can only grab rgb8 on 8-bit Indigo' + # Dirty Dirty here. Set buffer to cmap mode, grab image and set it back + gl.cmode() + gl.gconfig() + gl.pixmode(GL.PM_SIZE, 8) + data = gl.lrectread(0, 0, w-1, h-1) + data = data[:w*h] # BUG FIX for python lrectread + gl.RGBmode() + gl.gconfig() + gl.pixmode(GL.PM_SIZE, 32) + return data, None + +def grab_grey(w, h, pf): + raise Error, 'Sorry, grabbing grey not implemented' + +def grab_yiq(w, h, pf): + raise Error, 'Sorry, grabbing yiq not implemented' + +def grab_hls(w, h, pf): + raise Error, 'Sorry, grabbing hls not implemented' + +def grab_hsv(w, h, pf): + raise Error, 'Sorry, grabbing hsv not implemented' + +# +# The class VoutFile is not as well-designed (and tested) as VinFile. +# Notably it will accept almost any garbage and write it to the video +# output file +# +class VoutFile(): + def init(self, filename): + if filename == '-': + return self.initfp(sys.stdout, filename) + else: + return self.initfp(open(filename,'w'), filename) + + def initfp(self, fp, filename): + self.fp = fp + self.format = 'grey' + self.width = self.height = 0 + self.packfactor = 1 + self.c0bits = 8 + self.c1bits = self.c2bits = 0 + self.offset = 0 + self.chrompack = 0 + self.headerwritten = 0 + return self + + def close(self): + self.fp.close() + self.initfp(None, None) + + def setinfo(self, values): + self.format, self.width, self.height, self.packfactor,\ + self.c0bits, self.c1bits, self.c2bits, self.offset, \ + self.chrompack = values + + def writeheader(self): + self.headerwritten = 1 + if self.format == 'rgb': + self.packfactor = 0 + elif self.packfactor == 0: + self.packfactor = 1 + self.fp.write('CMIF video 3.0\n') + if self.format == 'rgb': + data = ('rgb', 0) + elif self.format == 'grey': + data = ('grey', 0) + else: + data = (self.format, (self.c0bits, self.c1bits, \ + self.c2bits, self.chrompack, self.offset)) + self.fp.write(`data`+'\n') + data = (self.width, self.height, self.packfactor) + self.fp.write(`data`+'\n') + try: + self._grabber = eval('grab_' + self.format) + except: + raise Error, 'unknown colorsys: ' + self.format + + def writeframeheader(self, data): + if not self.headerwritten: + raise Error, 'Writing frame data before header' + # XXXX Should we sanity check here? + self.fp.write(`data`+'\n') + def writeframedata(self, data, chromdata): + # XXXX Check sizes here + self.fp.write(data) + if chromdata: + self.fp.write(chromdata) + def writeframe(self, time, data, chromdata): + if chromdata: + clen = len(chromdata) + else: + clen = 0 + self.writeframeheader((time, len(data), clen)) + self.writeframedata(data, chromdata) + + def grabframe(self): + return self._grabber(self.width, self.height, self.packfactor) + def test(): import sys, time filename = 'film.video' @@ -303,3 +501,4 @@ def test(): vin.showframe(data, chromdata) print 'Done.' time.sleep(2) + |