| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | # Classes to read and write CMIF video files. | 
					
						
							|  |  |  | # (For a description of the CMIF video format, see cmif-file.ms.) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Layers of functionality: | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | # VideoParams: maintain essential parameters of a video file | 
					
						
							|  |  |  | # Displayer: display a frame in a window (with some extra parameters) | 
					
						
							|  |  |  | # BasicVinFile: read a CMIF video file | 
					
						
							|  |  |  | # BasicVoutFile: write a CMIF video file | 
					
						
							|  |  |  | # VinFile: BasicVinFile + Displayer | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | # VoutFile: BasicVoutFile + Displayer | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # XXX Future extension: | 
					
						
							|  |  |  | # BasicVinoutFile: supports overwriting of individual frames | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Imported modules | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import gl | 
					
						
							|  |  |  | import GL | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | import GET | 
					
						
							| 
									
										
										
										
											1991-12-03 16:52:40 +00:00
										 |  |  | import colorsys | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | import imageop | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | # Exception raised for various occasions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Error = 'VFile.Error'			# file format errors | 
					
						
							|  |  |  | CallError = 'VFile.CallError'		# bad call | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | AssertError = 'VFile.AssertError'	# internal malfunction | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Max nr. of colormap entries to use | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-02-11 14:45:43 +00:00
										 |  |  | MAXMAP = 4096 - 256 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Parametrizations of colormap handling based on color system. | 
					
						
							|  |  |  | # (These functions are used via eval with a constructed argument!) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def conv_grey(l, x, y): | 
					
						
							|  |  |  | 	return colorsys.yiq_to_rgb(l, 0, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | def conv_grey4(l, x, y): | 
					
						
							|  |  |  | 	return colorsys.yiq_to_rgb(l*17, 0, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def conv_mono(l, x, y): | 
					
						
							|  |  |  | 	return colorsys.yiq_to_rgb(l*255, 0, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | def conv_yiq(y, i, q): | 
					
						
							|  |  |  | 	return colorsys.yiq_to_rgb(y, (i-0.5)*1.2, q-0.5) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def conv_hls(l, h, s): | 
					
						
							|  |  |  | 	return colorsys.hls_to_rgb(h, l, s) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def conv_hsv(v, h, s): | 
					
						
							|  |  |  | 	return colorsys.hsv_to_rgb(h, s, v) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def conv_rgb(r, g, b): | 
					
						
							| 
									
										
										
										
											1992-02-11 14:45:43 +00:00
										 |  |  | 	raise Error, 'Attempt to make RGB colormap' | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def conv_rgb8(rgb, d1, d2): | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 	rgb = int(rgb*255.0) | 
					
						
							|  |  |  | 	r = (rgb >> 5) & 0x07 | 
					
						
							|  |  |  | 	g = (rgb     ) & 0x07 | 
					
						
							|  |  |  | 	b = (rgb >> 3) & 0x03 | 
					
						
							|  |  |  | 	return (r/7.0, g/7.0, b/3.0) | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | def conv_jpeg(r, g, b): | 
					
						
							|  |  |  | 	raise Error, 'Attempt to make RGB colormap (jpeg)' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | conv_jpeggrey = conv_grey | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | conv_grey2 = conv_grey | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | # Choose one of the above based upon a color system name | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | def choose_conversion(format): | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		return eval('conv_' + format) | 
					
						
							|  |  |  | 	except: | 
					
						
							|  |  |  | 		raise Error, 'Unknown color system: ' + `format` | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | # Inverses of the above | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def inv_grey(r, g, b): | 
					
						
							|  |  |  | 	y, i, q = colorsys.rgb_to_yiq(r, g, b) | 
					
						
							|  |  |  | 	return y, 0, 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def inv_yiq(r, g, b): | 
					
						
							|  |  |  | 	y, i, q = colorsys.rgb_to_yiq(r, g, b) | 
					
						
							|  |  |  | 	return y, i/1.2 + 0.5, q + 0.5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def inv_hls(r, g, b): | 
					
						
							|  |  |  | 	h, l, s = colorsys.rgb_to_hls(r, g, b) | 
					
						
							|  |  |  | 	return l, h, s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def inv_hsv(r, g, b): | 
					
						
							|  |  |  | 	h, s, v = colorsys.rgb_to_hsv(r, g, b) | 
					
						
							|  |  |  | 	return v, h, s | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def inv_rgb(r, g, b): | 
					
						
							|  |  |  | 	raise Error, 'Attempt to invert RGB colormap' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def inv_rgb8(r, g, b): | 
					
						
							|  |  |  | 	r = int(r*7.0) | 
					
						
							|  |  |  | 	g = int(g*7.0) | 
					
						
							|  |  |  | 	b = int(b*7.0) | 
					
						
							|  |  |  | 	rgb = ((r&7) << 5) | ((b&3) << 3) | (g&7) | 
					
						
							|  |  |  | 	return rgb / 255.0, 0, 0 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | def inv_jpeg(r, g, b): | 
					
						
							|  |  |  | 	raise Error, 'Attempt to invert RGB colormap (jpeg)' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inv_jpeggrey = inv_grey | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Choose one of the above based upon a color system name | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def choose_inverse(format): | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		return eval('inv_' + format) | 
					
						
							|  |  |  | 	except: | 
					
						
							|  |  |  | 		raise Error, 'Unknown color system: ' + `format` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Predicate to see whether this is an entry level (non-XS) Indigo. | 
					
						
							|  |  |  | # If so we can lrectwrite 8-bit wide pixels into a window in RGB mode | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def is_entry_indigo(): | 
					
						
							|  |  |  | 	# XXX hack, hack.  We should call gl.gversion() but that doesn't | 
					
						
							|  |  |  | 	# exist in earlier Python versions.  Therefore we check the number | 
					
						
							|  |  |  | 	# of bitplanes *and* the size of the monitor. | 
					
						
							|  |  |  | 	xmax = gl.getgdesc(GL.GD_XPMAX) | 
					
						
							|  |  |  | 	if xmax <> 1024: return 0 | 
					
						
							|  |  |  | 	ymax = gl.getgdesc(GL.GD_YPMAX) | 
					
						
							|  |  |  | 	if ymax != 768: return 0 | 
					
						
							|  |  |  | 	r = gl.getgdesc(GL.GD_BITS_NORM_SNG_RED) | 
					
						
							|  |  |  | 	g = gl.getgdesc(GL.GD_BITS_NORM_SNG_GREEN) | 
					
						
							|  |  |  | 	b = gl.getgdesc(GL.GD_BITS_NORM_SNG_BLUE) | 
					
						
							|  |  |  | 	return (r, g, b) == (3, 3, 2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Predicate to see whether this machine supports pixmode(PM_SIZE) with | 
					
						
							|  |  |  | # values 1 or 4. | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | # | 
					
						
							|  |  |  | # XXX Temporarily disabled, since it is unclear which machines support | 
					
						
							|  |  |  | # XXX which pixelsizes. | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											1993-01-27 11:41:37 +00:00
										 |  |  | # 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 is faster than using PM_SIZE=4) | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | def support_packed_pixels(): | 
					
						
							|  |  |  | 	return 0   # To be architecture-dependent | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | # Tables listing bits per pixel for some formats | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | bitsperpixel = { \ | 
					
						
							|  |  |  | 	  'rgb': 32, \ | 
					
						
							|  |  |  | 	  'rgb8': 8, \ | 
					
						
							|  |  |  | 	  'grey': 8, \ | 
					
						
							|  |  |  | 	  'grey4': 4, \ | 
					
						
							|  |  |  | 	  'grey2': 2, \ | 
					
						
							|  |  |  | 	  'mono': 1, \ | 
					
						
							| 
									
										
										
										
											1993-03-17 12:09:29 +00:00
										 |  |  | 	  'compress': 32, \ | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | bppafterdecomp = {'jpeg': 32, 'jpeggrey': 8} | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Base class to manage video format parameters | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class VideoParams: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# Initialize an instance. | 
					
						
							|  |  |  | 	# Set all parameters to something decent | 
					
						
							|  |  |  | 	# (except width and height are set to zero) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def init(self): | 
					
						
							|  |  |  | 		# Essential parameters | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		self.frozen = 0		# if set, can't change parameters | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self.format = 'grey'	# color system used | 
					
						
							| 
									
										
										
										
											1992-12-14 12:25:21 +00:00
										 |  |  | 		# Choose from: grey, rgb, rgb8, hsv, yiq, hls, jpeg, jpeggrey, | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		#              mono, grey2, grey4 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self.width = 0		# width of frame | 
					
						
							|  |  |  | 		self.height = 0		# height of frame | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		self.packfactor = 1, 1	# expansion using rectzoom | 
					
						
							| 
									
										
										
										
											1993-03-02 12:07:34 +00:00
										 |  |  | 		# Colormap info | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self.c0bits = 8		# bits in first color dimension | 
					
						
							|  |  |  | 		self.c1bits = 0		# bits in second color dimension | 
					
						
							|  |  |  | 		self.c2bits = 0		# bits in third color dimension | 
					
						
							|  |  |  | 		self.offset = 0		# colormap index offset (XXX ???) | 
					
						
							|  |  |  | 		self.chrompack = 0	# set if separate chrominance data | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		self.setderived() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		return self | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 	# 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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-03-02 12:07:34 +00:00
										 |  |  | 	# Set colormap info | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def setcmapinfo(self): | 
					
						
							|  |  |  | 		stuff = 0, 0, 0, 0, 0 | 
					
						
							|  |  |  | 		if self.format in ('rgb8', 'grey'): | 
					
						
							|  |  |  | 			stuff = 8, 0, 0, 0, 0 | 
					
						
							|  |  |  | 		if self.format == 'grey4': | 
					
						
							|  |  |  | 			stuff = 4, 0, 0, 0, 0 | 
					
						
							|  |  |  | 		if self.format == 'grey2': | 
					
						
							|  |  |  | 			stuff = 2, 0, 0, 0, 0 | 
					
						
							|  |  |  | 		if self.format == 'mono': | 
					
						
							|  |  |  | 			stuff = 1, 0, 0, 0, 0 | 
					
						
							|  |  |  | 		self.c0bits, self.c1bits, self.c2bits, \ | 
					
						
							|  |  |  | 			  self.offset, self.chrompack = stuff | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	# Set the frame width and height (e.g. from gl.getsize()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-24 11:37:21 +00:00
										 |  |  | 	def setsize(self, width, height): | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if self.frozen: raise CallError | 
					
						
							|  |  |  | 		width = (width/self.xpf)*self.xpf | 
					
						
							|  |  |  | 		height = (height/self.ypf)*self.ypf | 
					
						
							| 
									
										
										
										
											1992-12-24 11:37:21 +00:00
										 |  |  | 		self.width, self.height = width, height | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		self.setderived() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	# Retrieve the frame width and height (e.g. for gl.prefsize()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def getsize(self): | 
					
						
							|  |  |  | 		return (self.width, self.height) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 	# Set the format | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def setformat(self, format): | 
					
						
							|  |  |  | 		if self.frozen: raise CallError | 
					
						
							| 
									
										
										
										
											1993-03-02 12:07:34 +00:00
										 |  |  | 		self.format = format | 
					
						
							|  |  |  | 		self.setderived() | 
					
						
							|  |  |  | 		self.setcmapinfo() | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	# 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 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 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def setinfo(self, values): | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if self.frozen: raise CallError | 
					
						
							|  |  |  | 		self.setformat(values[0]) | 
					
						
							|  |  |  | 		self.setpf(values[3]) | 
					
						
							|  |  |  | 		self.setsize(values[1], values[2]) | 
					
						
							|  |  |  | 		(self.c0bits, self.c1bits, self.c2bits, \ | 
					
						
							| 
									
										
										
										
											1993-03-17 12:09:29 +00:00
										 |  |  | 			  self.offset, self.chrompack) = values[4:9] | 
					
						
							|  |  |  | 		if self.format == 'compress': | 
					
						
							|  |  |  | 			self.compressheader = values[9] | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		self.setderived() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	# Retrieve all parameters in a format suitable for a subsequent | 
					
						
							|  |  |  | 	# call to setinfo() | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def getinfo(self): | 
					
						
							|  |  |  | 		return (self.format, self.width, self.height, self.packfactor,\ | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			self.c0bits, self.c1bits, self.c2bits, self.offset, \ | 
					
						
							|  |  |  | 			self.chrompack) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# Write the relevant bits to stdout | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def printinfo(self): | 
					
						
							|  |  |  | 		print 'Format:  ', self.format | 
					
						
							|  |  |  | 		print 'Size:    ', self.width, 'x', self.height | 
					
						
							|  |  |  | 		print 'Pack:    ', self.packfactor, '; chrom:', self.chrompack | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		print 'Bpp:     ', self.bpp | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		print 'Bits:    ', self.c0bits, self.c1bits, self.c2bits | 
					
						
							|  |  |  | 		print 'Offset:  ', self.offset | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 	# Calculate data size, if possible | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 	# (Not counting frame header or cdata size) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 	def calcframesize(self): | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if not self.bpp: raise CallError | 
					
						
							|  |  |  | 		size = self.width/self.xpf * self.height/self.ypf | 
					
						
							|  |  |  | 		size = (size * self.bpp + 7) / 8 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		return size | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # Class to display video frames in a window. | 
					
						
							|  |  |  | # It is the caller's responsibility to ensure that the correct window | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | # is current when using showframe(), initcolormap(), clear() and clearto() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Displayer(VideoParams): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# Initialize an instance. | 
					
						
							|  |  |  | 	# This does not need a current window | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def init(self): | 
					
						
							|  |  |  | 		self = VideoParams.init(self) | 
					
						
							|  |  |  | 		# User-settable parameters | 
					
						
							|  |  |  | 		self.magnify = 1.0	# frame magnification factor | 
					
						
							|  |  |  | 		self.xorigin = 0	# x frame offset | 
					
						
							|  |  |  | 		self.yorigin = 0	# y frame offset (from bottom) | 
					
						
							|  |  |  | 		self.quiet = 0		# if set, don't print messages | 
					
						
							|  |  |  | 		self.fallback = 1	# allow fallback to grey | 
					
						
							|  |  |  | 		# Internal flags | 
					
						
							|  |  |  | 		self.colormapinited = 0	# must initialize window | 
					
						
							|  |  |  | 		self.skipchrom = 0	# don't skip chrominance data | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		self.color0 = None	# magic, used by clearto() | 
					
						
							|  |  |  | 		self.fixcolor0 = 0	# don't need to fix color0 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		self.mustunpack = (not support_packed_pixels()) | 
					
						
							| 
									
										
										
										
											1993-03-17 12:09:29 +00:00
										 |  |  | 		self.decompressor = None | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		return self | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	# setinfo() must reset some internal flags | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	def setinfo(self, values): | 
					
						
							| 
									
										
										
										
											1992-09-22 15:01:43 +00:00
										 |  |  | 		VideoParams.setinfo(self, values) | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self.colormapinited = 0 | 
					
						
							|  |  |  | 		self.skipchrom = 0 | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		self.color0 = None | 
					
						
							|  |  |  | 		self.fixcolor0 = 0 | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	# Show one frame, initializing the window if necessary | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def showframe(self, data, chromdata): | 
					
						
							| 
									
										
										
										
											1992-09-22 15:01:43 +00:00
										 |  |  | 		self.showpartframe(data, chromdata, \ | 
					
						
							|  |  |  | 			  (0,0,self.width,self.height)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def showpartframe(self, data, chromdata, (x,y,w,h)): | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		pmsize = self.bpp | 
					
						
							|  |  |  | 		xpf, ypf = self.xpf, self.ypf | 
					
						
							|  |  |  | 		if self.upside_down: | 
					
						
							|  |  |  | 			gl.pixmode(GL.PM_TTOB, 1) | 
					
						
							|  |  |  | 		if self.mirror_image: | 
					
						
							|  |  |  | 			gp.pixmode(GL.PM_RTOL, 1) | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | 		if self.format in ('jpeg', 'jpeggrey'): | 
					
						
							|  |  |  | 			import jpeg | 
					
						
							|  |  |  | 			data, width, height, bytes = jpeg.decompress(data) | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 			pmsize = bytes*8 | 
					
						
							| 
									
										
										
										
											1993-03-17 12:09:29 +00:00
										 |  |  | 		elif self.format == 'compress': | 
					
						
							|  |  |  | 			if not self.decompressor: | 
					
						
							|  |  |  | 				import cl, CL | 
					
						
							|  |  |  | 				scheme = cl.QueryScheme(self.compressheader) | 
					
						
							|  |  |  | 				self.decompressor = cl.OpenDecompressor(scheme) | 
					
						
							|  |  |  | 				headersize = self.decompressor.ReadHeader(self.compressheader) | 
					
						
							|  |  |  | 				width = self.decompressor.GetParam(CL.IMAGE_WIDTH) | 
					
						
							|  |  |  | 				height = self.decompressor.GetParam(CL.IMAGE_HEIGHT) | 
					
						
							|  |  |  | 				params = [CL.ORIGINAL_FORMAT, CL.RGBX, \ | 
					
						
							|  |  |  | 					  CL.ORIENTATION, CL.BOTTOM_UP, \ | 
					
						
							|  |  |  | 					  CL.FRAME_BUFFER_SIZE, width*height*CL.BytesPerPixel(CL.RGBX)] | 
					
						
							|  |  |  | 				self.decompressor.SetParams(params) | 
					
						
							|  |  |  | 			data = self.decompressor.Decompress(1, data) | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		elif self.format in ('mono', 'grey4'): | 
					
						
							|  |  |  | 			if self.mustunpack: | 
					
						
							|  |  |  | 				if self.format == 'mono': | 
					
						
							|  |  |  | 					data = imageop.mono2grey(data, \ | 
					
						
							|  |  |  | 						  w/xpf, h/ypf, 0x20, 0xdf) | 
					
						
							|  |  |  | 				elif self.format == 'grey4': | 
					
						
							|  |  |  | 					data = imageop.grey42grey(data, \ | 
					
						
							|  |  |  | 						  w/xpf, h/ypf) | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 				pmsize = 8 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		elif self.format == 'grey2': | 
					
						
							|  |  |  | 			data = imageop.grey22grey(data, w/xpf, h/ypf) | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 			pmsize = 8 | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 		if not self.colormapinited: | 
					
						
							|  |  |  | 			self.initcolormap() | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		if self.fixcolor0: | 
					
						
							|  |  |  | 			gl.mapcolor(self.color0) | 
					
						
							|  |  |  | 			self.fixcolor0 = 0 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		xfactor = yfactor = self.magnify | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		xfactor = xfactor * xpf | 
					
						
							|  |  |  | 		yfactor = yfactor * ypf | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 		if chromdata and not self.skipchrom: | 
					
						
							|  |  |  | 			cp = self.chrompack | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 			cx = int(x*xfactor*cp) + self.xorigin | 
					
						
							|  |  |  | 			cy = int(y*yfactor*cp) + self.yorigin | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 			cw = (w+cp-1)/cp | 
					
						
							|  |  |  | 			ch = (h+cp-1)/cp | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 			gl.rectzoom(xfactor*cp, yfactor*cp) | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 			gl.pixmode(GL.PM_SIZE, 16) | 
					
						
							|  |  |  | 			gl.writemask(self.mask - ((1 << self.c0bits) - 1)) | 
					
						
							| 
									
										
										
										
											1992-09-22 15:01:43 +00:00
										 |  |  | 			gl.lrectwrite(cx, cy, cx + cw - 1, cy + ch - 1, \ | 
					
						
							|  |  |  | 				  chromdata) | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 		# | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if pmsize < 32: | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 			gl.writemask((1 << self.c0bits) - 1) | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		gl.pixmode(GL.PM_SIZE, pmsize) | 
					
						
							|  |  |  | 		w = w/xpf | 
					
						
							|  |  |  | 		h = h/ypf | 
					
						
							|  |  |  | 		x = x/xpf | 
					
						
							|  |  |  | 		y = y/ypf | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		gl.rectzoom(xfactor, yfactor) | 
					
						
							|  |  |  | 		x = int(x*xfactor)+self.xorigin | 
					
						
							|  |  |  | 		y = int(y*yfactor)+self.yorigin | 
					
						
							| 
									
										
										
										
											1992-09-22 15:01:43 +00:00
										 |  |  | 		gl.lrectwrite(x, y, x + w - 1, y + h - 1, data) | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		gl.gflush() | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	# Initialize the window: set RGB or colormap mode as required, | 
					
						
							|  |  |  | 	# fill in the colormap, and clear the window | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 	def initcolormap(self): | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		self.colormapinited = 1 | 
					
						
							|  |  |  | 		self.color0 = None | 
					
						
							|  |  |  | 		self.fixcolor0 = 0 | 
					
						
							| 
									
										
										
										
											1993-03-17 12:09:29 +00:00
										 |  |  | 		if self.format in ('rgb', 'jpeg', 'compress'): | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 			gl.RGBmode() | 
					
						
							|  |  |  | 			gl.gconfig() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			gl.RGBcolor(200, 200, 200) # XXX rather light grey | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 			gl.clear() | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											1992-09-29 17:07:10 +00:00
										 |  |  | 		# This only works on an Entry-level Indigo from IRIX 4.0.5 | 
					
						
							|  |  |  | 		if self.format == 'rgb8' and is_entry_indigo() and \ | 
					
						
							|  |  |  | 			  gl.gversion() == 'GL4DLG-4.0.': # Note trailing '.'! | 
					
						
							|  |  |  | 			gl.RGBmode() | 
					
						
							|  |  |  | 			gl.gconfig() | 
					
						
							|  |  |  | 			gl.RGBcolor(200, 200, 200) # XXX rather light grey | 
					
						
							|  |  |  | 			gl.clear() | 
					
						
							|  |  |  | 			gl.pixmode(GL.PM_SIZE, 8) | 
					
						
							|  |  |  | 			return | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 		gl.cmode() | 
					
						
							|  |  |  | 		gl.gconfig() | 
					
						
							|  |  |  | 		self.skipchrom = 0 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		if self.offset == 0: | 
					
						
							|  |  |  | 			self.mask = 0x7ff | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			self.mask = 0xfff | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 		if not self.quiet: | 
					
						
							|  |  |  | 			sys.stderr.write('Initializing color map...') | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self._initcmap() | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		gl.clear() | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 		if not self.quiet: | 
					
						
							|  |  |  | 			sys.stderr.write(' Done.\n') | 
					
						
							| 
									
										
										
										
											1992-09-01 14:45:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 	# Clear the window to a default color | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-01 14:45:57 +00:00
										 |  |  | 	def clear(self): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		if not self.colormapinited: raise CallError | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if gl.getdisplaymode() in (GET.DMRGB, GET.DMRGBDOUBLE): | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 			gl.RGBcolor(200, 200, 200) # XXX rather light grey | 
					
						
							| 
									
										
										
										
											1992-09-01 14:45:57 +00:00
										 |  |  | 			gl.clear() | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		gl.writemask(0xffffffff) | 
					
						
							|  |  |  | 		gl.clear() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# Clear the window to a given RGB color. | 
					
						
							|  |  |  | 	# This may steal the first color index used; the next call to | 
					
						
							|  |  |  | 	# showframe() will restore the intended mapping for that index | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 	def clearto(self, r, g, b): | 
					
						
							|  |  |  | 		if not self.colormapinited: raise CallError | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if gl.getdisplaymode() in (GET.DMRGB, GET.DMRGBDOUBLE): | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 			gl.RGBcolor(r, g, b) | 
					
						
							|  |  |  | 			gl.clear() | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		index = self.color0[0] | 
					
						
							|  |  |  | 		self.fixcolor0 = 1 | 
					
						
							|  |  |  | 		gl.mapcolor(index, r, g, b) | 
					
						
							|  |  |  | 		gl.writemask(0xffffffff) | 
					
						
							|  |  |  | 		gl.clear() | 
					
						
							|  |  |  | 		gl.gflush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# Do the hard work for initializing the colormap (internal). | 
					
						
							|  |  |  | 	# This also sets the current color to the first color index | 
					
						
							|  |  |  | 	# used -- the caller should never change this since it is used | 
					
						
							|  |  |  | 	# by clear() and clearto() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def _initcmap(self): | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		if self.format in ('mono', 'grey4') and self.mustunpack: | 
					
						
							|  |  |  | 			convcolor = conv_grey | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			convcolor = choose_conversion(self.format) | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 		maxbits = gl.getgdesc(GL.GD_BITS_NORM_SNG_CMODE) | 
					
						
							|  |  |  | 		if maxbits > 11: | 
					
						
							|  |  |  | 			maxbits = 11 | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		c0bits = self.c0bits | 
					
						
							|  |  |  | 		c1bits = self.c1bits | 
					
						
							|  |  |  | 		c2bits = self.c2bits | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 		if c0bits+c1bits+c2bits > maxbits: | 
					
						
							|  |  |  | 			if self.fallback and c0bits < maxbits: | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 				# Cannot display frames in this mode, use grey | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 				self.skipchrom = 1 | 
					
						
							|  |  |  | 				c1bits = c2bits = 0 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 				convcolor = choose_conversion('grey') | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 			else: | 
					
						
							|  |  |  | 				raise Error, 'Sorry, '+`maxbits`+ \ | 
					
						
							|  |  |  | 				  ' bits max on this machine' | 
					
						
							|  |  |  | 		maxc0 = 1 << c0bits | 
					
						
							|  |  |  | 		maxc1 = 1 << c1bits | 
					
						
							|  |  |  | 		maxc2 = 1 << c2bits | 
					
						
							|  |  |  | 		if self.offset == 0 and maxbits == 11: | 
					
						
							|  |  |  | 			offset = 2048 | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			offset = self.offset | 
					
						
							|  |  |  | 		if maxbits <> 11: | 
					
						
							|  |  |  | 			offset = offset & ((1<<maxbits)-1) | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		self.color0 = None | 
					
						
							|  |  |  | 		self.fixcolor0 = 0 | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 		for c0 in range(maxc0): | 
					
						
							|  |  |  | 			c0v = c0/float(maxc0-1) | 
					
						
							|  |  |  | 			for c1 in range(maxc1): | 
					
						
							|  |  |  | 				if maxc1 == 1: | 
					
						
							|  |  |  | 					c1v = 0 | 
					
						
							|  |  |  | 				else: | 
					
						
							|  |  |  | 					c1v = c1/float(maxc1-1) | 
					
						
							|  |  |  | 				for c2 in range(maxc2): | 
					
						
							|  |  |  | 					if maxc2 == 1: | 
					
						
							|  |  |  | 						c2v = 0 | 
					
						
							|  |  |  | 					else: | 
					
						
							|  |  |  | 						c2v = c2/float(maxc2-1) | 
					
						
							|  |  |  | 					index = offset + c0 + (c1<<c0bits) + \ | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 						(c2 << (c0bits+c1bits)) | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 					if index < MAXMAP: | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 						rv, gv, bv = \ | 
					
						
							|  |  |  | 						  convcolor(c0v, c1v, c2v) | 
					
						
							|  |  |  | 						r, g, b = int(rv*255.0), \ | 
					
						
							|  |  |  | 							  int(gv*255.0), \ | 
					
						
							|  |  |  | 							  int(bv*255.0) | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 						gl.mapcolor(index, r, g, b) | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 						if self.color0 == None: | 
					
						
							|  |  |  | 							self.color0 = \ | 
					
						
							|  |  |  | 								index, r, g, b | 
					
						
							|  |  |  | 		# Permanently make the first color index current | 
					
						
							|  |  |  | 		gl.color(self.color0[0]) | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		gl.gflush() # send the colormap changes to the X server | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-25 12:29:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | # Read a CMIF video file header. | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | # Return (version, values) where version is 0.0, 1.0, 2.0 or 3.[01], | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | # and values is ready for setinfo(). | 
					
						
							|  |  |  | # Raise Error if there is an error in the info | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def readfileheader(fp, filename): | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# Get identifying header | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	line = fp.readline(20) | 
					
						
							|  |  |  | 	if   line == 'CMIF video 0.0\n': | 
					
						
							|  |  |  | 		version = 0.0 | 
					
						
							|  |  |  | 	elif line == 'CMIF video 1.0\n': | 
					
						
							|  |  |  | 		version = 1.0 | 
					
						
							|  |  |  | 	elif line == 'CMIF video 2.0\n': | 
					
						
							|  |  |  | 		version = 2.0 | 
					
						
							|  |  |  | 	elif line == 'CMIF video 3.0\n': | 
					
						
							|  |  |  | 		version = 3.0 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 	elif line == 'CMIF video 3.1\n': | 
					
						
							|  |  |  | 		version = 3.1 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	else: | 
					
						
							|  |  |  | 		# XXX Could be version 0.0 without identifying header | 
					
						
							|  |  |  | 		raise Error, \ | 
					
						
							|  |  |  | 			filename + ': Unrecognized file header: ' + `line`[:20] | 
					
						
							| 
									
										
										
										
											1993-03-17 12:09:29 +00:00
										 |  |  | 	compressheader = None | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	# Get color encoding info | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 	# (The format may change to 'rgb' later when packfactor == 0) | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	if version <= 1.0: | 
					
						
							|  |  |  | 		format = 'grey' | 
					
						
							|  |  |  | 		c0bits, c1bits, c2bits = 8, 0, 0 | 
					
						
							|  |  |  | 		chrompack = 0 | 
					
						
							|  |  |  | 		offset = 0 | 
					
						
							|  |  |  | 	elif version == 2.0: | 
					
						
							|  |  |  | 		line = fp.readline() | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			c0bits, c1bits, c2bits, chrompack = eval(line[:-1]) | 
					
						
							|  |  |  | 		except: | 
					
						
							|  |  |  | 			raise Error, filename + ': Bad 2.0 color info' | 
					
						
							|  |  |  | 		if c1bits or c2bits: | 
					
						
							|  |  |  | 			format = 'yiq' | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			format = 'grey' | 
					
						
							|  |  |  | 		offset = 0 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 	elif version in (3.0, 3.1): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		line = fp.readline() | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			format, rest = eval(line[:-1]) | 
					
						
							|  |  |  | 		except: | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 			raise Error, filename + ': Bad 3.[01] color info' | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | 		if format in ('rgb', 'jpeg'): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			c0bits = c1bits = c2bits = 0 | 
					
						
							|  |  |  | 			chrompack = 0 | 
					
						
							|  |  |  | 			offset = 0 | 
					
						
							| 
									
										
										
										
											1993-03-17 12:09:29 +00:00
										 |  |  | 		elif format == 'compress': | 
					
						
							|  |  |  | 			c0bits = c1bits = c2bits = 0 | 
					
						
							|  |  |  | 			chrompack = 0 | 
					
						
							|  |  |  | 			offset = 0 | 
					
						
							|  |  |  | 			compressheader = rest | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		elif format in ('grey', 'jpeggrey', 'mono', 'grey2', 'grey4'): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			c0bits = rest | 
					
						
							|  |  |  | 			c1bits = c2bits = 0 | 
					
						
							|  |  |  | 			chrompack = 0 | 
					
						
							|  |  |  | 			offset = 0 | 
					
						
							|  |  |  | 		else: | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 			# XXX ought to check that the format is valid | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			try: | 
					
						
							|  |  |  | 			    c0bits, c1bits, c2bits, chrompack, offset = rest | 
					
						
							|  |  |  | 			except: | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 			    raise Error, filename + ': Bad 3.[01] color info' | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 	if format == 'xrgb8': | 
					
						
							|  |  |  | 		format = 'rgb8' # rgb8 upside-down, for X | 
					
						
							|  |  |  | 		upside_down = 1 | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		upside_down = 0 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	# Get frame geometry info | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	line = fp.readline() | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		x = eval(line[:-1]) | 
					
						
							|  |  |  | 	except: | 
					
						
							|  |  |  | 		raise Error, filename + ': Bad (w,h,pf) info' | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 	if type(x) <> type(()): | 
					
						
							|  |  |  | 		raise Error, filename + ': Bad (w,h,pf) info' | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	if len(x) == 3: | 
					
						
							|  |  |  | 		width, height, packfactor = x | 
					
						
							|  |  |  | 		if packfactor == 0 and version < 3.0: | 
					
						
							|  |  |  | 			format = 'rgb' | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 			c0bits = 0 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	elif len(x) == 2 and version <= 1.0: | 
					
						
							|  |  |  | 		width, height = x | 
					
						
							|  |  |  | 		packfactor = 2 | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		raise Error, filename + ': Bad (w,h,pf) info' | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 	if type(packfactor) is type(0): | 
					
						
							|  |  |  | 		if packfactor == 0: packfactor = 1 | 
					
						
							|  |  |  | 		xpf = ypf = packfactor | 
					
						
							|  |  |  | 	else: | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		xpf, ypf = packfactor | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 	if upside_down: | 
					
						
							|  |  |  | 		ypf = -ypf | 
					
						
							|  |  |  | 	packfactor = (xpf, ypf) | 
					
						
							|  |  |  | 	xpf = abs(xpf) | 
					
						
							|  |  |  | 	ypf = abs(ypf) | 
					
						
							|  |  |  | 	width = (width/xpf) * xpf | 
					
						
							|  |  |  | 	height = (height/ypf) * ypf | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	# Return (version, values) | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	values = (format, width, height, packfactor, \ | 
					
						
							| 
									
										
										
										
											1993-03-17 12:09:29 +00:00
										 |  |  | 		  c0bits, c1bits, c2bits, offset, chrompack, compressheader) | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	return (version, values) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Read a *frame* header -- separate functions per version. | 
					
						
							|  |  |  | # Return (timecode, datasize, chromdatasize). | 
					
						
							|  |  |  | # Raise EOFError if end of data is reached. | 
					
						
							|  |  |  | # Raise Error if data is bad. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def readv0frameheader(fp): | 
					
						
							|  |  |  | 	line = fp.readline() | 
					
						
							|  |  |  | 	if not line or line == '\n': raise EOFError | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		t = eval(line[:-1]) | 
					
						
							|  |  |  | 	except: | 
					
						
							|  |  |  | 		raise Error, 'Bad 0.0 frame header' | 
					
						
							|  |  |  | 	return (t, 0, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def readv1frameheader(fp): | 
					
						
							|  |  |  | 	line = fp.readline() | 
					
						
							|  |  |  | 	if not line or line == '\n': raise EOFError | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		t, datasize = eval(line[:-1]) | 
					
						
							|  |  |  | 	except: | 
					
						
							|  |  |  | 		raise Error, 'Bad 1.0 frame header' | 
					
						
							|  |  |  | 	return (t, datasize, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def readv2frameheader(fp): | 
					
						
							|  |  |  | 	line = fp.readline() | 
					
						
							|  |  |  | 	if not line or line == '\n': raise EOFError | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		t, datasize = eval(line[:-1]) | 
					
						
							|  |  |  | 	except: | 
					
						
							|  |  |  | 		raise Error, 'Bad 2.0 frame header' | 
					
						
							|  |  |  | 	return (t, datasize, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def readv3frameheader(fp): | 
					
						
							|  |  |  | 	line = fp.readline() | 
					
						
							|  |  |  | 	if not line or line == '\n': raise EOFError | 
					
						
							|  |  |  | 	try: | 
					
						
							|  |  |  | 		t, datasize, chromdatasize = x = eval(line[:-1]) | 
					
						
							|  |  |  | 	except: | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		raise Error, 'Bad 3.[01] frame header' | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	return x | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | # Write a CMIF video file header (always version 3.1) | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def writefileheader(fp, values): | 
					
						
							|  |  |  | 	(format, width, height, packfactor, \ | 
					
						
							|  |  |  | 		c0bits, c1bits, c2bits, offset, chrompack) = values | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# Write identifying header | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 	fp.write('CMIF video 3.1\n') | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	# | 
					
						
							|  |  |  | 	# Write color encoding info | 
					
						
							|  |  |  | 	# | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | 	if format in ('rgb', 'jpeg'): | 
					
						
							|  |  |  | 		data = (format, 0) | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 	elif format in ('grey', 'jpeggrey', 'mono', 'grey2', 'grey4'): | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | 		data = (format, c0bits) | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	else: | 
					
						
							|  |  |  | 		data = (format, (c0bits, c1bits, c2bits, chrompack, offset)) | 
					
						
							|  |  |  | 	fp.write(`data`+'\n') | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	# Write frame geometry info | 
					
						
							|  |  |  | 	# | 
					
						
							|  |  |  | 	data = (width, height, packfactor) | 
					
						
							|  |  |  | 	fp.write(`data`+'\n') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Basic class for reading CMIF video files | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BasicVinFile(VideoParams): | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def init(self, filename): | 
					
						
							| 
									
										
										
										
											1992-02-11 14:45:43 +00:00
										 |  |  | 		if filename == '-': | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			fp = sys.stdin | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			fp = open(filename, 'r') | 
					
						
							|  |  |  | 		return self.initfp(fp, filename) | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-18 14:16:21 +00:00
										 |  |  | 	def initfp(self, fp, filename): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self = VideoParams.init(self) | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 		self.fp = fp | 
					
						
							|  |  |  | 		self.filename = filename | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self.version, values = readfileheader(fp, filename) | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		self.setinfo(values) | 
					
						
							|  |  |  | 		self.freeze() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		if self.version == 0.0: | 
					
						
							|  |  |  | 			w, h, pf = self.width, self.height, self.packfactor | 
					
						
							|  |  |  | 			if pf == 0: | 
					
						
							|  |  |  | 				self._datasize = w*h*4 | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				self._datasize = (w/pf) * (h/pf) | 
					
						
							|  |  |  | 			self._readframeheader = self._readv0frameheader | 
					
						
							|  |  |  | 		elif self.version == 1.0: | 
					
						
							|  |  |  | 			self._readframeheader = readv1frameheader | 
					
						
							| 
									
										
										
										
											1992-02-11 14:45:43 +00:00
										 |  |  | 		elif self.version == 2.0: | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			self._readframeheader = readv2frameheader | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		elif self.version in (3.0, 3.1): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			self._readframeheader = readv3frameheader | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			raise Error, \ | 
					
						
							|  |  |  | 				filename + ': Bad version: ' + `self.version` | 
					
						
							|  |  |  | 		self.framecount = 0 | 
					
						
							|  |  |  | 		self.atframeheader = 1 | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		self.eofseen = 0 | 
					
						
							|  |  |  | 		self.errorseen = 0 | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 		try: | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			self.startpos = self.fp.tell() | 
					
						
							|  |  |  | 			self.canseek = 1 | 
					
						
							|  |  |  | 		except IOError: | 
					
						
							|  |  |  | 			self.startpos = -1 | 
					
						
							|  |  |  | 			self.canseek = 0 | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 		return self | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	def _readv0frameheader(self, fp): | 
					
						
							|  |  |  | 		t, ds, cs = readv0frameheader(fp) | 
					
						
							|  |  |  | 		ds = self._datasize | 
					
						
							|  |  |  | 		return (t, ds, cs) | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-18 17:00:51 +00:00
										 |  |  | 	def close(self): | 
					
						
							|  |  |  | 		self.fp.close() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		del self.fp | 
					
						
							|  |  |  | 		del self._readframeheader | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-08-20 11:51:47 +00:00
										 |  |  | 	def rewind(self): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		if not self.canseek: | 
					
						
							|  |  |  | 			raise Error, self.filename + ': can\'t seek' | 
					
						
							|  |  |  | 		self.fp.seek(self.startpos) | 
					
						
							|  |  |  | 		self.framecount = 0 | 
					
						
							|  |  |  | 		self.atframeheader = 1 | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		self.eofseen = 0 | 
					
						
							|  |  |  | 		self.errorseen = 0 | 
					
						
							| 
									
										
										
										
											1992-08-20 11:51:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	def warmcache(self): | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		print '[BasicVinFile.warmcache() not implemented]' | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	def printinfo(self): | 
					
						
							|  |  |  | 		print 'File:    ', self.filename | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | 		print 'Size:    ', getfilesize(self.filename) | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		print 'Version: ', self.version | 
					
						
							|  |  |  | 		VideoParams.printinfo(self) | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def getnextframe(self): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		t, ds, cs = self.getnextframeheader() | 
					
						
							|  |  |  | 		data, cdata = self.getnextframedata(ds, cs) | 
					
						
							|  |  |  | 		return (t, data, cdata) | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def skipnextframe(self): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		t, ds, cs = self.getnextframeheader() | 
					
						
							|  |  |  | 		self.skipnextframedata(ds, cs) | 
					
						
							|  |  |  | 		return t | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def getnextframeheader(self): | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		if self.eofseen: raise EOFError | 
					
						
							|  |  |  | 		if self.errorseen: raise CallError | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		if not self.atframeheader: raise CallError | 
					
						
							|  |  |  | 		self.atframeheader = 0 | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 		try: | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			return self._readframeheader(self.fp) | 
					
						
							|  |  |  | 		except Error, msg: | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 			self.errorseen = 1 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			# Patch up the error message | 
					
						
							|  |  |  | 			raise Error, self.filename + ': ' + msg | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		except EOFError: | 
					
						
							|  |  |  | 			self.eofseen = 1 | 
					
						
							|  |  |  | 			raise EOFError | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def getnextframedata(self, ds, cs): | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		if self.eofseen: raise EOFError | 
					
						
							|  |  |  | 		if self.errorseen: raise CallError | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		if self.atframeheader: raise CallError | 
					
						
							|  |  |  | 		if ds: | 
					
						
							|  |  |  | 			data = self.fp.read(ds) | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 			if len(data) < ds: | 
					
						
							|  |  |  | 				self.eofseen = 1 | 
					
						
							|  |  |  | 				raise EOFError | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		else: | 
					
						
							|  |  |  | 			data = '' | 
					
						
							|  |  |  | 		if cs: | 
					
						
							|  |  |  | 			cdata = self.fp.read(cs) | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 			if len(cdata) < cs: | 
					
						
							|  |  |  | 				self.eofseen = 1 | 
					
						
							|  |  |  | 				raise EOFError | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		else: | 
					
						
							|  |  |  | 			cdata = '' | 
					
						
							|  |  |  | 		self.atframeheader = 1 | 
					
						
							|  |  |  | 		self.framecount = self.framecount + 1 | 
					
						
							|  |  |  | 		return (data, cdata) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def skipnextframedata(self, ds, cs): | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		if self.eofseen: raise EOFError | 
					
						
							|  |  |  | 		if self.errorseen: raise CallError | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		if self.atframeheader: raise CallError | 
					
						
							|  |  |  | 		# Note that this won't raise EOFError for a partial frame | 
					
						
							|  |  |  | 		# since there is no easy way to tell whether a seek | 
					
						
							|  |  |  | 		# ended up beyond the end of the file | 
					
						
							|  |  |  | 		if self.canseek: | 
					
						
							|  |  |  | 			self.fp.seek(ds + cs, 1) # Relative seek | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			dummy = self.fp.read(ds + cs) | 
					
						
							|  |  |  | 			del dummy | 
					
						
							|  |  |  | 		self.atframeheader = 1 | 
					
						
							|  |  |  | 		self.framecount = self.framecount + 1 | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-29 13:40:47 +00:00
										 |  |  | # 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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-08 15:04:01 +00:00
										 |  |  | # Derived class implementing random access and index cached in the file | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class RandomVinFile(BasicVinFile): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def initfp(self, fp, filename): | 
					
						
							|  |  |  | 		self = BasicVinFile.initfp(self, fp, filename) | 
					
						
							|  |  |  | 		self.index = [] | 
					
						
							|  |  |  | 		return self | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def warmcache(self): | 
					
						
							|  |  |  | 		if len(self.index) == 0: | 
					
						
							| 
									
										
										
										
											1992-09-08 15:04:01 +00:00
										 |  |  | 			try: | 
					
						
							|  |  |  | 				self.readcache() | 
					
						
							|  |  |  | 			except Error: | 
					
						
							|  |  |  | 				self.buildcache() | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		else: | 
					
						
							|  |  |  | 			print '[RandomVinFile.warmcache(): too late]' | 
					
						
							| 
									
										
										
										
											1992-09-08 15:04:01 +00:00
										 |  |  | 			self.rewind() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def buildcache(self): | 
					
						
							|  |  |  | 		self.index = [] | 
					
						
							|  |  |  | 		self.rewind() | 
					
						
							|  |  |  | 		while 1: | 
					
						
							|  |  |  | 			try: dummy = self.skipnextframe() | 
					
						
							|  |  |  | 			except EOFError: break | 
					
						
							|  |  |  | 		self.rewind() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def writecache(self): | 
					
						
							|  |  |  | 		# Raises IOerror if the file is not seekable & writable! | 
					
						
							|  |  |  | 		import marshal | 
					
						
							|  |  |  | 		if len(self.index) == 0: | 
					
						
							|  |  |  | 			self.buildcache() | 
					
						
							|  |  |  | 			if len(self.index) == 0: | 
					
						
							|  |  |  | 				raise Error, self.filename + ': No frames' | 
					
						
							|  |  |  | 		self.fp.seek(0, 2) | 
					
						
							|  |  |  | 		self.fp.write('\n/////CMIF/////\n') | 
					
						
							|  |  |  | 		pos = self.fp.tell() | 
					
						
							|  |  |  | 		data = `pos` | 
					
						
							|  |  |  | 		data = '\n-*-*-CMIF-*-*-\n' + data + ' '*(15-len(data)) + '\n' | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			marshal.dump(self.index, self.fp) | 
					
						
							|  |  |  | 			self.fp.write(data) | 
					
						
							|  |  |  | 			self.fp.flush() | 
					
						
							|  |  |  | 		finally: | 
					
						
							|  |  |  | 			self.rewind() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def readcache(self): | 
					
						
							|  |  |  | 		# Raises Error if there is no cache in the file | 
					
						
							|  |  |  | 		import marshal | 
					
						
							|  |  |  | 		if len(self.index) <> 0: | 
					
						
							|  |  |  | 			raise CallError | 
					
						
							|  |  |  | 		self.fp.seek(-32, 2) | 
					
						
							|  |  |  | 		data = self.fp.read() | 
					
						
							|  |  |  | 		if data[:16] <> '\n-*-*-CMIF-*-*-\n' or data[-1:] <> '\n': | 
					
						
							|  |  |  | 			self.rewind() | 
					
						
							|  |  |  | 			raise Error, self.filename + ': No cache' | 
					
						
							|  |  |  | 		pos = eval(data[16:-1]) | 
					
						
							|  |  |  | 		self.fp.seek(pos) | 
					
						
							|  |  |  | 		try: | 
					
						
							|  |  |  | 			self.index = marshal.load(self.fp) | 
					
						
							|  |  |  | 		except TypeError: | 
					
						
							|  |  |  | 			self.rewind() | 
					
						
							|  |  |  | 			raise Error, self.filename + ': Bad cache' | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		self.rewind() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def getnextframeheader(self): | 
					
						
							|  |  |  | 		if self.framecount < len(self.index): | 
					
						
							|  |  |  | 			return self._getindexframeheader(self.framecount) | 
					
						
							|  |  |  | 		if self.framecount > len(self.index): | 
					
						
							|  |  |  | 			raise AssertError, \ | 
					
						
							|  |  |  | 				'managed to bypass index?!?' | 
					
						
							|  |  |  | 		rv = BasicVinFile.getnextframeheader(self) | 
					
						
							|  |  |  | 		if self.canseek: | 
					
						
							|  |  |  | 			pos = self.fp.tell() | 
					
						
							|  |  |  | 			self.index.append(rv, pos) | 
					
						
							|  |  |  | 		return rv | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def getrandomframe(self, i): | 
					
						
							|  |  |  | 		t, ds, cs = self.getrandomframeheader(i) | 
					
						
							| 
									
										
										
										
											1993-02-16 16:10:02 +00:00
										 |  |  | 		data, cdata = self.getnextframedata(ds, cs) | 
					
						
							|  |  |  | 		return t, data, cdata | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def getrandomframeheader(self, i): | 
					
						
							|  |  |  | 		if i < 0: raise ValueError, 'negative frame index' | 
					
						
							|  |  |  | 		if not self.canseek: | 
					
						
							|  |  |  | 			raise Error, self.filename + ': can\'t seek' | 
					
						
							|  |  |  | 		if i < len(self.index): | 
					
						
							|  |  |  | 			return self._getindexframeheader(i) | 
					
						
							|  |  |  | 		if len(self.index) > 0: | 
					
						
							|  |  |  | 			rv = self.getrandomframeheader(len(self.index)-1) | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			self.rewind() | 
					
						
							|  |  |  | 			rv = self.getnextframeheader() | 
					
						
							|  |  |  | 		while i > self.framecount: | 
					
						
							|  |  |  | 			self.skipnextframedata() | 
					
						
							|  |  |  | 			rv = self.getnextframeheader() | 
					
						
							|  |  |  | 		return rv | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def _getindexframeheader(self, i): | 
					
						
							|  |  |  | 		(rv, pos) = self.index[i] | 
					
						
							|  |  |  | 		self.fp.seek(pos) | 
					
						
							|  |  |  | 		self.framecount = i | 
					
						
							|  |  |  | 		self.atframeheader = 0 | 
					
						
							|  |  |  | 		self.eofseen = 0 | 
					
						
							|  |  |  | 		self.errorseen = 0 | 
					
						
							|  |  |  | 		return rv | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Basic class for writing CMIF video files | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | class BasicVoutFile(VideoParams): | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def init(self, filename): | 
					
						
							|  |  |  | 		if filename == '-': | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			fp = sys.stdout | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 		else: | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 			fp = open(filename, 'w') | 
					
						
							|  |  |  | 		return self.initfp(fp, filename) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 	def initfp(self, fp, filename): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self = VideoParams.init(self) | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 		self.fp = fp | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self.filename = filename | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		self.version = 3.1 # In case anyone inquries | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 		return self | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	def flush(self): | 
					
						
							|  |  |  | 		self.fp.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 	def close(self): | 
					
						
							|  |  |  | 		self.fp.close() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		del self.fp | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 	def prealloc(self, nframes): | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if not self.frozen: raise CallError | 
					
						
							|  |  |  | 		data = '\xff' * (self.calcframesize() + 64) | 
					
						
							| 
									
										
										
										
											1992-12-23 15:37:20 +00:00
										 |  |  | 		pos = self.fp.tell() | 
					
						
							|  |  |  | 		for i in range(nframes): | 
					
						
							|  |  |  | 			self.fp.write(data) | 
					
						
							|  |  |  | 		self.fp.seek(pos) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 	def writeheader(self): | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if self.frozen: raise CallError | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		writefileheader(self.fp, self.getinfo()) | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		self.freeze() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self.atheader = 1 | 
					
						
							|  |  |  | 		self.framecount = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def rewind(self): | 
					
						
							|  |  |  | 		self.fp.seek(0) | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		self.unfreeze() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self.atheader = 1 | 
					
						
							|  |  |  | 		self.framecount = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def printinfo(self): | 
					
						
							|  |  |  | 		print 'File:    ', self.filename | 
					
						
							|  |  |  | 		VideoParams.printinfo(self) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def writeframe(self, t, data, cdata): | 
					
						
							|  |  |  | 		if data: ds = len(data) | 
					
						
							|  |  |  | 		else: ds = 0 | 
					
						
							|  |  |  | 		if cdata: cs = len(cdata) | 
					
						
							|  |  |  | 		else: cs = 0 | 
					
						
							|  |  |  | 		self.writeframeheader(t, ds, cs) | 
					
						
							|  |  |  | 		self.writeframedata(data, cdata) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def writeframeheader(self, t, ds, cs): | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if not self.frozen: self.writeheader() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		if not self.atheader: raise CallError | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		data = `(t, ds, cs)` | 
					
						
							|  |  |  | 		n = len(data) | 
					
						
							|  |  |  | 		if n < 63: data = data + ' '*(63-n) | 
					
						
							|  |  |  | 		self.fp.write(data + '\n') | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		self.atheader = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	def writeframedata(self, data, cdata): | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | 		if not self.frozen or self.atheader: raise CallError | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		if data: self.fp.write(data) | 
					
						
							|  |  |  | 		if cdata: self.fp.write(cdata) | 
					
						
							|  |  |  | 		self.atheader = 1 | 
					
						
							|  |  |  | 		self.framecount = self.framecount + 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | # Classes that combine files with displayers: | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | class VinFile(RandomVinFile, Displayer): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def initfp(self, fp, filename): | 
					
						
							|  |  |  | 		self = Displayer.init(self) | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		return RandomVinFile.initfp(self, fp, filename) | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def shownextframe(self): | 
					
						
							|  |  |  | 		t, data, cdata = self.getnextframe() | 
					
						
							|  |  |  | 		self.showframe(data, cdata) | 
					
						
							|  |  |  | 		return t | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1993-02-25 14:20:13 +00:00
										 |  |  | class VoutFile(BasicVoutFile, Displayer): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	def initfp(self, fp, filename): | 
					
						
							|  |  |  | 		self = Displayer.init(self) | 
					
						
							|  |  |  | ##		self = Grabber.init(self) # XXX not needed | 
					
						
							|  |  |  | 		return BasicVoutFile.initfp(self, fp, filename) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Simple test program (VinFile only) | 
					
						
							| 
									
										
										
										
											1992-02-28 15:59:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | def test(): | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	import time | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 	if sys.argv[1:]: filename = sys.argv[1] | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	else: filename = 'film.video' | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 	vin = VinFile().init(filename) | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	vin.printinfo() | 
					
						
							| 
									
										
										
										
											1991-12-03 16:50:00 +00:00
										 |  |  | 	gl.foreground() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 	gl.prefsize(vin.getsize()) | 
					
						
							| 
									
										
										
										
											1992-02-11 14:45:43 +00:00
										 |  |  | 	wid = gl.winopen(filename) | 
					
						
							|  |  |  | 	vin.initcolormap() | 
					
						
							|  |  |  | 	t0 = time.millitimer() | 
					
						
							|  |  |  | 	while 1: | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		try: t, data, cdata = vin.getnextframe() | 
					
						
							| 
									
										
										
										
											1992-09-07 09:24:17 +00:00
										 |  |  | 		except EOFError: break | 
					
						
							|  |  |  | 		dt = t0 + t - time.millitimer() | 
					
						
							|  |  |  | 		if dt > 0: time.millisleep(dt) | 
					
						
							| 
									
										
										
										
											1992-09-07 15:28:57 +00:00
										 |  |  | 		vin.showframe(data, cdata) | 
					
						
							| 
									
										
										
										
											1992-02-11 14:45:43 +00:00
										 |  |  | 	time.sleep(2) |