]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
VFile: added new formats 'jpeg' and 'jpeggrey'. Decompression is done
authorGuido van Rossum <guido@python.org>
Tue, 29 Sep 1992 13:40:47 +0000 (13:40 +0000)
committerGuido van Rossum <guido@python.org>
Tue, 29 Sep 1992 13:40:47 +0000 (13:40 +0000)
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.

Demo/sgi/video/README
Demo/sgi/video/VFile.py
Demo/sgi/video/Vinfo.py
Demo/sgi/video/Vmkjpeg.py [new file with mode: 0755]
Demo/sgi/video/Vtime.py
Demo/sgi/video/Vunjpeg.py [new file with mode: 0755]

index 5e14cff50aadf31fd95fe4160fdc4fd6e8f1692a..071ca9b4c96c14e6c6ca4f6cd2e5fbfcf8e67c92 100644 (file)
@@ -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
index b65f28771d78331dc1aba36a4b401e4fbd163da9..12e087ca31146f2b9a96c4d966f0d9d1e2fed551 100755 (executable)
@@ -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):
index cf89a8d397dd62e67945acda60f3b9733bd1630e..22eab2325ca741a747b377cd28f059b11bd0dbb1 100755 (executable)
@@ -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 (executable)
index 0000000..19c51d6
--- /dev/null
@@ -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()
index 3096ce1dc771324865f65679d325d4c88cb76726..321e23395887b64d3f517ffdfcd0a4c3150f76b1 100755 (executable)
@@ -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 (executable)
index 0000000..c5ce471
--- /dev/null
@@ -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()