diff options
author | Guido van Rossum <guido@python.org> | 1992-09-29 13:40:47 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1992-09-29 13:40:47 (GMT) |
commit | 9e3f335bea3a57481e935d0ec015b4f395b1bc9b (patch) | |
tree | 6bc375de1b2bc517d405a067efe64c56c4655a54 | |
parent | 3165fe6a56c07f4f85f4ea54b69f5b1f243e2463 (diff) | |
download | cpython-9e3f335bea3a57481e935d0ec015b4f395b1bc9b.zip cpython-9e3f335bea3a57481e935d0ec015b4f395b1bc9b.tar.gz cpython-9e3f335bea3a57481e935d0ec015b4f395b1bc9b.tar.bz2 |
VFile: added new formats 'jpeg' and 'jpeggrey'. Decompression is done
using module 'jpeg' by the Displayer class. (Unfortunately it's too
slow for real time.) Print file size in printinfo() method.
Vinfo: added -t option (terse -- one line per file) and usage message.
Vtime: use BasicV{in,out}File classes -- the minimum needed.
Vmkjpeg, Vunjpeg: new utilities for jpeg (de)compression.
-rw-r--r-- | Demo/sgi/video/README | 16 | ||||
-rwxr-xr-x | Demo/sgi/video/VFile.py | 59 | ||||
-rwxr-xr-x | Demo/sgi/video/Vinfo.py | 64 | ||||
-rwxr-xr-x | Demo/sgi/video/Vmkjpeg.py | 92 | ||||
-rwxr-xr-x | Demo/sgi/video/Vtime.py | 4 | ||||
-rwxr-xr-x | Demo/sgi/video/Vunjpeg.py | 97 |
6 files changed, 299 insertions, 33 deletions
diff --git a/Demo/sgi/video/README b/Demo/sgi/video/README index 5e14cff..071ca9b 100644 --- a/Demo/sgi/video/README +++ b/Demo/sgi/video/README @@ -24,12 +24,13 @@ editor, not in this directory but in /ufs/guido/mm/.) When we got our own Indigo entry-level video board (in June 1992) and a version of the Irix video library that supported capturing PAL format (in August 1992), Sjoerd added an interface to the video -library to Python (sv) and Guido wrote Vrec.py (based upon a -still frame grabber by Sjoerd, in turn based upon SGI demo code in C) -to record a movie using it. Vrec was soon followed by modernized +library to Python (sv) and Guido wrote Vrec.py (based upon a still +frame grabber by Sjoerd, in turn based upon SGI demo code in C) to +record a movie using it. Vrec was soon followed by modernized versions of the other programs (Vinfo, Vplay, Vtime) and an interactive editor (Vedit). Finally, VFile was rewritten for more -modularity, functionality and robustness. +modularity, functionality and robustness, and various other tools were +added as needed. Guido van Rossum Jack Jansen @@ -39,7 +40,8 @@ modularity, functionality and robustness. Overview of files ----------------- -cmif-film.ms description of the CMIF video file format +cmif-film.ms description of the CMIF video file format (a little + out of date) These are programs with a command line interface: @@ -55,6 +57,10 @@ Vtime.py (unrelated to vtime!!!) Copy a video file, manipulating the time codes (e.g. faster/slower, or regenerate time codes, or drop frames too close apart) +Vmkjpeg.py compress an rgb or grey video file to jpeg[grey] format + +Vunjpeg.py expand a jpeg[grey] video file to rgb or grey format + Vedit.py interactive video editing program Vsend.py unicast or multicast live video as UDP packets diff --git a/Demo/sgi/video/VFile.py b/Demo/sgi/video/VFile.py index b65f287..12e087c 100755 --- a/Demo/sgi/video/VFile.py +++ b/Demo/sgi/video/VFile.py @@ -69,6 +69,11 @@ def conv_rgb8(rgb, d1, d2): b = (rgb >> 3) & 0x03 return (r/7.0, g/7.0, b/3.0) +def conv_jpeg(r, g, b): + raise Error, 'Attempt to make RGB colormap (jpeg)' + +conv_jpeggrey = conv_grey + # Choose one of the above based upon a color system name @@ -107,6 +112,11 @@ def inv_rgb8(r, g, b): rgb = ((r&7) << 5) | ((b&3) << 3) | (g&7) return rgb / 255.0, 0, 0 +def inv_jpeg(r, g, b): + raise Error, 'Attempt to invert RGB colormap (jpeg)' + +inv_jpeggrey = inv_grey + # Choose one of the above based upon a color system name @@ -175,6 +185,13 @@ def grab_hls(w, h, pf): def grab_hsv(w, h, pf): raise Error, 'Sorry, grabbing hsv not implemented' +def grab_jpeg(w, h, pf): + # XXX Ought to grab rgb and compress it + raise Error, 'sorry, grabbing jpeg not implemented' + +def grab_jpeggrey(w, h, pf): + raise Error, 'sorry, grabbing jpeggrey not implemented' + # Choose one of the above based upon a color system name @@ -196,7 +213,7 @@ class VideoParams: def init(self): # Essential parameters self.format = 'grey' # color system used - # Choose from: 'rgb', 'rgb8', 'hsv', 'yiq', 'hls' + # Choose from: grey, rgb, rgb8, hsv, yiq, hls, jpeg, jpeggrey self.width = 0 # width of frame self.height = 0 # height of frame self.packfactor = 1 # expansion using rectzoom @@ -286,12 +303,22 @@ class Displayer(VideoParams): (0,0,self.width,self.height)) def showpartframe(self, data, chromdata, (x,y,w,h)): + pf = self.packfactor + if self.format in ('jpeg', 'jpeggrey'): + import jpeg + data, width, height, bytes = jpeg.decompress(data) + if self.format == 'jpeg': + b = 4 + else: + b = 1 + width, height = width*pf, height*pf + if (width, height, bytes) <> (w, h, b): + raise Error, 'jpeg data has wrong size' if not self.colormapinited: self.initcolormap() if self.fixcolor0: gl.mapcolor(self.color0) self.fixcolor0 = 0 - pf = self.packfactor factor = self.magnify if pf: factor = factor * pf if chromdata and not self.skipchrom: @@ -326,7 +353,7 @@ class Displayer(VideoParams): self.colormapinited = 1 self.color0 = None self.fixcolor0 = 0 - if self.format == 'rgb': + if self.format in ('rgb', 'jpeg'): gl.RGBmode() gl.gconfig() gl.RGBcolor(200, 200, 200) # XXX rather light grey @@ -509,11 +536,11 @@ def readfileheader(fp, filename): format, rest = eval(line[:-1]) except: raise Error, filename + ': Bad 3.0 color info' - if format == 'rgb': + if format in ('rgb', 'jpeg'): c0bits = c1bits = c2bits = 0 chrompack = 0 offset = 0 - elif format == 'grey': + elif format in ('grey', 'jpeggrey'): c0bits = rest c1bits = c2bits = 0 chrompack = 0 @@ -606,17 +633,17 @@ def writefileheader(fp, values): # # Write color encoding info # - if format == 'rgb': - data = ('rgb', 0) - elif format == 'grey': - data = ('grey', c0bits) + if format in ('rgb', 'jpeg'): + data = (format, 0) + elif format in ('grey', 'jpeggrey'): + data = (format, c0bits) else: data = (format, (c0bits, c1bits, c2bits, chrompack, offset)) fp.write(`data`+'\n') # # Write frame geometry info # - if format == 'rgb': + if format in ('rgb', 'jpeg'): packfactor = 0 elif packfactor == 0: packfactor = 1 @@ -699,6 +726,7 @@ class BasicVinFile(VideoParams): def printinfo(self): print 'File: ', self.filename + print 'Size: ', getfilesize(self.filename) print 'Version: ', self.version VideoParams.printinfo(self) @@ -765,6 +793,17 @@ class BasicVinFile(VideoParams): self.framecount = self.framecount + 1 +# Subroutine to return a file's size in bytes + +def getfilesize(filename): + import os, stat + try: + st = os.stat(filename) + return st[stat.ST_SIZE] + except os.error: + return 0 + + # Derived class implementing random access and index cached in the file class RandomVinFile(BasicVinFile): diff --git a/Demo/sgi/video/Vinfo.py b/Demo/sgi/video/Vinfo.py index cf89a8d..22eab23 100755 --- a/Demo/sgi/video/Vinfo.py +++ b/Demo/sgi/video/Vinfo.py @@ -20,6 +20,7 @@ import sys sys.path.append('/ufs/guido/src/video') import VFile import getopt +import string # Global options @@ -27,22 +28,34 @@ import getopt short = 0 quick = 0 delta = 0 +terse = 0 +maxwidth = 10 # Main program -- mostly command line parsing def main(): - global short, quick, delta - opts, args = getopt.getopt(sys.argv[1:], 'dqs') + global short, quick, delta, terse, maxwidth + try: + opts, args = getopt.getopt(sys.argv[1:], 'dqst') + except getopt.error, msg: + sys.stdout = sys.stderr + print msg + print 'usage: Vinfo [-d] [-q] [-s] [-t] [file] ...' + sys.exit(2) for opt, arg in opts: if opt == '-q': quick = 1 - elif opt == '-d': + if opt == '-d': delta = 1 - elif opt == '-s': + if opt == '-s': short = 1 + if opt == '-t': + terse = short = 1 if not args: args = ['film.video'] + for filename in args: + maxwidth = max(maxwidth, len(filename)) sts = 0 for filename in args: if process(filename): @@ -65,17 +78,31 @@ def process(filename): sys.stderr.write(filename + ': EOF in video file\n') return 1 - vin.printinfo() + if terse: + print string.ljust(filename, maxwidth), + kbytes = (VFile.getfilesize(filename) + 1023) / 1024 + print string.rjust(`kbytes`, 5) + 'K', + print ' ', string.ljust(`vin.version`, 5), + print string.ljust(vin.format, 8), + print string.rjust(`vin.width`, 4), + print string.rjust(`vin.height`, 4), + sys.stdout.flush() + else: + vin.printinfo() if quick: + if terse: + print vin.close() - return + return 0 try: vin.readcache() - print '[Using cached index]' + if not terse: + print '[Using cached index]' except VFile.Error: - print '[Constructing index on the fly]' + if not terse: + print '[Constructing index on the fly]' if not short: if delta: @@ -107,16 +134,21 @@ def process(filename): if not short: print - print 'Total', n, 'frames in', t*0.001, 'sec.', - if t: print '-- average', int(n*10000.0/t)*0.1, 'frames/sec', - print - print 'Total data', 0.1 * int(datasize / 102.4), 'Kbytes', - if t: - print '-- average', - print 0.1 * int(datasize / 0.1024 / t), 'Kbytes/sec', - print + if terse: + print string.rjust(`n`, 6), + print string.rjust(`int(n*10000.0/t)*0.1`, 5) + else: + print 'Total', n, 'frames in', t*0.001, 'sec.', + if t: print '-- average', int(n*10000.0/t)*0.1, 'frames/sec', + print + print 'Total data', 0.1 * int(datasize / 102.4), 'Kbytes', + if t: + print '-- average', + print 0.1 * int(datasize / 0.1024 / t), 'Kbytes/sec', + print vin.close() + return 0 # Don't forget to call the main program diff --git a/Demo/sgi/video/Vmkjpeg.py b/Demo/sgi/video/Vmkjpeg.py new file mode 100755 index 0000000..19c51d6 --- /dev/null +++ b/Demo/sgi/video/Vmkjpeg.py @@ -0,0 +1,92 @@ +#!/ufs/guido/bin/sgi/python + +# Compress an rgb or grey video file to jpeg format + + +# Usage: +# +# Vmkjpeg [infile [outfile]] + + +# Options: +# +# infile : input file (default film.video) +# outfile : output file (default out.video) + + +import sys +import jpeg +sys.path.append('/ufs/guido/src/video') +import VFile + + +# Main program -- mostly command line parsing + +def main(): + args = sys.argv[1:] + if len(args) < 1: + args.append('film.video') + if len(args) < 2: + args.append('out.video') + if len(args) > 2: + sys.stderr.write('usage: Vmkjpeg [infile [outfile]]\n') + sys.exit(2) + sts = process(args[0], args[1]) + sys.exit(sts) + + +# Copy one file to another + +def process(infilename, outfilename): + try: + vin = VFile.BasicVinFile().init(infilename) + except IOError, msg: + sys.stderr.write(infilename + ': I/O error: ' + `msg` + '\n') + return 1 + except VFile.Error, msg: + sys.stderr.write(msg + '\n') + return 1 + except EOFError: + sys.stderr.write(infilename + ': EOF in video file\n') + return 1 + + try: + vout = VFile.BasicVoutFile().init(outfilename) + except IOError, msg: + sys.stderr.write(outfilename + ': I/O error: ' + `msg` + '\n') + return 1 + + info = vin.getinfo() + if info[0] == 'rgb': + width, height = vin.getsize() + bytes = 4 + format = 'jpeg' + elif info[0] == 'grey': + width, height = vin.getsize() + pf = vin.packfactor + width, height = width / pf, height / pf + bytes = 1 + format = 'jpeggrey' + else: + sys.stderr.write('Vmkjpeg: input not in rgb or grey format\n') + return 1 + info = (format,) + info[1:] + vout.setinfo(info) + vout.writeheader() + n = 0 + try: + while 1: + t, data, cdata = vin.getnextframe() + n = n + 1 + sys.stderr.write('Frame ' + `n` + '...') + data = jpeg.compress(data, width, height, bytes) + vout.writeframe(t, data, None) + sys.stderr.write('\n') + except EOFError: + pass + return 0 + + +# Don't forget to call the main program + +main() diff --git a/Demo/sgi/video/Vtime.py b/Demo/sgi/video/Vtime.py index 3096ce1..321e233 100755 --- a/Demo/sgi/video/Vtime.py +++ b/Demo/sgi/video/Vtime.py @@ -65,7 +65,7 @@ def main(): def process(infilename, outfilename): try: - vin = VFile.VinFile().init(infilename) + vin = VFile.BasicVinFile().init(infilename) except IOError, msg: sys.stderr.write(infilename + ': I/O error: ' + `msg` + '\n') return 1 @@ -77,7 +77,7 @@ def process(infilename, outfilename): return 1 try: - vout = VFile.VoutFile().init(outfilename) + vout = VFile.BasicVoutFile().init(outfilename) except IOError, msg: sys.stderr.write(outfilename + ': I/O error: ' + `msg` + '\n') return 1 diff --git a/Demo/sgi/video/Vunjpeg.py b/Demo/sgi/video/Vunjpeg.py new file mode 100755 index 0000000..c5ce471 --- /dev/null +++ b/Demo/sgi/video/Vunjpeg.py @@ -0,0 +1,97 @@ +#!/ufs/guido/bin/sgi/python + +# Decompress a jpeg or jpeggrey video file to rgb format + + +# Usage: +# +# Vunjpeg [infile [outfile]] + + +# Options: +# +# infile : input file (default film.video) +# outfile : output file (default out.video) + + +import sys +import jpeg +sys.path.append('/ufs/guido/src/video') +import VFile + + +# Main program -- mostly command line parsing + +def main(): + args = sys.argv[1:] + if len(args) < 1: + args.append('film.video') + if len(args) < 2: + args.append('out.video') + if len(args) > 2: + sys.stderr.write('usage: Vunjpeg [infile [outfile]]\n') + sys.exit(2) + sts = process(args[0], args[1]) + sys.exit(sts) + + +# Copy one file to another + +def process(infilename, outfilename): + try: + vin = VFile.BasicVinFile().init(infilename) + except IOError, msg: + sys.stderr.write(infilename + ': I/O error: ' + `msg` + '\n') + return 1 + except VFile.Error, msg: + sys.stderr.write(msg + '\n') + return 1 + except EOFError: + sys.stderr.write(infilename + ': EOF in video file\n') + return 1 + + try: + vout = VFile.BasicVoutFile().init(outfilename) + except IOError, msg: + sys.stderr.write(outfilename + ': I/O error: ' + `msg` + '\n') + return 1 + + info = vin.getinfo() + if info[0] == 'jpeg': + format = 'rgb' + width, height = vin.getsize() + bytes = 4 + elif info[0] == 'jpeggrey': + format = 'grey' + width, height = vin.getsize() + pf = vin.packfactor + width, height = width/pf, height/pf + bytes = 1 + else: + sys.stderr.write('Vunjpeg: input not in jpeg[grey] format\n') + return 1 + info = (format,) + info[1:] + vout.setinfo(info) + vout.writeheader() + sts = 0 + n = 0 + try: + while 1: + t, data, cdata = vin.getnextframe() + n = n + 1 + sys.stderr.write('Frame ' + `n` + '...') + data, w, h, b = jpeg.decompress(data) + if (w, h, b) <> (width, height, bytes): + sys.stderr.write('jpeg data has wrong size\n') + sts = 1 + else: + vout.writeframe(t, data, None) + sys.stderr.write('\n') + except EOFError: + pass + return sts + + +# Don't forget to call the main program + +main() |