xref: /inferno-os/appl/lib/quicktime.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement QuickTime;
2*37da2899SCharles.Forsyth
3*37da2899SCharles.Forsythinclude "sys.m";
4*37da2899SCharles.Forsyth
5*37da2899SCharles.Forsythsys: Sys;
6*37da2899SCharles.Forsyth
7*37da2899SCharles.Forsythinclude "quicktime.m";
8*37da2899SCharles.Forsyth
9*37da2899SCharles.Forsythinit()
10*37da2899SCharles.Forsyth{
11*37da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
12*37da2899SCharles.Forsyth}
13*37da2899SCharles.Forsyth
14*37da2899SCharles.Forsythopen(file: string): (ref QD, string)
15*37da2899SCharles.Forsyth{
16*37da2899SCharles.Forsyth	fd := sys->open(file, sys->OREAD);
17*37da2899SCharles.Forsyth	if(fd == nil)
18*37da2899SCharles.Forsyth		return (nil, "open failed");
19*37da2899SCharles.Forsyth
20*37da2899SCharles.Forsyth	r := ref QD;
21*37da2899SCharles.Forsyth	r.fd = fd;
22*37da2899SCharles.Forsyth	r.buf = array[DEFBUF] of byte;
23*37da2899SCharles.Forsyth
24*37da2899SCharles.Forsyth	(hdr, l) := r.atomhdr();
25*37da2899SCharles.Forsyth	if(hdr != "mdat")
26*37da2899SCharles.Forsyth		return (nil, "not a QuickTime movie file");
27*37da2899SCharles.Forsyth
28*37da2899SCharles.Forsyth	#
29*37da2899SCharles.Forsyth	# We are expecting a unified file with .data then .rsrc
30*37da2899SCharles.Forsyth	#
31*37da2899SCharles.Forsyth	r.skipatom(l);
32*37da2899SCharles.Forsyth
33*37da2899SCharles.Forsyth	return (r, nil);
34*37da2899SCharles.Forsyth}
35*37da2899SCharles.Forsyth
36*37da2899SCharles.ForsythQD.atomhdr(r: self ref QD): (string, int)
37*37da2899SCharles.Forsyth{
38*37da2899SCharles.Forsyth	b := array[8] of byte;
39*37da2899SCharles.Forsyth
40*37da2899SCharles.Forsyth	if(r.readn(b, 8) != 8)
41*37da2899SCharles.Forsyth		return (nil, -1);
42*37da2899SCharles.Forsyth
43*37da2899SCharles.Forsythfor(i := 0; i < 8; i++)
44*37da2899SCharles.Forsythsys->print("%.2ux ", int b[i]);
45*37da2899SCharles.Forsythsys->print(" %s %d\n", string b[4:8], bedword(b, 0));
46*37da2899SCharles.Forsyth
47*37da2899SCharles.Forsyth	return (string b[4:8], bedword(b, 0));
48*37da2899SCharles.Forsyth}
49*37da2899SCharles.Forsyth
50*37da2899SCharles.ForsythQD.skipatom(r: self ref QD, l: int): int
51*37da2899SCharles.Forsyth{
52*37da2899SCharles.Forsyth	return r.skip(l - AtomHDR);
53*37da2899SCharles.Forsyth}
54*37da2899SCharles.Forsyth
55*37da2899SCharles.ForsythQD.mvhd(q: self ref QD, l: int): string
56*37da2899SCharles.Forsyth{
57*37da2899SCharles.Forsyth	l -= AtomHDR;
58*37da2899SCharles.Forsyth	if(l != MvhdrSIZE)
59*37da2899SCharles.Forsyth		return "mvhd atom funny size";
60*37da2899SCharles.Forsyth
61*37da2899SCharles.Forsyth	b := array[l] of byte;
62*37da2899SCharles.Forsyth	if(q.readn(b, l) != l)
63*37da2899SCharles.Forsyth		return "short read in mvhd";
64*37da2899SCharles.Forsyth
65*37da2899SCharles.Forsyth	mvhdr := ref Mvhdr;
66*37da2899SCharles.Forsyth
67*37da2899SCharles.Forsyth	mvhdr.version = bedword(b, 0);
68*37da2899SCharles.Forsyth	mvhdr.create = bedword(b, 4);
69*37da2899SCharles.Forsyth	mvhdr.modtime = bedword(b, 8);
70*37da2899SCharles.Forsyth	mvhdr.timescale = bedword(b, 12);
71*37da2899SCharles.Forsyth	mvhdr.duration = bedword(b, 16);
72*37da2899SCharles.Forsyth	mvhdr.rate = bedword(b, 20);
73*37da2899SCharles.Forsyth	mvhdr.vol = beword(b, 24);
74*37da2899SCharles.Forsyth	mvhdr.r1 = bedword(b, 26);
75*37da2899SCharles.Forsyth	mvhdr.r2 = bedword(b, 30);
76*37da2899SCharles.Forsyth
77*37da2899SCharles.Forsyth	mvhdr.matrix = array[9] of int;
78*37da2899SCharles.Forsyth	for(i :=0; i<9; i++)
79*37da2899SCharles.Forsyth		mvhdr.matrix[i] = bedword(b, 34+i*4);
80*37da2899SCharles.Forsyth
81*37da2899SCharles.Forsyth	mvhdr.r3 = beword(b, 70);
82*37da2899SCharles.Forsyth	mvhdr.r4 = bedword(b, 72);
83*37da2899SCharles.Forsyth	mvhdr.pvtime = bedword(b, 76);
84*37da2899SCharles.Forsyth	mvhdr.posttime = bedword(b, 80);
85*37da2899SCharles.Forsyth	mvhdr.seltime = bedword(b, 84);
86*37da2899SCharles.Forsyth	mvhdr.seldurat = bedword(b, 88);
87*37da2899SCharles.Forsyth	mvhdr.curtime = bedword(b, 92);
88*37da2899SCharles.Forsyth	mvhdr.nxttkid = bedword(b, 96);
89*37da2899SCharles.Forsyth
90*37da2899SCharles.Forsyth	q.mvhdr = mvhdr;
91*37da2899SCharles.Forsyth	return nil;
92*37da2899SCharles.Forsyth}
93*37da2899SCharles.Forsyth
94*37da2899SCharles.ForsythQD.trak(q: self ref QD, l: int): string
95*37da2899SCharles.Forsyth{
96*37da2899SCharles.Forsyth	(tk, tkl) := q.atomhdr();
97*37da2899SCharles.Forsyth	if(tk != "tkhd")
98*37da2899SCharles.Forsyth		return "missing track header atom";
99*37da2899SCharles.Forsyth
100*37da2899SCharles.Forsyth	l -= tkl;
101*37da2899SCharles.Forsyth	tkl -= AtomHDR;
102*37da2899SCharles.Forsyth	b := array[tkl] of byte;
103*37da2899SCharles.Forsyth	if(q.readn(b, tkl) != tkl)
104*37da2899SCharles.Forsyth		return "short read in tkhd";
105*37da2899SCharles.Forsyth
106*37da2899SCharles.Forsyth	tkhdr := ref Tkhdr;
107*37da2899SCharles.Forsyth
108*37da2899SCharles.Forsyth	tkhdr.version =	bedword(b, 0);
109*37da2899SCharles.Forsyth	tkhdr.creation = bedword(b, 4);
110*37da2899SCharles.Forsyth	tkhdr.modtime =	bedword(b, 8);
111*37da2899SCharles.Forsyth	tkhdr.trackid =	bedword(b, 12);
112*37da2899SCharles.Forsyth	tkhdr.timescale = bedword(b, 16);
113*37da2899SCharles.Forsyth	tkhdr.duration = bedword(b, 20);
114*37da2899SCharles.Forsyth	tkhdr.timeoff = bedword(b, 24);
115*37da2899SCharles.Forsyth	tkhdr.priority = bedword(b, 28);
116*37da2899SCharles.Forsyth	tkhdr.layer = beword(b, 32);
117*37da2899SCharles.Forsyth	tkhdr.altgrp = beword(b, 34);
118*37da2899SCharles.Forsyth	tkhdr.volume = beword(b, 36);
119*37da2899SCharles.Forsyth
120*37da2899SCharles.Forsyth	tkhdr.matrix = array[9] of int;
121*37da2899SCharles.Forsyth	for(i := 0; i < 9; i++)
122*37da2899SCharles.Forsyth		tkhdr.matrix[i] = bedword(b, 38+i*4);
123*37da2899SCharles.Forsyth
124*37da2899SCharles.Forsyth	tkhdr.width = bedword(b, 74);
125*37da2899SCharles.Forsyth	tkhdr.height = bedword(b, 78);
126*37da2899SCharles.Forsyth
127*37da2899SCharles.Forsyth	(md, mdl) := q.atomhdr();
128*37da2899SCharles.Forsyth	if(md != "mdia")
129*37da2899SCharles.Forsyth		return "missing media atom";
130*37da2899SCharles.Forsyth
131*37da2899SCharles.Forsyth	while(mdl != AtomHDR) {
132*37da2899SCharles.Forsyth		(atom, atoml) := q.atomhdr();
133*37da2899SCharles.Forsythsys->print("\t%s %d\n", atom, atoml);
134*37da2899SCharles.Forsyth		q.skipatom(atoml);
135*37da2899SCharles.Forsyth
136*37da2899SCharles.Forsyth		mdl -= atoml;
137*37da2899SCharles.Forsyth	}
138*37da2899SCharles.Forsyth
139*37da2899SCharles.Forsyth	return nil;
140*37da2899SCharles.Forsyth}
141*37da2899SCharles.Forsyth
142*37da2899SCharles.ForsythQD.readn(r: self ref QD, b: array of byte, l: int): int
143*37da2899SCharles.Forsyth{
144*37da2899SCharles.Forsyth	if(r.nbyte < l) {
145*37da2899SCharles.Forsyth		c := 0;
146*37da2899SCharles.Forsyth		if(r.nbyte != 0) {
147*37da2899SCharles.Forsyth			b[0:] = r.buf[r.ptr:];
148*37da2899SCharles.Forsyth			l -= r.nbyte;
149*37da2899SCharles.Forsyth			c += r.nbyte;
150*37da2899SCharles.Forsyth			b = b[r.nbyte:];
151*37da2899SCharles.Forsyth		}
152*37da2899SCharles.Forsyth		bsize := len r.buf;
153*37da2899SCharles.Forsyth		while(l != 0) {
154*37da2899SCharles.Forsyth			r.nbyte = sys->read(r.fd, r.buf, bsize);
155*37da2899SCharles.Forsyth			if(r.nbyte <= 0) {
156*37da2899SCharles.Forsyth				r.nbyte = 0;
157*37da2899SCharles.Forsyth				return -1;
158*37da2899SCharles.Forsyth			}
159*37da2899SCharles.Forsyth			n := l;
160*37da2899SCharles.Forsyth			if(n > bsize)
161*37da2899SCharles.Forsyth				n = bsize;
162*37da2899SCharles.Forsyth
163*37da2899SCharles.Forsyth			r.ptr = 0;
164*37da2899SCharles.Forsyth			b[0:] = r.buf[0:n];
165*37da2899SCharles.Forsyth			b = b[n:];
166*37da2899SCharles.Forsyth			r.nbyte -= n;
167*37da2899SCharles.Forsyth			r.ptr += n;
168*37da2899SCharles.Forsyth			l -= n;
169*37da2899SCharles.Forsyth			c += n;
170*37da2899SCharles.Forsyth		}
171*37da2899SCharles.Forsyth		return c;
172*37da2899SCharles.Forsyth	}
173*37da2899SCharles.Forsyth	b[0:] = r.buf[r.ptr:r.ptr+l];
174*37da2899SCharles.Forsyth	r.nbyte -= l;
175*37da2899SCharles.Forsyth	r.ptr += l;
176*37da2899SCharles.Forsyth	return l;
177*37da2899SCharles.Forsyth}
178*37da2899SCharles.Forsyth
179*37da2899SCharles.ForsythQD.skip(r: self ref QD, size: int): int
180*37da2899SCharles.Forsyth{
181*37da2899SCharles.Forsyth	if(r.nbyte != 0) {
182*37da2899SCharles.Forsyth		n := size;
183*37da2899SCharles.Forsyth		if(n > r.nbyte)
184*37da2899SCharles.Forsyth			n = r.nbyte;
185*37da2899SCharles.Forsyth		r.ptr += n;
186*37da2899SCharles.Forsyth		r.nbyte -= n;
187*37da2899SCharles.Forsyth		size -= n;
188*37da2899SCharles.Forsyth		if(size == 0)
189*37da2899SCharles.Forsyth			return 0;
190*37da2899SCharles.Forsyth	}
191*37da2899SCharles.Forsyth	return int sys->seek(r.fd, big size, sys->SEEKRELA);
192*37da2899SCharles.Forsyth}
193*37da2899SCharles.Forsyth
194*37da2899SCharles.Forsythbeword(b: array of byte, o: int): int
195*37da2899SCharles.Forsyth{
196*37da2899SCharles.Forsyth	return 	(int b[o] << 8) | int b[o+1];
197*37da2899SCharles.Forsyth}
198*37da2899SCharles.Forsyth
199*37da2899SCharles.Forsythbedword(b: array of byte, o: int): int
200*37da2899SCharles.Forsyth{
201*37da2899SCharles.Forsyth	return	(int b[o] << 24) |
202*37da2899SCharles.Forsyth		(int b[o+1] << 16) |
203*37da2899SCharles.Forsyth		(int b[o+2] << 8) |
204*37da2899SCharles.Forsyth		int b[o+3];
205*37da2899SCharles.Forsyth}
206