- Separated grabbing (which isn't used much!) from VFile.
- Renamed old Vcopy.py to OldVcopy.py, some cosmetic changes to it (is it still needed?) - Added new Vcopy.py which does everything that Vtime.py does but also format conversions, image scaling, and packfactors. - VFile: make packfactor always a tuple; introduce set and get methods for pf, format, and calculate some derived values. - Added new module GET.py to std library, use it instead of defining DM* in VFile. - Get rid of C programs (new Python programs can do all that they do and they probably don't understand the current file format anyway).
This commit is contained in:
parent
b616ebe4e4
commit
5e044b7009
@ -59,9 +59,9 @@ Vtime.py Copy a video file, manipulating the time codes (e.g.
|
|||||||
faster/slower, or regenerate time codes, or drop
|
faster/slower, or regenerate time codes, or drop
|
||||||
frames too close apart)
|
frames too close apart)
|
||||||
|
|
||||||
Vcopy.py selectively write frames from one movie file to another
|
Vcopy.py Universal video file copying tool. Can manipulate the
|
||||||
usage: Vcopy [-t type] [-m treshold] [-a] infile outfile
|
time codes, change the type, size, and packfactor.
|
||||||
commands: 'n' gets next frame; 'w' writes current frame
|
Subsumes Vtime.py.
|
||||||
|
|
||||||
Vmkjpeg.py compress an rgb or grey video file to jpeg[grey] format
|
Vmkjpeg.py compress an rgb or grey video file to jpeg[grey] format
|
||||||
|
|
||||||
|
@ -6,11 +6,10 @@
|
|||||||
#
|
#
|
||||||
# VideoParams: maintain essential parameters of a video file
|
# VideoParams: maintain essential parameters of a video file
|
||||||
# Displayer: display a frame in a window (with some extra parameters)
|
# Displayer: display a frame in a window (with some extra parameters)
|
||||||
# Grabber: grab a frame from a window
|
|
||||||
# BasicVinFile: read a CMIF video file
|
# BasicVinFile: read a CMIF video file
|
||||||
# BasicVoutFile: write a CMIF video file
|
# BasicVoutFile: write a CMIF video file
|
||||||
# VinFile: BasicVinFile + Displayer
|
# VinFile: BasicVinFile + Displayer
|
||||||
# VoutFile: BasicVoutFile + Displayer + Grabber
|
# VoutFile: BasicVoutFile + Displayer
|
||||||
#
|
#
|
||||||
# XXX Future extension:
|
# XXX Future extension:
|
||||||
# BasicVinoutFile: supports overwriting of individual frames
|
# BasicVinoutFile: supports overwriting of individual frames
|
||||||
@ -21,6 +20,7 @@
|
|||||||
import sys
|
import sys
|
||||||
import gl
|
import gl
|
||||||
import GL
|
import GL
|
||||||
|
import GET
|
||||||
import colorsys
|
import colorsys
|
||||||
import imageop
|
import imageop
|
||||||
|
|
||||||
@ -32,14 +32,6 @@ CallError = 'VFile.CallError' # bad call
|
|||||||
AssertError = 'VFile.AssertError' # internal malfunction
|
AssertError = 'VFile.AssertError' # internal malfunction
|
||||||
|
|
||||||
|
|
||||||
# Constants returned by gl.getdisplaymode(), from <gl/get.h>
|
|
||||||
|
|
||||||
DMRGB = 0
|
|
||||||
DMSINGLE = 1
|
|
||||||
DMDOUBLE = 2
|
|
||||||
DMRGBDOUBLE = 5
|
|
||||||
|
|
||||||
|
|
||||||
# Max nr. of colormap entries to use
|
# Max nr. of colormap entries to use
|
||||||
|
|
||||||
MAXMAP = 4096 - 256
|
MAXMAP = 4096 - 256
|
||||||
@ -151,9 +143,9 @@ def is_entry_indigo():
|
|||||||
b = gl.getgdesc(GL.GD_BITS_NORM_SNG_BLUE)
|
b = gl.getgdesc(GL.GD_BITS_NORM_SNG_BLUE)
|
||||||
return (r, g, b) == (3, 3, 2)
|
return (r, g, b) == (3, 3, 2)
|
||||||
|
|
||||||
#
|
|
||||||
# Predicate function to see whether this machine supports pixmode(PM_SIZE)
|
# Predicate to see whether this machine supports pixmode(PM_SIZE) with
|
||||||
# with values 1 or 4.
|
# values 1 or 4.
|
||||||
#
|
#
|
||||||
# XXX Temporarily disabled, since it is unclear which machines support
|
# XXX Temporarily disabled, since it is unclear which machines support
|
||||||
# XXX which pixelsizes.
|
# XXX which pixelsizes.
|
||||||
@ -161,66 +153,24 @@ def is_entry_indigo():
|
|||||||
# XXX The XS appears to support 4 bit pixels, but (looking at osview) it
|
# XXX The XS appears to support 4 bit pixels, but (looking at osview) it
|
||||||
# XXX seems as if the conversion is done by the kernel (unpacking ourselves
|
# XXX seems as if the conversion is done by the kernel (unpacking ourselves
|
||||||
# XXX is faster than using PM_SIZE=4)
|
# XXX is faster than using PM_SIZE=4)
|
||||||
#
|
|
||||||
def support_packed_pixels():
|
def support_packed_pixels():
|
||||||
return 0 # To be architecture-dependent
|
return 0 # To be architecture-dependent
|
||||||
|
|
||||||
# Routines to grab data, per color system (only a few really supported).
|
|
||||||
# (These functions are used via eval with a constructed argument!)
|
|
||||||
|
|
||||||
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 rgb 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 rgb8 in single-buf rgbmode'
|
|
||||||
if pf <> 1 and pf <> 0:
|
|
||||||
raise Error, 'Sorry, can only grab rgb8 with packfactor 1'
|
|
||||||
if not is_entry_indigo():
|
|
||||||
raise Error, 'Sorry, can only grab rgb8 on entry level Indigo'
|
|
||||||
# XXX Dirty Dirty here.
|
|
||||||
# XXX 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'
|
|
||||||
|
|
||||||
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
|
# Tables listing bits per pixel for some formats
|
||||||
|
|
||||||
def choose_grabber(format):
|
bitsperpixel = { \
|
||||||
try:
|
'rgb': 32, \
|
||||||
return eval('grab_' + format)
|
'rgb8': 8, \
|
||||||
except:
|
'grey': 8, \
|
||||||
raise Error, 'Unknown color system: ' + `format`
|
'grey4': 4, \
|
||||||
|
'grey2': 2, \
|
||||||
|
'mono': 1, \
|
||||||
|
}
|
||||||
|
|
||||||
|
bppafterdecomp = {'jpeg': 32, 'jpeggrey': 8}
|
||||||
|
|
||||||
|
|
||||||
# Base class to manage video format parameters
|
# Base class to manage video format parameters
|
||||||
@ -233,39 +183,102 @@ class VideoParams:
|
|||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
# Essential parameters
|
# Essential parameters
|
||||||
|
self.frozen = 0 # if set, can't change parameters
|
||||||
self.format = 'grey' # color system used
|
self.format = 'grey' # color system used
|
||||||
# Choose from: grey, rgb, rgb8, hsv, yiq, hls, jpeg, jpeggrey,
|
# Choose from: grey, rgb, rgb8, hsv, yiq, hls, jpeg, jpeggrey,
|
||||||
# mono, grey2, grey4
|
# mono, grey2, grey4
|
||||||
self.width = 0 # width of frame
|
self.width = 0 # width of frame
|
||||||
self.height = 0 # height of frame
|
self.height = 0 # height of frame
|
||||||
self.packfactor = 1 # expansion using rectzoom
|
self.packfactor = 1, 1 # expansion using rectzoom
|
||||||
# if packfactor == 0, data is one 32-bit word/pixel;
|
|
||||||
# otherwise, data is one byte/pixel
|
|
||||||
self.c0bits = 8 # bits in first color dimension
|
self.c0bits = 8 # bits in first color dimension
|
||||||
self.c1bits = 0 # bits in second color dimension
|
self.c1bits = 0 # bits in second color dimension
|
||||||
self.c2bits = 0 # bits in third color dimension
|
self.c2bits = 0 # bits in third color dimension
|
||||||
self.offset = 0 # colormap index offset (XXX ???)
|
self.offset = 0 # colormap index offset (XXX ???)
|
||||||
self.chrompack = 0 # set if separate chrominance data
|
self.chrompack = 0 # set if separate chrominance data
|
||||||
|
self.setderived()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
# Freeze the parameters (disallow changes)
|
||||||
|
|
||||||
|
def freeze(self):
|
||||||
|
self.frozen = 1
|
||||||
|
|
||||||
|
# Unfreeze the parameters (allow changes)
|
||||||
|
|
||||||
|
def unfreeze(self):
|
||||||
|
self.frozen = 0
|
||||||
|
|
||||||
|
# Set some values derived from the standard info values
|
||||||
|
|
||||||
|
def setderived(self):
|
||||||
|
if self.frozen: raise AssertError
|
||||||
|
if bitsperpixel.has_key(self.format):
|
||||||
|
self.bpp = bitsperpixel[self.format]
|
||||||
|
else:
|
||||||
|
self.bpp = 0
|
||||||
|
xpf, ypf = self.packfactor
|
||||||
|
self.xpf = abs(xpf)
|
||||||
|
self.ypf = abs(ypf)
|
||||||
|
self.mirror_image = (xpf < 0)
|
||||||
|
self.upside_down = (ypf < 0)
|
||||||
|
self.realwidth = self.width / self.xpf
|
||||||
|
self.realheight = self.height / self.ypf
|
||||||
|
|
||||||
# Set the frame width and height (e.g. from gl.getsize())
|
# Set the frame width and height (e.g. from gl.getsize())
|
||||||
|
|
||||||
def setsize(self, width, height):
|
def setsize(self, width, height):
|
||||||
|
if self.frozen: raise CallError
|
||||||
|
width = (width/self.xpf)*self.xpf
|
||||||
|
height = (height/self.ypf)*self.ypf
|
||||||
self.width, self.height = width, height
|
self.width, self.height = width, height
|
||||||
|
self.setderived()
|
||||||
|
|
||||||
# Retrieve the frame width and height (e.g. for gl.prefsize())
|
# Retrieve the frame width and height (e.g. for gl.prefsize())
|
||||||
|
|
||||||
def getsize(self):
|
def getsize(self):
|
||||||
return (self.width, self.height)
|
return (self.width, self.height)
|
||||||
|
|
||||||
# Set all parameters.
|
# Set the format
|
||||||
# This does limited validity checking;
|
|
||||||
# if the check fails no parameters are changed
|
def setformat(self, format):
|
||||||
|
if self.frozen: raise CallError
|
||||||
|
if format <> self.format:
|
||||||
|
self.format = format
|
||||||
|
self.setderived()
|
||||||
|
|
||||||
|
# Get the format
|
||||||
|
|
||||||
|
def getformat(self):
|
||||||
|
return self.format
|
||||||
|
|
||||||
|
# Set the packfactor
|
||||||
|
|
||||||
|
def setpf(self, pf):
|
||||||
|
if self.frozen: raise CallError
|
||||||
|
## if type(pf) is type(0):
|
||||||
|
## if pf == 0:
|
||||||
|
## pf = (1, 1)
|
||||||
|
## else:
|
||||||
|
## pf = (pf, pf)
|
||||||
|
if type(pf) is not type(()) or len(pf) <> 2: raise CallError
|
||||||
|
self.packfactor = pf
|
||||||
|
self.setderived()
|
||||||
|
|
||||||
|
# Get the packfactor
|
||||||
|
|
||||||
|
def getpf(self):
|
||||||
|
return self.packfactor
|
||||||
|
|
||||||
|
# Set all parameters
|
||||||
|
|
||||||
def setinfo(self, values):
|
def setinfo(self, values):
|
||||||
(self.format, self.width, self.height, self.packfactor,\
|
if self.frozen: raise CallError
|
||||||
self.c0bits, self.c1bits, self.c2bits, self.offset, \
|
self.setformat(values[0])
|
||||||
self.chrompack) = values
|
self.setpf(values[3])
|
||||||
|
self.setsize(values[1], values[2])
|
||||||
|
(self.c0bits, self.c1bits, self.c2bits, \
|
||||||
|
self.offset, self.chrompack) = values[4:]
|
||||||
|
self.setderived()
|
||||||
|
|
||||||
# Retrieve all parameters in a format suitable for a subsequent
|
# Retrieve all parameters in a format suitable for a subsequent
|
||||||
# call to setinfo()
|
# call to setinfo()
|
||||||
@ -281,27 +294,17 @@ class VideoParams:
|
|||||||
print 'Format: ', self.format
|
print 'Format: ', self.format
|
||||||
print 'Size: ', self.width, 'x', self.height
|
print 'Size: ', self.width, 'x', self.height
|
||||||
print 'Pack: ', self.packfactor, '; chrom:', self.chrompack
|
print 'Pack: ', self.packfactor, '; chrom:', self.chrompack
|
||||||
|
print 'Bpp: ', self.bpp
|
||||||
print 'Bits: ', self.c0bits, self.c1bits, self.c2bits
|
print 'Bits: ', self.c0bits, self.c1bits, self.c2bits
|
||||||
print 'Offset: ', self.offset
|
print 'Offset: ', self.offset
|
||||||
|
|
||||||
# Calculate data size, if possible
|
# Calculate data size, if possible
|
||||||
|
# (Not counting frame header or cdata size)
|
||||||
|
|
||||||
def calcframesize(self):
|
def calcframesize(self):
|
||||||
if self.format == 'rgb':
|
if not self.bpp: raise CallError
|
||||||
return self.width*self.height*4
|
size = self.width/self.xpf * self.height/self.ypf
|
||||||
if self.format in ('jpeg', 'jpeggrey'):
|
size = (size * self.bpp + 7) / 8
|
||||||
raise CallError
|
|
||||||
if type(self.packfactor) == type(()):
|
|
||||||
xpf, ypf = self.packfactor
|
|
||||||
else:
|
|
||||||
xpf = ypf = self.packfactor
|
|
||||||
if ypf < 0: ypf = -ypf
|
|
||||||
size = (self.width/xpf)*(self.height/ypf)
|
|
||||||
if self.format == 'grey4':
|
|
||||||
size = (size+1)/2
|
|
||||||
elif self.format == 'grey2':
|
|
||||||
size = (size+3)/4
|
|
||||||
elif self.format == 'mono':
|
|
||||||
size = (size+7)/8
|
|
||||||
return size
|
return size
|
||||||
|
|
||||||
|
|
||||||
@ -346,33 +349,16 @@ class Displayer(VideoParams):
|
|||||||
(0,0,self.width,self.height))
|
(0,0,self.width,self.height))
|
||||||
|
|
||||||
def showpartframe(self, data, chromdata, (x,y,w,h)):
|
def showpartframe(self, data, chromdata, (x,y,w,h)):
|
||||||
pf = self.packfactor
|
pmsize = self.bpp
|
||||||
pmsize = 8
|
xpf, ypf = self.xpf, self.ypf
|
||||||
if pf:
|
if self.upside_down:
|
||||||
if type(pf) == type(()):
|
gl.pixmode(GL.PM_TTOB, 1)
|
||||||
xpf, ypf = pf
|
if self.mirror_image:
|
||||||
else:
|
gp.pixmode(GL.PM_RTOL, 1)
|
||||||
xpf = ypf = pf
|
|
||||||
if ypf < 0:
|
|
||||||
gl.pixmode(GL.PM_TTOB, 1)
|
|
||||||
ypf = -ypf
|
|
||||||
if xpf < 0:
|
|
||||||
gl.pixmode(GL.PM_RTOL, 1)
|
|
||||||
xpf = -xpf
|
|
||||||
else:
|
|
||||||
xpf = ypf = 1
|
|
||||||
if self.format in ('jpeg', 'jpeggrey'):
|
if self.format in ('jpeg', 'jpeggrey'):
|
||||||
import jpeg
|
import jpeg
|
||||||
data, width, height, bytes = jpeg.decompress(data)
|
data, width, height, bytes = jpeg.decompress(data)
|
||||||
if self.format == 'jpeg':
|
pmsize = bytes*8
|
||||||
b = 4
|
|
||||||
xp = yp = 1
|
|
||||||
else:
|
|
||||||
b = 1
|
|
||||||
xp = xpf
|
|
||||||
yp = ypf
|
|
||||||
if (width, height, bytes) <> (w/xp, h/yp, b):
|
|
||||||
raise Error, 'jpeg data has wrong size'
|
|
||||||
elif self.format in ('mono', 'grey4'):
|
elif self.format in ('mono', 'grey4'):
|
||||||
if self.mustunpack:
|
if self.mustunpack:
|
||||||
if self.format == 'mono':
|
if self.format == 'mono':
|
||||||
@ -381,24 +367,18 @@ class Displayer(VideoParams):
|
|||||||
elif self.format == 'grey4':
|
elif self.format == 'grey4':
|
||||||
data = imageop.grey42grey(data, \
|
data = imageop.grey42grey(data, \
|
||||||
w/xpf, h/ypf)
|
w/xpf, h/ypf)
|
||||||
else:
|
pmsize = 8
|
||||||
# We don't need to unpack, the hardware
|
|
||||||
# can do it.
|
|
||||||
if self.format == 'mono':
|
|
||||||
pmsize = 1
|
|
||||||
else:
|
|
||||||
pmsize = 4
|
|
||||||
elif self.format == 'grey2':
|
elif self.format == 'grey2':
|
||||||
data = imageop.grey22grey(data, w/xpf, h/ypf)
|
data = imageop.grey22grey(data, w/xpf, h/ypf)
|
||||||
|
pmsize = 8
|
||||||
if not self.colormapinited:
|
if not self.colormapinited:
|
||||||
self.initcolormap()
|
self.initcolormap()
|
||||||
if self.fixcolor0:
|
if self.fixcolor0:
|
||||||
gl.mapcolor(self.color0)
|
gl.mapcolor(self.color0)
|
||||||
self.fixcolor0 = 0
|
self.fixcolor0 = 0
|
||||||
xfactor = yfactor = self.magnify
|
xfactor = yfactor = self.magnify
|
||||||
if pf:
|
xfactor = xfactor * xpf
|
||||||
xfactor = xfactor * xpf
|
yfactor = yfactor * ypf
|
||||||
yfactor = yfactor * ypf
|
|
||||||
if chromdata and not self.skipchrom:
|
if chromdata and not self.skipchrom:
|
||||||
cp = self.chrompack
|
cp = self.chrompack
|
||||||
cx = int(x*xfactor*cp) + self.xorigin
|
cx = int(x*xfactor*cp) + self.xorigin
|
||||||
@ -411,13 +391,13 @@ class Displayer(VideoParams):
|
|||||||
gl.lrectwrite(cx, cy, cx + cw - 1, cy + ch - 1, \
|
gl.lrectwrite(cx, cy, cx + cw - 1, cy + ch - 1, \
|
||||||
chromdata)
|
chromdata)
|
||||||
#
|
#
|
||||||
if pf:
|
if pmsize < 32:
|
||||||
gl.writemask((1 << self.c0bits) - 1)
|
gl.writemask((1 << self.c0bits) - 1)
|
||||||
gl.pixmode(GL.PM_SIZE, pmsize)
|
gl.pixmode(GL.PM_SIZE, pmsize)
|
||||||
w = w/xpf
|
w = w/xpf
|
||||||
h = h/ypf
|
h = h/ypf
|
||||||
x = x/xpf
|
x = x/xpf
|
||||||
y = y/ypf
|
y = y/ypf
|
||||||
gl.rectzoom(xfactor, yfactor)
|
gl.rectzoom(xfactor, yfactor)
|
||||||
x = int(x*xfactor)+self.xorigin
|
x = int(x*xfactor)+self.xorigin
|
||||||
y = int(y*yfactor)+self.yorigin
|
y = int(y*yfactor)+self.yorigin
|
||||||
@ -464,7 +444,7 @@ class Displayer(VideoParams):
|
|||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
if not self.colormapinited: raise CallError
|
if not self.colormapinited: raise CallError
|
||||||
if gl.getdisplaymode() in (DMRGB, DMRGBDOUBLE):
|
if gl.getdisplaymode() in (GET.DMRGB, GET.DMRGBDOUBLE):
|
||||||
gl.RGBcolor(200, 200, 200) # XXX rather light grey
|
gl.RGBcolor(200, 200, 200) # XXX rather light grey
|
||||||
gl.clear()
|
gl.clear()
|
||||||
return
|
return
|
||||||
@ -477,7 +457,7 @@ class Displayer(VideoParams):
|
|||||||
|
|
||||||
def clearto(self, r, g, b):
|
def clearto(self, r, g, b):
|
||||||
if not self.colormapinited: raise CallError
|
if not self.colormapinited: raise CallError
|
||||||
if gl.getdisplaymode() in (DMRGB, DMRGBDOUBLE):
|
if gl.getdisplaymode() in (GET.DMRGB, GET.DMRGBDOUBLE):
|
||||||
gl.RGBcolor(r, g, b)
|
gl.RGBcolor(r, g, b)
|
||||||
gl.clear()
|
gl.clear()
|
||||||
return
|
return
|
||||||
@ -553,23 +533,6 @@ class Displayer(VideoParams):
|
|||||||
gl.gflush() # send the colormap changes to the X server
|
gl.gflush() # send the colormap changes to the X server
|
||||||
|
|
||||||
|
|
||||||
# Class to grab frames from a window.
|
|
||||||
# (This has fewer user-settable parameters than Displayer.)
|
|
||||||
# It is the caller's responsibility to initialize the window and to
|
|
||||||
# ensure that it is current when using grabframe()
|
|
||||||
|
|
||||||
class Grabber(VideoParams):
|
|
||||||
|
|
||||||
# XXX The init() method of VideoParams is just fine, for now
|
|
||||||
|
|
||||||
# Grab a frame.
|
|
||||||
# Return (data, chromdata) just like getnextframe().
|
|
||||||
|
|
||||||
def grabframe(self):
|
|
||||||
grabber = choose_grabber(self.format)
|
|
||||||
return grabber(self.width, self.height, self.packfactor)
|
|
||||||
|
|
||||||
|
|
||||||
# Read a CMIF video file header.
|
# Read a CMIF video file header.
|
||||||
# Return (version, values) where version is 0.0, 1.0, 2.0 or 3.[01],
|
# Return (version, values) where version is 0.0, 1.0, 2.0 or 3.[01],
|
||||||
# and values is ready for setinfo().
|
# and values is ready for setinfo().
|
||||||
@ -620,8 +583,6 @@ def readfileheader(fp, filename):
|
|||||||
format, rest = eval(line[:-1])
|
format, rest = eval(line[:-1])
|
||||||
except:
|
except:
|
||||||
raise Error, filename + ': Bad 3.[01] color info'
|
raise Error, filename + ': Bad 3.[01] color info'
|
||||||
if format == 'xrgb8':
|
|
||||||
format = 'rgb8' # rgb8 upside-down, for X
|
|
||||||
if format in ('rgb', 'jpeg'):
|
if format in ('rgb', 'jpeg'):
|
||||||
c0bits = c1bits = c2bits = 0
|
c0bits = c1bits = c2bits = 0
|
||||||
chrompack = 0
|
chrompack = 0
|
||||||
@ -637,6 +598,11 @@ def readfileheader(fp, filename):
|
|||||||
c0bits, c1bits, c2bits, chrompack, offset = rest
|
c0bits, c1bits, c2bits, chrompack, offset = rest
|
||||||
except:
|
except:
|
||||||
raise Error, filename + ': Bad 3.[01] color info'
|
raise Error, filename + ': Bad 3.[01] color info'
|
||||||
|
if format == 'xrgb8':
|
||||||
|
format = 'rgb8' # rgb8 upside-down, for X
|
||||||
|
upside_down = 1
|
||||||
|
else:
|
||||||
|
upside_down = 0
|
||||||
#
|
#
|
||||||
# Get frame geometry info
|
# Get frame geometry info
|
||||||
#
|
#
|
||||||
@ -657,15 +623,18 @@ def readfileheader(fp, filename):
|
|||||||
packfactor = 2
|
packfactor = 2
|
||||||
else:
|
else:
|
||||||
raise Error, filename + ': Bad (w,h,pf) info'
|
raise Error, filename + ': Bad (w,h,pf) info'
|
||||||
if type(packfactor) == type(()):
|
if type(packfactor) is type(0):
|
||||||
|
if packfactor == 0: packfactor = 1
|
||||||
|
xpf = ypf = packfactor
|
||||||
|
else:
|
||||||
xpf, ypf = packfactor
|
xpf, ypf = packfactor
|
||||||
xpf = abs(xpf)
|
if upside_down:
|
||||||
ypf = abs(ypf)
|
ypf = -ypf
|
||||||
width = (width/xpf) * xpf
|
packfactor = (xpf, ypf)
|
||||||
height = (height/ypf) * ypf
|
xpf = abs(xpf)
|
||||||
elif packfactor > 1:
|
ypf = abs(ypf)
|
||||||
width = (width / packfactor) * packfactor
|
width = (width/xpf) * xpf
|
||||||
height = (height / packfactor) * packfactor
|
height = (height/ypf) * ypf
|
||||||
#
|
#
|
||||||
# Return (version, values)
|
# Return (version, values)
|
||||||
#
|
#
|
||||||
@ -762,7 +731,8 @@ class BasicVinFile(VideoParams):
|
|||||||
self.fp = fp
|
self.fp = fp
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.version, values = readfileheader(fp, filename)
|
self.version, values = readfileheader(fp, filename)
|
||||||
VideoParams.setinfo(self, values)
|
self.setinfo(values)
|
||||||
|
self.freeze()
|
||||||
if self.version == 0.0:
|
if self.version == 0.0:
|
||||||
w, h, pf = self.width, self.height, self.packfactor
|
w, h, pf = self.width, self.height, self.packfactor
|
||||||
if pf == 0:
|
if pf == 0:
|
||||||
@ -801,12 +771,6 @@ class BasicVinFile(VideoParams):
|
|||||||
del self.fp
|
del self.fp
|
||||||
del self._readframeheader
|
del self._readframeheader
|
||||||
|
|
||||||
def setinfo(self, values):
|
|
||||||
raise CallError # Can't change info of input file!
|
|
||||||
|
|
||||||
def setsize(self, width, height):
|
|
||||||
raise CallError # Can't change info of input file!
|
|
||||||
|
|
||||||
def rewind(self):
|
def rewind(self):
|
||||||
if not self.canseek:
|
if not self.canseek:
|
||||||
raise Error, self.filename + ': can\'t seek'
|
raise Error, self.filename + ': can\'t seek'
|
||||||
@ -1022,8 +986,7 @@ class BasicVoutFile(VideoParams):
|
|||||||
self = VideoParams.init(self)
|
self = VideoParams.init(self)
|
||||||
self.fp = fp
|
self.fp = fp
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.version = 3.0 # In case anyone inquries
|
self.version = 3.1 # In case anyone inquries
|
||||||
self.headerwritten = 0
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
@ -1034,27 +997,23 @@ class BasicVoutFile(VideoParams):
|
|||||||
del self.fp
|
del self.fp
|
||||||
|
|
||||||
def prealloc(self, nframes):
|
def prealloc(self, nframes):
|
||||||
if not self.headerwritten: raise CallError
|
if not self.frozen: raise CallError
|
||||||
data = '\xff' * self.calcframesize()
|
data = '\xff' * (self.calcframesize() + 64)
|
||||||
pos = self.fp.tell()
|
pos = self.fp.tell()
|
||||||
for i in range(nframes):
|
for i in range(nframes):
|
||||||
self.fp.write(data)
|
self.fp.write(data)
|
||||||
self.fp.seek(pos)
|
self.fp.seek(pos)
|
||||||
|
|
||||||
def setinfo(self, values):
|
|
||||||
if self.headerwritten: raise CallError
|
|
||||||
VideoParams.setinfo(self, values)
|
|
||||||
|
|
||||||
def writeheader(self):
|
def writeheader(self):
|
||||||
if self.headerwritten: raise CallError
|
if self.frozen: raise CallError
|
||||||
writefileheader(self.fp, self.getinfo())
|
writefileheader(self.fp, self.getinfo())
|
||||||
self.headerwritten = 1
|
self.freeze()
|
||||||
self.atheader = 1
|
self.atheader = 1
|
||||||
self.framecount = 0
|
self.framecount = 0
|
||||||
|
|
||||||
def rewind(self):
|
def rewind(self):
|
||||||
self.fp.seek(0)
|
self.fp.seek(0)
|
||||||
self.headerwritten = 0
|
self.unfreeze()
|
||||||
self.atheader = 1
|
self.atheader = 1
|
||||||
self.framecount = 0
|
self.framecount = 0
|
||||||
|
|
||||||
@ -1071,7 +1030,7 @@ class BasicVoutFile(VideoParams):
|
|||||||
self.writeframedata(data, cdata)
|
self.writeframedata(data, cdata)
|
||||||
|
|
||||||
def writeframeheader(self, t, ds, cs):
|
def writeframeheader(self, t, ds, cs):
|
||||||
if not self.headerwritten: self.writeheader()
|
if not self.frozen: self.writeheader()
|
||||||
if not self.atheader: raise CallError
|
if not self.atheader: raise CallError
|
||||||
data = `(t, ds, cs)`
|
data = `(t, ds, cs)`
|
||||||
n = len(data)
|
n = len(data)
|
||||||
@ -1080,14 +1039,14 @@ class BasicVoutFile(VideoParams):
|
|||||||
self.atheader = 0
|
self.atheader = 0
|
||||||
|
|
||||||
def writeframedata(self, data, cdata):
|
def writeframedata(self, data, cdata):
|
||||||
if not self.headerwritten or self.atheader: raise CallError
|
if not self.frozen or self.atheader: raise CallError
|
||||||
if data: self.fp.write(data)
|
if data: self.fp.write(data)
|
||||||
if cdata: self.fp.write(cdata)
|
if cdata: self.fp.write(cdata)
|
||||||
self.atheader = 1
|
self.atheader = 1
|
||||||
self.framecount = self.framecount + 1
|
self.framecount = self.framecount + 1
|
||||||
|
|
||||||
|
|
||||||
# Classes that combine files with displayers and/or grabbers:
|
# Classes that combine files with displayers:
|
||||||
|
|
||||||
class VinFile(RandomVinFile, Displayer):
|
class VinFile(RandomVinFile, Displayer):
|
||||||
|
|
||||||
@ -1101,7 +1060,7 @@ class VinFile(RandomVinFile, Displayer):
|
|||||||
return t
|
return t
|
||||||
|
|
||||||
|
|
||||||
class VoutFile(BasicVoutFile, Displayer, Grabber):
|
class VoutFile(BasicVoutFile, Displayer):
|
||||||
|
|
||||||
def initfp(self, fp, filename):
|
def initfp(self, fp, filename):
|
||||||
self = Displayer.init(self)
|
self = Displayer.init(self)
|
||||||
|
78
Demo/sgi/video/VGrabber.py
Executable file
78
Demo/sgi/video/VGrabber.py
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
# Class to grab frames from a window.
|
||||||
|
# (This has fewer user-settable parameters than Displayer.)
|
||||||
|
# It is the caller's responsibility to initialize the window and to
|
||||||
|
# ensure that it is current when using grabframe()
|
||||||
|
|
||||||
|
import gl, GL
|
||||||
|
import VFile
|
||||||
|
import GET
|
||||||
|
from VFile import Error
|
||||||
|
|
||||||
|
class VGrabber(VFile.VideoParams):
|
||||||
|
|
||||||
|
# XXX The init() method of VideoParams is just fine, for now
|
||||||
|
|
||||||
|
# Grab a frame.
|
||||||
|
# Return (data, chromdata) just like getnextframe().
|
||||||
|
|
||||||
|
def grabframe(self):
|
||||||
|
grabber = choose_grabber(self.format)
|
||||||
|
return grabber(self.width, self.height, self.packfactor)
|
||||||
|
|
||||||
|
|
||||||
|
# Choose one of the grabber functions below based upon a color system name
|
||||||
|
|
||||||
|
def choose_grabber(format):
|
||||||
|
try:
|
||||||
|
return eval('grab_' + format)
|
||||||
|
except:
|
||||||
|
raise Error, 'Unknown color system: ' + `format`
|
||||||
|
|
||||||
|
|
||||||
|
# Routines to grab data, per color system (only a few really supported).
|
||||||
|
# (These functions are used via eval with a constructed argument!)
|
||||||
|
|
||||||
|
def grab_rgb(w, h, pf):
|
||||||
|
if gl.getdisplaymode() <> GET.DMRGB:
|
||||||
|
raise Error, 'Sorry, can only grab rgb in single-buf rgbmode'
|
||||||
|
if pf <> (1, 1):
|
||||||
|
raise Error, 'Sorry, only grab rgb with packfactor (1,1)'
|
||||||
|
return gl.lrectread(0, 0, w-1, h-1), None
|
||||||
|
|
||||||
|
def grab_rgb8(w, h, pf):
|
||||||
|
if gl.getdisplaymode() <> GET.DMRGB:
|
||||||
|
raise Error, 'Sorry, can only grab rgb8 in single-buf rgbmode'
|
||||||
|
if pf <> (1, 1):
|
||||||
|
raise Error, 'Sorry, can only grab rgb8 with packfactor (1,1)'
|
||||||
|
if not VFile.is_entry_indigo():
|
||||||
|
raise Error, 'Sorry, can only grab rgb8 on entry level Indigo'
|
||||||
|
# XXX Dirty Dirty here.
|
||||||
|
# XXX 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'
|
||||||
|
|
||||||
|
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'
|
@ -1,134 +1,269 @@
|
|||||||
# Copy a video file, interactively, frame-by-frame.
|
#! /ufs/guido/bin/sgi/python
|
||||||
|
|
||||||
import sys
|
# Universal (non-interactive) CMIF video file copier.
|
||||||
import getopt
|
|
||||||
from gl import *
|
|
||||||
from DEVICE import *
|
|
||||||
import VFile
|
|
||||||
import string
|
|
||||||
import imageop
|
|
||||||
|
|
||||||
def report(time, iframe):
|
|
||||||
print 'Frame', iframe, ': t =', time
|
# Possibilities:
|
||||||
|
#
|
||||||
|
# - Manipulate the time base:
|
||||||
|
# = resample at a fixed rate
|
||||||
|
# = divide the time codes by a speed factor (to make it go faster/slower)
|
||||||
|
# = drop frames that are less than n msec apart (to accomodate slow players)
|
||||||
|
# - Convert to a different format
|
||||||
|
# - Magnify (scale) the image
|
||||||
|
|
||||||
|
|
||||||
|
# Usage function (keep this up-to-date if you change the program!)
|
||||||
|
|
||||||
def usage():
|
def usage():
|
||||||
sys.stderr.write('usage: Vcopy [-t type] [-m treshold] [-a] infile outfile\n')
|
print 'Usage: Vcopy [options] [infile [outfile]]'
|
||||||
sys.stderr.write('-t Convert to other type\n')
|
print
|
||||||
sys.stderr.write('-a Automatic\n')
|
print 'Options:'
|
||||||
sys.stderr.write('-m Convert grey to mono with treshold\n')
|
print
|
||||||
sys.stderr.write('-d Convert grey to mono with dithering\n')
|
print '-t type : new image type (default unchanged)'
|
||||||
sys.exit(2)
|
print
|
||||||
|
print '-M magnify : image magnification factor (default unchanged)'
|
||||||
|
print '-w width : output image width (default height*4/3 if -h used)'
|
||||||
|
print '-h height : output image height (default width*3/4 if -w used)'
|
||||||
|
print
|
||||||
|
print '-p pf : new x and y packfactor (default unchanged)'
|
||||||
|
print '-x xpf : new x packfactor (default 1 if -y used)'
|
||||||
|
print '-y ypf : new y packfactor (default 1 if -x used)'
|
||||||
|
print
|
||||||
|
print '-m delta : drop frames closer than delta msec (default 0)'
|
||||||
|
print '-r delta : regenerate input time base delta msec apart'
|
||||||
|
print '-s speed : speed change factor (default unchanged)'
|
||||||
|
print
|
||||||
|
print 'infile : input file (default film.video)'
|
||||||
|
print 'outfile : output file (default out.video)'
|
||||||
|
|
||||||
def help():
|
|
||||||
print 'Command summary:'
|
import sys
|
||||||
print 'n get next image from input'
|
sys.path.append('/ufs/guido/src/video')
|
||||||
print 'w write current image to output'
|
|
||||||
|
import VFile
|
||||||
|
import imgconv
|
||||||
|
import imageop
|
||||||
|
import getopt
|
||||||
|
import string
|
||||||
|
|
||||||
|
|
||||||
|
# Global options
|
||||||
|
|
||||||
|
speed = 1.0
|
||||||
|
mindelta = 0
|
||||||
|
regen = None
|
||||||
|
newpf = None
|
||||||
|
newtype = None
|
||||||
|
magnify = None
|
||||||
|
newwidth = None
|
||||||
|
newheight = None
|
||||||
|
|
||||||
|
|
||||||
|
# Function to turn a string into a float
|
||||||
|
|
||||||
|
atof_error = 'atof_error' # Exception if it fails
|
||||||
|
|
||||||
|
def atof(s):
|
||||||
|
try:
|
||||||
|
return float(eval(s))
|
||||||
|
except:
|
||||||
|
raise atof_error
|
||||||
|
|
||||||
|
|
||||||
|
# Main program -- mostly command line parsing
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
foreground()
|
global speed, mindelta, regen, newpf, newtype, \
|
||||||
opts, args = getopt.getopt(sys.argv[1:], 't:am:d')
|
magnify, newwidth, newheight
|
||||||
if len(args) <> 2:
|
|
||||||
|
# Parse command line
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(sys.argv[1:], \
|
||||||
|
'M:h:m:p:r:s:t:w:x:y:')
|
||||||
|
except getopt.error, msg:
|
||||||
|
sys.stdout = sys.stderr
|
||||||
|
print 'Error:', msg, '\n'
|
||||||
usage()
|
usage()
|
||||||
[ifile, ofile] = args
|
sys.exit(2)
|
||||||
print 'open film ', ifile
|
|
||||||
ifilm = VFile.VinFile().init(ifile)
|
xpf = ypf = None
|
||||||
print 'open output ', ofile
|
|
||||||
ofilm = VFile.VoutFile().init(ofile)
|
|
||||||
|
|
||||||
ofilm.setinfo(ifilm.getinfo())
|
# Interpret options
|
||||||
|
try:
|
||||||
|
for opt, arg in opts:
|
||||||
|
if opt == '-M': magnify = atof(arg)
|
||||||
|
if opt == '-h': height = string.atoi(arg)
|
||||||
|
if opt == '-m': mindelta = string.atoi(arg)
|
||||||
|
if opt == '-p': xpf = ypf = string.atoi(arg)
|
||||||
|
if opt == '-r': regen = string.atoi(arg)
|
||||||
|
if opt == '-s': speed = atof(arg)
|
||||||
|
if opt == '-t': newtype = arg
|
||||||
|
if opt == '-w': newwidth = string.atoi(arg)
|
||||||
|
if opt == '-x': xpf = string.atoi(arg)
|
||||||
|
if opt == '-y': ypf = string.atoi(arg)
|
||||||
|
except string.atoi_error:
|
||||||
|
sys.stdout = sys.stderr
|
||||||
|
print 'Option', opt, 'requires integer argument'
|
||||||
|
sys.exit(2)
|
||||||
|
except atof_error:
|
||||||
|
sys.stdout = sys.stderr
|
||||||
|
print 'Option', opt, 'requires float argument'
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
if xpf or ypf:
|
||||||
|
if not xpf: xpf = 1
|
||||||
|
if not ypf: ypf = 1
|
||||||
|
newpf = (xpf, ypf)
|
||||||
|
|
||||||
|
if newwidth or newheight:
|
||||||
|
if magnify:
|
||||||
|
sys.stdout = sys.stderr
|
||||||
|
print 'Options -w or -h are incompatible with -M'
|
||||||
|
sys.exit(2)
|
||||||
|
if not newheight:
|
||||||
|
newheight = newwidth * 3 / 4
|
||||||
|
elif not newwidth:
|
||||||
|
newwidth = newheight * 4 / 3
|
||||||
|
|
||||||
|
# Check filename arguments
|
||||||
|
if len(args) < 1:
|
||||||
|
args.append('film.video')
|
||||||
|
if len(args) < 2:
|
||||||
|
args.append('out.video')
|
||||||
|
if len(args) > 2:
|
||||||
|
usage()
|
||||||
|
sys.exit(2)
|
||||||
|
if args[0] == args[1]:
|
||||||
|
sys.stderr.write('Input file can\'t be output file\n')
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
# Do the right thing
|
||||||
|
sts = process(args[0], args[1])
|
||||||
|
|
||||||
|
# Exit
|
||||||
|
sys.exit(sts)
|
||||||
|
|
||||||
|
|
||||||
|
# Copy one file to another
|
||||||
|
|
||||||
|
def process(infilename, outfilename):
|
||||||
|
global newwidth, newheight
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
vout.setinfo(vin.getinfo())
|
||||||
|
|
||||||
|
scale = 0
|
||||||
|
flip = 0
|
||||||
|
|
||||||
|
if newtype:
|
||||||
|
vout.setformat(newtype)
|
||||||
|
try:
|
||||||
|
convert = imgconv.getconverter(vin.format, vout.format)
|
||||||
|
except imgconv.error, msg:
|
||||||
|
sys.stderr.write(str(msg) + '\n')
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if newpf:
|
||||||
|
vout.setpf(newpf)
|
||||||
|
scale = 1
|
||||||
|
|
||||||
|
if newwidth and newheight:
|
||||||
|
scale = 1
|
||||||
|
|
||||||
|
if vin.upside_down <> vout.upside_down or \
|
||||||
|
vin.mirror_image <> vout.mirror_image:
|
||||||
|
flip = 1
|
||||||
|
|
||||||
|
inwidth, inheight = vin.getsize()
|
||||||
|
inwidth = inwidth / vin.xpf
|
||||||
|
inheight = inheight / vin.ypf
|
||||||
|
|
||||||
|
if magnify:
|
||||||
|
newwidth = int(vout.width * magnify)
|
||||||
|
newheight = int(vout.height * magnify)
|
||||||
|
scale = 1
|
||||||
|
|
||||||
|
if scale:
|
||||||
|
vout.setsize(newwidth, newheight)
|
||||||
|
else:
|
||||||
|
newwidth, newheight = vout.getsize()
|
||||||
|
|
||||||
|
if vin.packfactor <> vout.packfactor:
|
||||||
|
scale = 1
|
||||||
|
|
||||||
|
if scale or flip:
|
||||||
|
if vout.bpp not in (8, 32):
|
||||||
|
sys.stderr.write('Can\'t scale or flip this type\n')
|
||||||
|
return 1
|
||||||
|
|
||||||
|
newwidth = newwidth / vout.xpf
|
||||||
|
newheight = newheight / vout.ypf
|
||||||
|
|
||||||
|
vout.writeheader()
|
||||||
|
|
||||||
|
told = 0
|
||||||
|
nin = 0
|
||||||
|
nout = 0
|
||||||
|
tin = 0
|
||||||
|
tout = 0
|
||||||
|
|
||||||
use_grabber = 0
|
|
||||||
continuous = 0
|
|
||||||
tomono = 0
|
|
||||||
tomonodither = 0
|
|
||||||
for o, a in opts:
|
|
||||||
if o == '-t':
|
|
||||||
ofilm.format = a
|
|
||||||
use_grabber = 1
|
|
||||||
if o == '-a':
|
|
||||||
continuous = 1
|
|
||||||
if o == '-m':
|
|
||||||
if ifilm.format <> 'grey':
|
|
||||||
print '-m only supported for greyscale'
|
|
||||||
sys.exit(1)
|
|
||||||
tomono = 1
|
|
||||||
treshold = string.atoi(a)
|
|
||||||
ofilm.format = 'mono'
|
|
||||||
if o == '-d':
|
|
||||||
if ifilm.format <> 'grey':
|
|
||||||
print '-m only supported for greyscale'
|
|
||||||
sys.exit(1)
|
|
||||||
tomonodither = 1
|
|
||||||
ofilm.format = 'mono'
|
|
||||||
|
|
||||||
ofilm.writeheader()
|
|
||||||
#
|
|
||||||
prefsize(ifilm.width, ifilm.height)
|
|
||||||
w = winopen(ifile)
|
|
||||||
qdevice(KEYBD)
|
|
||||||
qdevice(ESCKEY)
|
|
||||||
qdevice(WINQUIT)
|
|
||||||
qdevice(WINSHUT)
|
|
||||||
print 'qdevice calls done'
|
|
||||||
#
|
|
||||||
help()
|
|
||||||
#
|
|
||||||
time, data, cdata = ifilm.getnextframe()
|
|
||||||
ifilm.showframe(data, cdata)
|
|
||||||
iframe = 1
|
|
||||||
report(time, iframe)
|
|
||||||
#
|
|
||||||
while 1:
|
while 1:
|
||||||
if continuous:
|
try:
|
||||||
dev = KEYBD
|
tin, data, cdata = vin.getnextframe()
|
||||||
else:
|
except EOFError:
|
||||||
dev, val = qread()
|
|
||||||
if dev in (ESCKEY, WINQUIT, WINSHUT):
|
|
||||||
break
|
break
|
||||||
if dev == REDRAW:
|
nin = nin + 1
|
||||||
reshapeviewport()
|
if regen:
|
||||||
elif dev == KEYBD:
|
tout = nin * regen
|
||||||
if continuous:
|
|
||||||
c = '0'
|
|
||||||
else:
|
|
||||||
c = chr(val)
|
|
||||||
#XXX Debug
|
|
||||||
if c == 'R':
|
|
||||||
c3i(255,0,0)
|
|
||||||
clear()
|
|
||||||
if c == 'G':
|
|
||||||
c3i(0,255,0)
|
|
||||||
clear()
|
|
||||||
if c == 'B':
|
|
||||||
c3i(0,0,255)
|
|
||||||
clear()
|
|
||||||
if c == 'w' or continuous:
|
|
||||||
if use_grabber:
|
|
||||||
data, cdata = ofilm.grabframe()
|
|
||||||
if tomono:
|
|
||||||
data = imageop.grey2mono(data, \
|
|
||||||
ifilm.width, ifilm.height, \
|
|
||||||
treshold)
|
|
||||||
if tomonodither:
|
|
||||||
data = imageop.dither2mono(data, \
|
|
||||||
ifilm.width, ifilm.height)
|
|
||||||
ofilm.writeframe(time, data, cdata)
|
|
||||||
print 'Frame', iframe, 'written.'
|
|
||||||
if c == 'n' or continuous:
|
|
||||||
try:
|
|
||||||
time,data,cdata = ifilm.getnextframe()
|
|
||||||
ifilm.showframe(data, cdata)
|
|
||||||
iframe = iframe+1
|
|
||||||
report(time, iframe)
|
|
||||||
except EOFError:
|
|
||||||
print 'EOF'
|
|
||||||
if continuous:
|
|
||||||
break
|
|
||||||
ringbell()
|
|
||||||
elif dev == INPUTCHANGE:
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
print '(dev, val) =', (dev, val)
|
tout = tin
|
||||||
ofilm.close()
|
tout = int(tout / speed)
|
||||||
|
if tout - told < mindelta:
|
||||||
|
continue
|
||||||
|
told = tout
|
||||||
|
if newtype:
|
||||||
|
data = convert(data, inwidth, inheight)
|
||||||
|
if newwidth and newheight:
|
||||||
|
data = imageop.scale(data, vout.bpp/8, \
|
||||||
|
inwidth, inheight, newwidth, newheight)
|
||||||
|
if vin.upside_down <> vout.upside_down or \
|
||||||
|
vin.mirror_image <> vout.mirror_image:
|
||||||
|
x0, y0 = 0, 0
|
||||||
|
x1, y1 = newwidth-1, neheight-1
|
||||||
|
if vin.upside_down <> vout.upside_down:
|
||||||
|
y1, y0 = y0, y1
|
||||||
|
if vin.mirror_image <> vout.mirror_image:
|
||||||
|
x1, x0 = x0, x1
|
||||||
|
data = imageop.crop(data, vout.bpp/8, \
|
||||||
|
newwidth, newheight, x0, y0, x1, y1)
|
||||||
|
vout.writeframe(tout, data, cdata)
|
||||||
|
nout = nout + 1
|
||||||
|
|
||||||
main()
|
vout.close()
|
||||||
|
vin.close()
|
||||||
|
|
||||||
|
|
||||||
|
# Don't forget to call the main program
|
||||||
|
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print '[Interrupt]'
|
||||||
|
@ -22,7 +22,7 @@ def rgb2jpeg(img, x, y):
|
|||||||
def jpeggrey2grey(img, width, height):
|
def jpeggrey2grey(img, width, height):
|
||||||
import jpeg
|
import jpeg
|
||||||
data, width, height, bytesperpixel = jpeg.decompress(img)
|
data, width, height, bytesperpixel = jpeg.decompress(img)
|
||||||
if bytesperpixel <> 1: raise RuntimeError, 'not grayscale jpeg'
|
if bytesperpixel <> 1: raise RuntimeError, 'not greyscale jpeg'
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def jpeg2rgb(img, width, height):
|
def jpeg2rgb(img, width, height):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user