Guido van Rossum | f06ee5f | 1996-11-27 19:52:01 +0000 | [diff] [blame] | 1 | #! /usr/bin/env python |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 2 | |
Guido van Rossum | 245be3a | 1993-02-18 18:09:18 +0000 | [diff] [blame] | 3 | # Convert CMIF movie file(s) to a sequence of rgb images |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 4 | |
| 5 | |
| 6 | # Help function |
| 7 | |
| 8 | def help(): |
Guido van Rossum | 245be3a | 1993-02-18 18:09:18 +0000 | [diff] [blame] | 9 | print 'Usage: video2rgb [options] [file] ...' |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 10 | print |
| 11 | print 'Options:' |
| 12 | print '-q : quiet, no informative messages' |
| 13 | print '-m : create monochrome (greyscale) image files' |
Guido van Rossum | 245be3a | 1993-02-18 18:09:18 +0000 | [diff] [blame] | 14 | print '-f prefix : create image files with names "prefix0000.rgb"' |
| 15 | print 'file ... : file(s) to convert; default film.video' |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 16 | |
| 17 | |
| 18 | # Imported modules |
| 19 | |
| 20 | import sys |
Jack Jansen | c82cfc8 | 1993-02-19 10:06:28 +0000 | [diff] [blame] | 21 | sys.path.append('/ufs/jack/src/av/video') # Increase chance of finding VFile |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 22 | import VFile |
| 23 | import time |
| 24 | import getopt |
| 25 | import string |
| 26 | import imgfile |
| 27 | import imgconv |
| 28 | |
| 29 | |
| 30 | # Global options |
| 31 | |
| 32 | quiet = 0 |
| 33 | prefix = 'film' |
| 34 | seqno = 0 |
| 35 | mono = 0 |
| 36 | |
| 37 | |
| 38 | # Main program -- mostly command line parsing |
| 39 | |
| 40 | def main(): |
| 41 | global quiet, prefix, mono |
| 42 | |
| 43 | # Parse command line |
| 44 | try: |
| 45 | opts, args = getopt.getopt(sys.argv[1:], 'qmf:') |
| 46 | except getopt.error, msg: |
| 47 | sys.stdout = sys.stderr |
| 48 | print 'Error:', msg, '\n' |
| 49 | help() |
| 50 | sys.exit(2) |
| 51 | |
| 52 | # Interpret options |
| 53 | try: |
| 54 | for opt, arg in opts: |
| 55 | if opt == '-q': quiet = 1 |
| 56 | if opt == '-f': prefix = arg |
| 57 | if opt == '-m': mono = 1 |
| 58 | except string.atoi_error: |
| 59 | sys.stdout = sys.stderr |
| 60 | print 'Option', opt, 'requires integer argument' |
| 61 | sys.exit(2) |
| 62 | |
| 63 | # Process all files |
| 64 | if not args: args = ['film.video'] |
| 65 | sts = 0 |
| 66 | for filename in args: |
| 67 | sts = (process(filename) or sts) |
| 68 | |
| 69 | # Exit with proper exit status |
| 70 | sys.exit(sts) |
| 71 | |
| 72 | |
| 73 | # Process one movie file |
| 74 | |
| 75 | def process(filename): |
| 76 | try: |
Guido van Rossum | 21a3ff9 | 1993-12-17 15:11:41 +0000 | [diff] [blame] | 77 | vin = VFile.VinFile(filename) |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 78 | except IOError, msg: |
| 79 | sys.stderr.write(filename + ': I/O error: ' + `msg` + '\n') |
| 80 | return 1 |
| 81 | except VFile.Error, msg: |
| 82 | sys.stderr.write(msg + '\n') |
| 83 | return 1 |
| 84 | except EOFError: |
| 85 | sys.stderr.write(filename + ': EOF in video header\n') |
| 86 | return 1 |
| 87 | |
| 88 | if not quiet: |
| 89 | vin.printinfo() |
| 90 | |
| 91 | width, height = int(vin.width), int(vin.height) |
| 92 | |
| 93 | try: |
| 94 | if mono: |
| 95 | cf = imgconv.getconverter(vin.format, 'grey') |
| 96 | else: |
| 97 | cf = imgconv.getconverter(vin.format, 'rgb') |
| 98 | except imgconv.error: |
| 99 | print 'Sorry, no converter available for type',vin.format |
| 100 | return |
| 101 | |
| 102 | if mono: |
| 103 | depth = 1 |
Guido van Rossum | b616ebe | 1993-02-25 00:19:14 +0000 | [diff] [blame] | 104 | bpp = 1 |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 105 | else: |
| 106 | depth = 3 |
Guido van Rossum | b616ebe | 1993-02-25 00:19:14 +0000 | [diff] [blame] | 107 | bpp = 4 |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 108 | |
Guido van Rossum | b616ebe | 1993-02-25 00:19:14 +0000 | [diff] [blame] | 109 | convert(vin, cf, width, height, depth, bpp, vin.packfactor) |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 110 | |
Guido van Rossum | b616ebe | 1993-02-25 00:19:14 +0000 | [diff] [blame] | 111 | def convert(vin, cf, width, height, depth, bpp, pf): |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 112 | global seqno |
| 113 | |
Jack Jansen | c82cfc8 | 1993-02-19 10:06:28 +0000 | [diff] [blame] | 114 | if type(pf) == type(()): |
| 115 | xpf, ypf = pf |
| 116 | elif pf == 0: |
| 117 | xpf = ypf = 1 |
| 118 | else: |
| 119 | xpf = ypf = pf |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 120 | while 1: |
| 121 | try: |
| 122 | time, data, cdata = vin.getnextframe() |
| 123 | except EOFError: |
| 124 | return |
| 125 | if cdata: |
| 126 | print 'Film contains chromdata!' |
| 127 | return |
Jack Jansen | c82cfc8 | 1993-02-19 10:06:28 +0000 | [diff] [blame] | 128 | data = cf(data, width/xpf, height/abs(ypf)) |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 129 | if pf: |
Guido van Rossum | b616ebe | 1993-02-25 00:19:14 +0000 | [diff] [blame] | 130 | data = applypackfactor(data, width, height, pf, bpp) |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 131 | s = `seqno` |
| 132 | s = '0'*(4-len(s)) + s |
| 133 | fname = prefix + s + '.rgb' |
| 134 | seqno = seqno + 1 |
| 135 | if not quiet: |
| 136 | print 'Writing',fname,'...' |
| 137 | imgfile.write(fname, data, width, height, depth) |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 138 | |
Guido van Rossum | b616ebe | 1993-02-25 00:19:14 +0000 | [diff] [blame] | 139 | def applypackfactor(image, w, h, pf, bpp): |
| 140 | import imageop |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 141 | if type(pf) == type(()): |
| 142 | xpf, ypf = pf |
Guido van Rossum | b616ebe | 1993-02-25 00:19:14 +0000 | [diff] [blame] | 143 | elif pf == 0: |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 144 | xpf = ypf = 1 |
Guido van Rossum | b616ebe | 1993-02-25 00:19:14 +0000 | [diff] [blame] | 145 | else: |
| 146 | xpf = ypf = pf |
| 147 | w1 = w/xpf |
| 148 | h1 = h/abs(ypf) |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 149 | if ypf < 0: |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 150 | ypf = -ypf |
Guido van Rossum | b616ebe | 1993-02-25 00:19:14 +0000 | [diff] [blame] | 151 | image = imageop.crop(image, bpp, w1, h1, 0, h1-1, w1-1, 0) |
| 152 | return imageop.scale(image, bpp, w1, h1, w, h) |
Jack Jansen | eeec33f | 1993-02-17 15:52:56 +0000 | [diff] [blame] | 153 | |
| 154 | # Don't forget to call the main program |
| 155 | |
| 156 | try: |
| 157 | main() |
| 158 | except KeyboardInterrupt: |
| 159 | print '[Interrupt]' |