Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2080b34

Browse files
committed
Added class VoutFile.
Added rgb8 support. Added cache of frame offsets to VinFile. Misc hacks to grab rgb8 data.
1 parent 444db07 commit 2080b34

1 file changed

Lines changed: 230 additions & 31 deletions

File tree

Demo/sgi/video/VFile.py

Lines changed: 230 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
Error = 'VFile.Error' # Exception
1111

12+
# Missing from GL.py:
13+
DMRGB = 0
14+
1215
MAXMAP = 4096 - 256
1316

1417
def conv_grey(l,x,y): return colorsys.yiq_to_rgb(l,0,0)
@@ -17,6 +20,12 @@ def conv_hls (l,h,s): return colorsys.hls_to_rgb(h,l,s)
1720
def conv_hsv (v,h,s): return colorsys.hsv_to_rgb(h,s,v)
1821
def conv_rgb (r,g,b):
1922
raise Error, 'Attempt to make RGB colormap'
23+
def conv_rgb8(rgb,d1,d2):
24+
rgb = int(rgb*255.0)
25+
r = (rgb >> 5) & 0x07
26+
g = (rgb ) & 0x07
27+
b = (rgb >> 3) & 0x03
28+
return (r/7.0, g/7.0, b/3.0)
2029

2130
# Class VinFile represents a video file used for input.
2231
#
@@ -39,6 +48,7 @@ def conv_rgb (r,g,b):
3948
# These writable data members provide additional parametrization:
4049
# magnify
4150
# xorigin, yorigin
51+
# fallback
4252

4353
class VinFile():
4454

@@ -54,6 +64,8 @@ def initfp(self, (fp, filename)):
5464
self.colormapinited = 0
5565
self.magnify = 1.0
5666
self.xorigin = self.yorigin = 0
67+
self.fallback = 1
68+
self.skipchrom = 0
5769
self.fp = fp
5870
self.filename = filename
5971
#
@@ -90,7 +102,11 @@ def initfp(self, (fp, filename)):
90102
try:
91103
self.format, rest = eval(line[:-1])
92104
if self.format == 'rgb':
93-
pass
105+
self.offset = 0
106+
self.c0bits = 0
107+
self.c1bits = 0
108+
self.c2bits = 0
109+
self.chrompack = 0
94110
elif self.format == 'grey':
95111
self.offset = 0
96112
self.c0bits = rest
@@ -121,16 +137,46 @@ def initfp(self, (fp, filename)):
121137
self.packfactor = 2
122138
except:
123139
raise Error, self.filename + ': bad (w,h,pf) info'
140+
self.frameno = 0
141+
self.framecache = []
142+
self.hascache = 0
124143
#
125144
return self
126145

146+
def warmcache(self):
147+
if self.hascache: return
148+
n = 0
149+
try:
150+
while 1:
151+
void = self.skipnextframe()
152+
n = n + 1
153+
except EOFError:
154+
pass
155+
if not self.hascache:
156+
raise Error, 'Cannot warm cache'
157+
158+
159+
#
160+
# getinfo returns all info pertaining to a film. The returned tuple
161+
# can be passed to VoutFile.setinfo()
162+
#
163+
def getinfo(self):
164+
return (self.format, self.width, self.height, self.packfactor,\
165+
self.c0bits, self.c1bits, self.c2bits, self.offset, \
166+
self.chrompack)
167+
127168
# rewind() raises Error if the header is bad (which can only
128169
# happen if the file was written to since opened).
129170

130171
def rewind(self):
131172
self.fp.seek(0)
132173
x = self.initfp(self.fp, self.filename)
133174

175+
def position(self):
176+
if self.frameno >= len(self.framecache):
177+
raise EOFError
178+
self.fp.seek(self.framecache[self.frameno][0])
179+
134180
# getnextframe() raises EOFError (built-in) if there is no next frame,
135181
# or if the next frame is broken.
136182
# So to getnextframeheader(), getnextframedata() and skipnextframe().
@@ -141,6 +187,9 @@ def getnextframe(self):
141187
return time, data, chromdata
142188

143189
def getnextframedata(self, (size, chromsize)):
190+
if self.hascache:
191+
self.position()
192+
self.frameno = self.frameno + 1
144193
data = self.fp.read(size)
145194
if len(data) <> size: raise EOFError
146195
if chromsize:
@@ -157,6 +206,9 @@ def skipnextframe(self):
157206
return time
158207

159208
def skipnextframedata(self, (size, chromsize)):
209+
if self.hascache:
210+
self.frameno = self.frameno + 1
211+
return
160212
# Note that this won't raise EOFError for a partial frame.
161213
try:
162214
self.fp.seek(size + chromsize, 1) # Relative seek
@@ -165,8 +217,13 @@ def skipnextframedata(self, (size, chromsize)):
165217
dummy = self.fp.read(size + chromsize)
166218

167219
def getnextframeheader(self):
220+
if self.hascache:
221+
if self.frameno >= len(self.framecache):
222+
raise EOFError
223+
return self.framecache[self.frameno][1]
168224
line = self.fp.readline()
169225
if not line:
226+
self.hascache = 1
170227
raise EOFError
171228
#
172229
w, h, pf = self.width, self.height, self.packfactor
@@ -191,6 +248,8 @@ def getnextframeheader(self):
191248
time, size, chromsize = x
192249
except:
193250
raise Error, self.filename + ': bad frame header'
251+
cdata = (self.fp.tell(), (time, size, chromsize))
252+
self.framecache.append(cdata)
194253
return time, size, chromsize
195254

196255
def shownextframe(self):
@@ -204,7 +263,7 @@ def showframe(self, (data, chromdata)):
204263
self.initcolormap()
205264
factor = self.magnify
206265
if pf: factor = factor * pf
207-
if chromdata:
266+
if chromdata and not self.skipchrom:
208267
cp = self.chrompack
209268
cw = (w+cp-1)/cp
210269
ch = (h+cp-1)/cp
@@ -232,49 +291,188 @@ def initcolormap(self):
232291
return
233292
gl.cmode()
234293
gl.gconfig()
294+
self.skipchrom = 0
235295
sys.stderr.write('Initializing color map...')
236-
initcmap(self.convcolor, self.c0bits, self.c1bits, \
237-
self.c2bits, self.chrompack, self.offset)
296+
self.initcmap()
238297
sys.stderr.write(' Done.\n')
239298
if self.offset == 0:
240299
gl.color(0x800)
300+
gl.clear()
241301
self.mask = 0x7ff
242302
else:
243303
self.mask = 0xfff
244304
gl.clear()
245305

246306

247-
def initcmap(convcolor, c0bits, c1bits, c2bits, chrompack, offset):
248-
if c0bits+c1bits+c2bits > 11:
249-
raise Error, 'Sorry, 11 bits max'
250-
maxc0 = 1 << c0bits
251-
maxc1 = 1 << c1bits
252-
maxc2 = 1 << c2bits
253-
if offset == 0:
254-
offset = 2048
255-
for i in range(offset, MAXMAP):
256-
gl.mapcolor(i, 0, 255, 0)
257-
for c0 in range(maxc0):
258-
c0v = c0/float(maxc0-1)
259-
for c1 in range(maxc1):
260-
if maxc1 == 1:
261-
c1v = 0
307+
def initcmap(self):
308+
maxbits = gl.getgdesc(GL.GD_BITS_NORM_SNG_CMODE)
309+
if maxbits > 11:
310+
maxbits = 11
311+
c0bits, c1bits, c2bits = self.c0bits, self.c1bits, self.c2bits
312+
if c0bits+c1bits+c2bits > maxbits:
313+
if self.fallback and c0bits < maxbits:
314+
# Cannot display film in this mode, use mono
315+
self.skipchrom = 1
316+
c1bits = c2bits = 0
317+
self.convcolor = conv_grey
262318
else:
263-
c1v = c1/float(maxc1-1)
264-
for c2 in range(maxc2):
265-
if maxc2 == 1:
266-
c2v = 0
319+
raise Error, 'Sorry, '+`maxbits`+ \
320+
' bits max on this machine'
321+
maxc0 = 1 << c0bits
322+
maxc1 = 1 << c1bits
323+
maxc2 = 1 << c2bits
324+
if self.offset == 0 and maxbits == 11:
325+
offset = 2048
326+
else:
327+
offset = self.offset
328+
if maxbits <> 11:
329+
offset = offset & ((1<<maxbits)-1)
330+
#for i in range(512, MAXMAP):
331+
# gl.mapcolor(i, 0, 0, 0)
332+
#void = gl.qtest() # Should be gl.gflush()
333+
for c0 in range(maxc0):
334+
c0v = c0/float(maxc0-1)
335+
for c1 in range(maxc1):
336+
if maxc1 == 1:
337+
c1v = 0
267338
else:
268-
c2v = c2/float(maxc2-1)
269-
index = offset + c0 + \
270-
(c1<<c0bits) + (c2 << (c0bits+c1bits))
271-
rv, gv, bv = convcolor(c0v, c1v, c2v)
272-
r, g, b = \
273-
int(rv*255.0), int(gv*255.0), int(bv*255.0)
274-
if index < MAXMAP:
275-
gl.mapcolor(index, r, g, b)
339+
c1v = c1/float(maxc1-1)
340+
for c2 in range(maxc2):
341+
if maxc2 == 1:
342+
c2v = 0
343+
else:
344+
c2v = c2/float(maxc2-1)
345+
index = offset + c0 + (c1<<c0bits) + \
346+
(c2 << (c0bits+c1bits))
347+
rv, gv, bv = self.convcolor( \
348+
c0v, c1v, c2v)
349+
r, g, b = int(rv*255.0), \
350+
int(gv*255.0), int(bv*255.0)
351+
if index < MAXMAP:
352+
gl.mapcolor(index, r, g, b)
353+
void = gl.gflush()
354+
355+
#
356+
# A set of routines to grab images from windows
357+
#
358+
def grab_rgb(w, h, pf):
359+
if gl.getdisplaymode() <> DMRGB:
360+
raise Error, 'Sorry, can only grab rgb in single-buf rgbmode'
361+
if pf <> 1 and pf <> 0:
362+
raise Error, 'Sorry, only grab with packfactor=1'
363+
return gl.lrectread(0, 0, w-1, h-1), None
364+
365+
def grab_rgb8(w, h, pf):
366+
if gl.getdisplaymode() <> DMRGB:
367+
raise Error, 'Sorry, can only grab rgb in single-buf rgbmode'
368+
if pf <> 1 and pf <> 0:
369+
raise Error, 'Sorry, can only grab with packfactor=1'
370+
r = gl.getgdesc(GL.GD_BITS_NORM_SNG_RED)
371+
g = gl.getgdesc(GL.GD_BITS_NORM_SNG_GREEN)
372+
b = gl.getgdesc(GL.GD_BITS_NORM_SNG_BLUE)
373+
if (r,g,b) <> (3,3,2):
374+
raise Error, 'Sorry, can only grab rgb8 on 8-bit Indigo'
375+
# Dirty Dirty here. Set buffer to cmap mode, grab image and set it back
376+
gl.cmode()
377+
gl.gconfig()
378+
gl.pixmode(GL.PM_SIZE, 8)
379+
data = gl.lrectread(0, 0, w-1, h-1)
380+
data = data[:w*h] # BUG FIX for python lrectread
381+
gl.RGBmode()
382+
gl.gconfig()
383+
gl.pixmode(GL.PM_SIZE, 32)
384+
return data, None
385+
386+
def grab_grey(w, h, pf):
387+
raise Error, 'Sorry, grabbing grey not implemented'
388+
389+
def grab_yiq(w, h, pf):
390+
raise Error, 'Sorry, grabbing yiq not implemented'
391+
392+
def grab_hls(w, h, pf):
393+
raise Error, 'Sorry, grabbing hls not implemented'
394+
395+
def grab_hsv(w, h, pf):
396+
raise Error, 'Sorry, grabbing hsv not implemented'
397+
398+
#
399+
# The class VoutFile is not as well-designed (and tested) as VinFile.
400+
# Notably it will accept almost any garbage and write it to the video
401+
# output file
402+
#
403+
class VoutFile():
404+
def init(self, filename):
405+
if filename == '-':
406+
return self.initfp(sys.stdout, filename)
407+
else:
408+
return self.initfp(open(filename,'w'), filename)
409+
410+
def initfp(self, fp, filename):
411+
self.fp = fp
412+
self.format = 'grey'
413+
self.width = self.height = 0
414+
self.packfactor = 1
415+
self.c0bits = 8
416+
self.c1bits = self.c2bits = 0
417+
self.offset = 0
418+
self.chrompack = 0
419+
self.headerwritten = 0
420+
return self
421+
422+
def close(self):
423+
self.fp.close()
424+
self.initfp(None, None)
425+
426+
def setinfo(self, values):
427+
self.format, self.width, self.height, self.packfactor,\
428+
self.c0bits, self.c1bits, self.c2bits, self.offset, \
429+
self.chrompack = values
430+
431+
def writeheader(self):
432+
self.headerwritten = 1
433+
if self.format == 'rgb':
434+
self.packfactor = 0
435+
elif self.packfactor == 0:
436+
self.packfactor = 1
437+
self.fp.write('CMIF video 3.0\n')
438+
if self.format == 'rgb':
439+
data = ('rgb', 0)
440+
elif self.format == 'grey':
441+
data = ('grey', 0)
442+
else:
443+
data = (self.format, (self.c0bits, self.c1bits, \
444+
self.c2bits, self.chrompack, self.offset))
445+
self.fp.write(`data`+'\n')
446+
data = (self.width, self.height, self.packfactor)
447+
self.fp.write(`data`+'\n')
448+
try:
449+
self._grabber = eval('grab_' + self.format)
450+
except:
451+
raise Error, 'unknown colorsys: ' + self.format
452+
453+
def writeframeheader(self, data):
454+
if not self.headerwritten:
455+
raise Error, 'Writing frame data before header'
456+
# XXXX Should we sanity check here?
457+
self.fp.write(`data`+'\n')
276458

459+
def writeframedata(self, data, chromdata):
460+
# XXXX Check sizes here
461+
self.fp.write(data)
462+
if chromdata:
463+
self.fp.write(chromdata)
277464

465+
def writeframe(self, time, data, chromdata):
466+
if chromdata:
467+
clen = len(chromdata)
468+
else:
469+
clen = 0
470+
self.writeframeheader((time, len(data), clen))
471+
self.writeframedata(data, chromdata)
472+
473+
def grabframe(self):
474+
return self._grabber(self.width, self.height, self.packfactor)
475+
278476
def test():
279477
import sys, time
280478
filename = 'film.video'
@@ -303,3 +501,4 @@ def test():
303501
vin.showframe(data, chromdata)
304502
print 'Done.'
305503
time.sleep(2)
504+

0 commit comments

Comments
 (0)