1*37da2899SCharles.Forsythimplement Riff; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsythinclude "sys.m"; 4*37da2899SCharles.Forsyth 5*37da2899SCharles.Forsythsys: Sys; 6*37da2899SCharles.Forsyth 7*37da2899SCharles.Forsythinclude "riff.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 RD, 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 RD; 21*37da2899SCharles.Forsyth r.fd = fd; 22*37da2899SCharles.Forsyth r.buf = array[DEFBUF] of byte; 23*37da2899SCharles.Forsyth r.ptr = 0; 24*37da2899SCharles.Forsyth r.nbyte = 0; 25*37da2899SCharles.Forsyth 26*37da2899SCharles.Forsyth (hdr, l) := r.gethdr(); 27*37da2899SCharles.Forsyth if(hdr != "RIFF") 28*37da2899SCharles.Forsyth return (nil, "not a RIFF file"); 29*37da2899SCharles.Forsyth 30*37da2899SCharles.Forsyth return (r, nil); 31*37da2899SCharles.Forsyth} 32*37da2899SCharles.Forsyth 33*37da2899SCharles.ForsythRD.gethdr(r: self ref RD): (string, int) 34*37da2899SCharles.Forsyth{ 35*37da2899SCharles.Forsyth b := array[8] of byte; 36*37da2899SCharles.Forsyth 37*37da2899SCharles.Forsyth if(r.readn(b, 8) != 8) 38*37da2899SCharles.Forsyth return (nil, -1); 39*37da2899SCharles.Forsyth 40*37da2899SCharles.Forsyth return (string b[0:4], ledword(b, 4)); 41*37da2899SCharles.Forsyth} 42*37da2899SCharles.Forsyth 43*37da2899SCharles.ForsythRD.check4(r: self ref RD, code: string): string 44*37da2899SCharles.Forsyth{ 45*37da2899SCharles.Forsyth b := array[4] of byte; 46*37da2899SCharles.Forsyth 47*37da2899SCharles.Forsyth if(r.readn(b, 4) != 4) 48*37da2899SCharles.Forsyth return "file i/o error"; 49*37da2899SCharles.Forsyth if(string b != code) 50*37da2899SCharles.Forsyth return "bad four code header information"; 51*37da2899SCharles.Forsyth return nil; 52*37da2899SCharles.Forsyth} 53*37da2899SCharles.Forsyth 54*37da2899SCharles.ForsythRD.avihdr(r: self ref RD): (ref AVIhdr, string) 55*37da2899SCharles.Forsyth{ 56*37da2899SCharles.Forsyth (s, l) := r.gethdr(); 57*37da2899SCharles.Forsyth if(s == nil || s != "avih") 58*37da2899SCharles.Forsyth return (nil, "missing/malformed avih"); 59*37da2899SCharles.Forsyth 60*37da2899SCharles.Forsyth b := array[AVImainhdr] of byte; 61*37da2899SCharles.Forsyth if(r.readn(b, AVImainhdr) != AVImainhdr) 62*37da2899SCharles.Forsyth return (nil, "short read in avih"); 63*37da2899SCharles.Forsyth 64*37da2899SCharles.Forsyth h := ref AVIhdr; 65*37da2899SCharles.Forsyth 66*37da2899SCharles.Forsyth h.usecperframe = ledword(b, 0); 67*37da2899SCharles.Forsyth h.bytesec = ledword(b, 4); 68*37da2899SCharles.Forsyth h.flag = ledword(b, 12); 69*37da2899SCharles.Forsyth h.frames = ledword(b, 16); 70*37da2899SCharles.Forsyth h.initframes = ledword(b, 20); 71*37da2899SCharles.Forsyth h.streams = ledword(b, 24); 72*37da2899SCharles.Forsyth h.bufsize = ledword(b, 28); 73*37da2899SCharles.Forsyth h.width = ledword(b, 32); 74*37da2899SCharles.Forsyth h.height = ledword(b, 36); 75*37da2899SCharles.Forsyth 76*37da2899SCharles.Forsyth return (h, nil); 77*37da2899SCharles.Forsyth} 78*37da2899SCharles.Forsyth 79*37da2899SCharles.ForsythRD.streaminfo(r: self ref RD): (ref AVIstream, string) 80*37da2899SCharles.Forsyth{ 81*37da2899SCharles.Forsyth (h, l) := r.gethdr(); 82*37da2899SCharles.Forsyth if(h != "LIST") 83*37da2899SCharles.Forsyth return (nil, "streaminfo expected LIST"); 84*37da2899SCharles.Forsyth 85*37da2899SCharles.Forsyth err := r.check4("strl"); 86*37da2899SCharles.Forsyth if(err != nil) 87*37da2899SCharles.Forsyth return (nil, err); 88*37da2899SCharles.Forsyth 89*37da2899SCharles.Forsyth (strh, sl) := r.gethdr(); 90*37da2899SCharles.Forsyth if(strh != "strh") 91*37da2899SCharles.Forsyth return (nil, "streaminfo expected strh"); 92*37da2899SCharles.Forsyth 93*37da2899SCharles.Forsyth b := array[sl] of byte; 94*37da2899SCharles.Forsyth if(r.readn(b, sl) != sl) 95*37da2899SCharles.Forsyth return (nil, "streaminfo strl short read"); 96*37da2899SCharles.Forsyth 97*37da2899SCharles.Forsyth s := ref AVIstream; 98*37da2899SCharles.Forsyth 99*37da2899SCharles.Forsyth s.stype = string b[0:4]; 100*37da2899SCharles.Forsyth s.handler = string b[4:8]; 101*37da2899SCharles.Forsyth s.flags = ledword(b, 8); 102*37da2899SCharles.Forsyth s.priority = ledword(b, 12); 103*37da2899SCharles.Forsyth s.initframes = ledword(b, 16); 104*37da2899SCharles.Forsyth s.scale = ledword(b, 20); 105*37da2899SCharles.Forsyth s.rate = ledword(b, 24); 106*37da2899SCharles.Forsyth s.start = ledword(b, 28); 107*37da2899SCharles.Forsyth s.length = ledword(b, 32); 108*37da2899SCharles.Forsyth s.bufsize = ledword(b, 36); 109*37da2899SCharles.Forsyth s.quality = ledword(b, 40); 110*37da2899SCharles.Forsyth s.samplesz = ledword(b, 44); 111*37da2899SCharles.Forsyth 112*37da2899SCharles.Forsyth (strf, sf) := r.gethdr(); 113*37da2899SCharles.Forsyth if(strf != "strf") 114*37da2899SCharles.Forsyth return (nil, "streaminfo expected strf"); 115*37da2899SCharles.Forsyth 116*37da2899SCharles.Forsyth s.fmt = array[sf] of byte; 117*37da2899SCharles.Forsyth if(r.readn(s.fmt, sf) != sf) 118*37da2899SCharles.Forsyth return (nil, "streaminfo strf short read"); 119*37da2899SCharles.Forsyth 120*37da2899SCharles.Forsyth return (s, nil); 121*37da2899SCharles.Forsyth} 122*37da2899SCharles.Forsyth 123*37da2899SCharles.ForsythRD.readn(r: self ref RD, b: array of byte, l: int): int 124*37da2899SCharles.Forsyth{ 125*37da2899SCharles.Forsyth if(r.nbyte < l) { 126*37da2899SCharles.Forsyth c := 0; 127*37da2899SCharles.Forsyth if(r.nbyte != 0) { 128*37da2899SCharles.Forsyth b[0:] = r.buf[r.ptr:]; 129*37da2899SCharles.Forsyth l -= r.nbyte; 130*37da2899SCharles.Forsyth c += r.nbyte; 131*37da2899SCharles.Forsyth b = b[r.nbyte:]; 132*37da2899SCharles.Forsyth } 133*37da2899SCharles.Forsyth bsize := len r.buf; 134*37da2899SCharles.Forsyth while(l != 0) { 135*37da2899SCharles.Forsyth r.nbyte = sys->read(r.fd, r.buf, bsize); 136*37da2899SCharles.Forsyth if(r.nbyte <= 0) { 137*37da2899SCharles.Forsyth r.nbyte = 0; 138*37da2899SCharles.Forsyth return -1; 139*37da2899SCharles.Forsyth } 140*37da2899SCharles.Forsyth n := l; 141*37da2899SCharles.Forsyth if(n > bsize) 142*37da2899SCharles.Forsyth n = bsize; 143*37da2899SCharles.Forsyth 144*37da2899SCharles.Forsyth r.ptr = 0; 145*37da2899SCharles.Forsyth b[0:] = r.buf[0:n]; 146*37da2899SCharles.Forsyth b = b[n:]; 147*37da2899SCharles.Forsyth r.nbyte -= n; 148*37da2899SCharles.Forsyth r.ptr += n; 149*37da2899SCharles.Forsyth l -= n; 150*37da2899SCharles.Forsyth c += n; 151*37da2899SCharles.Forsyth } 152*37da2899SCharles.Forsyth return c; 153*37da2899SCharles.Forsyth } 154*37da2899SCharles.Forsyth b[0:] = r.buf[r.ptr:r.ptr+l]; 155*37da2899SCharles.Forsyth r.nbyte -= l; 156*37da2899SCharles.Forsyth r.ptr += l; 157*37da2899SCharles.Forsyth return l; 158*37da2899SCharles.Forsyth} 159*37da2899SCharles.Forsyth 160*37da2899SCharles.ForsythRD.skip(r: self ref RD, size: int): int 161*37da2899SCharles.Forsyth{ 162*37da2899SCharles.Forsyth if(r.nbyte != 0) { 163*37da2899SCharles.Forsyth n := size; 164*37da2899SCharles.Forsyth if(n > r.nbyte) 165*37da2899SCharles.Forsyth n = r.nbyte; 166*37da2899SCharles.Forsyth r.ptr += n; 167*37da2899SCharles.Forsyth r.nbyte -= n; 168*37da2899SCharles.Forsyth size -= n; 169*37da2899SCharles.Forsyth if(size == 0) 170*37da2899SCharles.Forsyth return 0; 171*37da2899SCharles.Forsyth } 172*37da2899SCharles.Forsyth return int sys->seek(r.fd, big size, sys->SEEKRELA); 173*37da2899SCharles.Forsyth} 174*37da2899SCharles.Forsyth 175*37da2899SCharles.ForsythAVIstream.fmt2binfo(a: self ref AVIstream): string 176*37da2899SCharles.Forsyth{ 177*37da2899SCharles.Forsyth if(len a.fmt < Binfosize) 178*37da2899SCharles.Forsyth return "format is wrong size for BITMAPINFO"; 179*37da2899SCharles.Forsyth 180*37da2899SCharles.Forsyth b := ref Bitmapinfo; 181*37da2899SCharles.Forsyth 182*37da2899SCharles.Forsyth # Pull out the bitmap info 183*37da2899SCharles.Forsyth b.width = ledword(a.fmt, 4); 184*37da2899SCharles.Forsyth b.height = ledword(a.fmt, 8); 185*37da2899SCharles.Forsyth b.planes = leword(a.fmt, 12); 186*37da2899SCharles.Forsyth b.bitcount = leword(a.fmt, 14); 187*37da2899SCharles.Forsyth b.compression = ledword(a.fmt, 16); 188*37da2899SCharles.Forsyth b.sizeimage = ledword(a.fmt, 20); 189*37da2899SCharles.Forsyth b.xpelpermeter = ledword(a.fmt, 24); 190*37da2899SCharles.Forsyth b.ypelpermeter = ledword(a.fmt, 28); 191*37da2899SCharles.Forsyth b.clrused = ledword(a.fmt, 32); 192*37da2899SCharles.Forsyth b.clrimportant = ledword(a.fmt, 36); 193*37da2899SCharles.Forsyth 194*37da2899SCharles.Forsyth # Parse out the color map 195*37da2899SCharles.Forsyth ncolor := len a.fmt - Binfosize; 196*37da2899SCharles.Forsyth if(ncolor & 3) 197*37da2899SCharles.Forsyth return "wrong size color map"; 198*37da2899SCharles.Forsyth ncolor /= 4; 199*37da2899SCharles.Forsyth 200*37da2899SCharles.Forsyth b.cmap = array[ncolor] of RGB; 201*37da2899SCharles.Forsyth idx := 40; 202*37da2899SCharles.Forsyth for(i := 0; i < ncolor; i++) { 203*37da2899SCharles.Forsyth b.cmap[i].r = int a.fmt[idx+2]; 204*37da2899SCharles.Forsyth b.cmap[i].g = int a.fmt[idx+1]; 205*37da2899SCharles.Forsyth b.cmap[i].b = int a.fmt[idx+0]; 206*37da2899SCharles.Forsyth idx += 4; 207*37da2899SCharles.Forsyth } 208*37da2899SCharles.Forsyth 209*37da2899SCharles.Forsyth a.fmt = nil; 210*37da2899SCharles.Forsyth a.binfo = b; 211*37da2899SCharles.Forsyth return nil; 212*37da2899SCharles.Forsyth} 213*37da2899SCharles.Forsyth 214*37da2899SCharles.Forsythleword(b: array of byte, o: int): int 215*37da2899SCharles.Forsyth{ 216*37da2899SCharles.Forsyth return (int b[o+1] << 8) | int b[o]; 217*37da2899SCharles.Forsyth} 218*37da2899SCharles.Forsyth 219*37da2899SCharles.Forsythledword(b: array of byte, o: int): int 220*37da2899SCharles.Forsyth{ 221*37da2899SCharles.Forsyth return (int b[o+3] << 24) | 222*37da2899SCharles.Forsyth (int b[o+2] << 16) | 223*37da2899SCharles.Forsyth (int b[o+1] << 8) | 224*37da2899SCharles.Forsyth int b[o]; 225*37da2899SCharles.Forsyth} 226