summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1992-09-29 13:40:47 (GMT)
committerGuido van Rossum <guido@python.org>1992-09-29 13:40:47 (GMT)
commit9e3f335bea3a57481e935d0ec015b4f395b1bc9b (patch)
tree6bc375de1b2bc517d405a067efe64c56c4655a54
parent3165fe6a56c07f4f85f4ea54b69f5b1f243e2463 (diff)
downloadcpython-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/README16
-rwxr-xr-xDemo/sgi/video/VFile.py59
-rwxr-xr-xDemo/sgi/video/Vinfo.py64
-rwxr-xr-xDemo/sgi/video/Vmkjpeg.py92
-rwxr-xr-xDemo/sgi/video/Vtime.py4
-rwxr-xr-xDemo/sgi/video/Vunjpeg.py97
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()