implement Mpegd; include "sys.m";include "mpegio.m"; sys: Sys;idct: IDCT; Mpegi, Picture, Slice, MacroBlock, YCbCr, Pair: import Mpegio; intra_tab := array[64] of { 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83,}; nintra_tab := array[64] of { * => 16 }; CLOFF: con 256; intraQ, nintraQ: array of int;rtmp: array of array of int;rflag := array[6] of int;rforw, dforw, rback, dback: int;rforw2, dforw2, rback2, dback2: int;ydb, ydf, cdb, cdf: int;vflags: int;past := array[3] of int;pinit := array[3] of { * => 128 * 8 };zeros := array[64] of { * => 0 };zeros1: array of int;clamp := array[CLOFF + 256 + CLOFF] of byte;width, height, w2, h2: int;mpi, mps, yadj, cadj, yskip: int;I, B0: ref YCbCr;Ps := array[2] of ref YCbCr;Rs := array[2] of ref YCbCr;P, B, R, M, N: ref YCbCr;pn: int = 0;rn: int = 0; zig := array[64] of { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63,}; init(m: ref Mpegi){ sys = load Sys Sys->PATH; idct = load IDCT IDCT->PATH; if (idct == nil) { sys->print("could not open %s: %r\n", IDCT->PATH); exit; } idct->init(); width = m.width; height = m.height; w2 = width >> 1; h2 = height >> 1; mps = width >> 4; mpi = mps * height >> 4; yskip = 8 * width; yadj = 16 * width - (width - 16); cadj = 8 * w2 - (w2 - 8); I = frame(); Ps[0] = frame(); Ps[1] = frame(); Rs[0] = Ps[0]; Rs[1] = Ps[1]; B0 = frame(); for (i := 0; i < CLOFF; i++) clamp[i] = byte 0; for (i = 0; i < 256; i++) clamp[i + CLOFF] = byte i; for (i = CLOFF + 256; i < CLOFF + 256 + CLOFF; i++) clamp[i] = byte 255; if (m.intra == nil) intraQ = intra_tab; else intraQ = zigof(m.intra); if (m.nintra == nil) nintraQ = nintra_tab; else nintraQ = zigof(m.nintra); rtmp = array[6] of array of int; for (i = 0; i < 6; i++) rtmp[i] = array[64] of int; zeros1 = zeros[1:];} zarray(n: int, v: byte): array of byte{ return array[n] of { * => v };} frame(): ref YCbCr{ y := zarray(width * height, byte 0); b := zarray(w2 * h2, byte 128); r := zarray(w2 * h2, byte 128); return ref YCbCr(y, b, r);} zigof(a: array of int): array of int{ z := array[64] of int; for (i := 0; i < 64; i++) z[zig[i]] = a[i]; return z;} invQ_intra(a: array of Pair, q: int, b: array of int){ (nil, t) := a[0]; b[0] = t * 8; b[1:] = zeros1; n := 1; i := 1; while (n < len a) { (r, l) := a[n++]; i += r; x := zig[i++]; if (l > 0) { v := l * q * intraQ[x] >> 3; if (v > 2047) b[x] = 2047; else b[x] = (v - 1) | 1; } else { v := (l * q * intraQ[x] + 7) >> 3; if (v < -2048) b[x] = -2048; else b[x] = v | 1; } #sys->print("%d %d %d %d\n", x, r, l, b[x]); }} invQ_nintra(a: array of Pair, q: int, b: array of int){ b[0:] = zeros; i := 0; for (n := 0; n < len a; n++) { (r, l) := a[n]; i += r; if (l == 0) { raisex("zero level"); i++; continue; } x := zig[i++]; if (l > 0) { v := ((l << 1) + 1) * q * nintraQ[x] >> 4; if (v > 2047) b[x] = 2047; else b[x] = (v - 1) | 1; } else { v := (((l << 1) - 1) * q * nintraQ[x] + 15) >> 4; if (v < -2048) b[x] = -2048; else b[x] = v | 1; } #sys->print("%d %d %d %d\n", x, r, l, b[x]); }} yzero(v: array of byte, base: int){ x := 0; i := 8; do { n := base; j := 8; do v[n++] = byte 0; while (--j > 0); base += width; } while (--i > 0);} czero(v: array of byte, base: int){ x := 0; i := 8; do { n := base; j := 8; do v[n++] = byte 128; while (--j > 0); base += w2; } while (--i > 0); } blockzero(d: ref YCbCr){ yzero(d.Y, ybase); yzero(d.Y, ybase + 8); yzero(d.Y, ybase + yskip); yzero(d.Y, ybase + 8 + yskip); czero(d.Cb, cbase); czero(d.Cr, cbase);} ydistr(a: array of int, v: array of byte, base: int){ x := 0; i := 8; do { n := base; j := 8; do v[n++] = clamp[a[x++] + CLOFF]; while (--j > 0); base += width; } while (--i > 0);} cdistr(a: array of int, v: array of byte, base: int){ x := 0; i := 8; do { n := base; j := 8; do v[n++] = clamp[a[x++] + CLOFF]; while (--j > 0); base += w2; } while (--i > 0); } invQ_intra_block(b: array of array of Pair, q: int, pred: int, d: ref YCbCr){ a, dc: array of int; if (pred) dc = past; else dc = pinit; p := dc[0]; for (i := 0; i < 4; i++) { a = rtmp[i]; #sys->print("%d\n", i); invQ_intra(b[i], q, a); p += a[0]; a[0] = p; #sys->print("%d\n", a[0]); idct->idct(a); } past[0] = p; for (i = 4; i < 6; i++) { p = dc[i - 3]; a = rtmp[i]; #sys->print("%d\n", i); invQ_intra(b[i], q, a); p += a[0]; a[0] = p; #sys->print("%d\n", a[0]); past[i - 3] = p; idct->idct(a); } ydistr(rtmp[0], d.Y, ybase); ydistr(rtmp[1], d.Y, ybase + 8); ydistr(rtmp[2], d.Y, ybase + yskip); ydistr(rtmp[3], d.Y, ybase + 8 + yskip); cdistr(rtmp[4], d.Cb, cbase); cdistr(rtmp[5], d.Cr, cbase);} invQ_nintra_block(b: array of array of Pair, q: int){ for (i := 0; i < 6; i++) { p := b[i]; if (p != nil) { a := rtmp[i]; #sys->print("%d\n", i); invQ_nintra(p, q, a); idct->idct(a); rflag[i] = 1; } else rflag[i] = 0; }} mbr, ybase, cbase: int; nextmb(){ if (--mbr == 0) { ybase += yadj; cbase += cadj; mbr = mps; } else { ybase += 16; cbase += 8; }} copyblock(s, d: array of byte, b, n, w: int){ i := 8; do { d[b:] = s[b:b+n]; b += w; } while (--i > 0);} copyblockdisp(s, d: array of byte, b, n, w, p: int){ i := 8; p += b; do { d[b:] = s[p:p+n]; b += w; p += w; } while (--i > 0);} interpblock(s0, s1, d: array of byte, b, n, w, p0, p1: int){ i := 8; do { dx := b; s0x := b + p0; s1x := b + p1; j := n; do d[dx++] = byte ((int s0[s0x++] + int s1[s1x++] + 1) >> 1); while (--j > 0); b += w; } while (--i > 0);} deltablock(s: array of byte, r: array of int, d: array of byte, b, w, o: int){ rx := 0; i := 8; do { dx := b; sx := b + o; j := 8; do d[dx++] = clamp[CLOFF + int s[sx++] + r[rx++]]; while (--j > 0); b += w; } while (--i > 0);} deltainterpblock(s0, s1: array of byte, r: array of int, d: array of byte, b, w, o0, o1: int){ rx := 0; i := 8; do { dx := b; s0x := b + o0; s1x := b + o1; j := 8; do d[dx++] = clamp[CLOFF + ((int s0[s0x++] + int s1[s1x++] + 1) >> 1) + r[rx++]]; while (--j > 0); b += w; } while (--i > 0);} dispblock(s, d: array of byte, n, b, w, o: int){ if (rflag[n]) deltablock(s, rtmp[n], d, b, w, o); else copyblockdisp(s, d, b, 8, w, o);} genblock(s0, s1, d: array of byte, n, b, w, o0, o1: int){ if (rflag[n]) deltainterpblock(s0, s1, rtmp[n], d, b, w, o0, o1); else interpblock(s0, s1, d, b, 8, w, o0, o1);} copymb(){ copyblock(R.Y, P.Y, ybase, 16, width); copyblock(R.Y, P.Y, ybase + yskip, 16, width); copyblock(R.Cb, P.Cb, cbase, 8, w2); copyblock(R.Cr, P.Cr, cbase, 8, w2);} deltamb(){ dispblock(R.Y, P.Y, 0, ybase, width, 0); dispblock(R.Y, P.Y, 1, ybase + 8, width, 0); dispblock(R.Y, P.Y, 2, ybase + yskip, width, 0); dispblock(R.Y, P.Y, 3, ybase + 8 + yskip, width, 0); dispblock(R.Cb, P.Cb, 4, cbase, w2, 0); dispblock(R.Cr, P.Cr, 5, cbase, w2, 0);} copymbforw(){ copyblockdisp(N.Y, B.Y, ybase, 16, width, ydf); copyblockdisp(N.Y, B.Y, ybase + yskip, 16, width, ydf); copyblockdisp(N.Cb, B.Cb, cbase, 8, w2, cdf); copyblockdisp(N.Cr, B.Cr, cbase, 8, w2, cdf);} copymbback(){ copyblockdisp(M.Y, B.Y, ybase, 16, width, ydb); copyblockdisp(M.Y, B.Y, ybase + yskip, 16, width, ydb); copyblockdisp(M.Cb, B.Cb, cbase, 8, w2, cdb); copyblockdisp(M.Cr, B.Cr, cbase, 8, w2, cdb);} copymbbackforw(){ interpblock(M.Y, N.Y, B.Y, ybase, 16, width, ydb, ydf); interpblock(M.Y, N.Y, B.Y, ybase + yskip, 16, width, ydb, ydf); interpblock(M.Cb, N.Cb, B.Cb, cbase, 8, w2, cdb, cdf); interpblock(M.Cr, N.Cr, B.Cr, cbase, 8, w2, cdb, cdf);} deltambforw(){ dispblock(N.Y, B.Y, 0, ybase, width, ydf); dispblock(N.Y, B.Y, 1, ybase + 8, width, ydf); dispblock(N.Y, B.Y, 2, ybase + yskip, width, ydf); dispblock(N.Y, B.Y, 3, ybase + 8 + yskip, width, ydf); dispblock(N.Cb, B.Cb, 4, cbase, w2, cdf); dispblock(N.Cr, B.Cr, 5, cbase, w2, cdf);} deltambback(){ dispblock(M.Y, B.Y, 0, ybase, width, ydb); dispblock(M.Y, B.Y, 1, ybase + 8, width, ydb); dispblock(M.Y, B.Y, 2, ybase + yskip, width, ydb); dispblock(M.Y, B.Y, 3, ybase + 8 + yskip, width, ydb); dispblock(M.Cb, B.Cb, 4, cbase, w2, cdb); dispblock(M.Cr, B.Cr, 5, cbase, w2, cdb);} deltambbackforw(){ genblock(M.Y, N.Y, B.Y, 0, ybase, width, ydb, ydf); genblock(M.Y, N.Y, B.Y, 1, ybase + 8, width, ydb, ydf); genblock(M.Y, N.Y, B.Y, 2, ybase + yskip, width, ydb, ydf); genblock(M.Y, N.Y, B.Y, 3, ybase + 8 + yskip, width, ydb, ydf); genblock(M.Cb, N.Cb, B.Cb, 4, cbase, w2, cdb, cdf); genblock(M.Cr, N.Cr, B.Cr, 5, cbase, w2, cdb, cdf);} deltambinterp(){ case vflags & (Mpegio->MB_MF | Mpegio->MB_MB) { Mpegio->MB_MF => deltambforw(); Mpegio->MB_MB => deltambback(); Mpegio->MB_MF | Mpegio->MB_MB => deltambbackforw(); * => raisex("bad vflags"); }} interpmb(){ case vflags & (Mpegio->MB_MF | Mpegio->MB_MB) { Mpegio->MB_MF => copymbforw(); Mpegio->MB_MB => copymbback(); Mpegio->MB_MF | Mpegio->MB_MB => copymbbackforw(); * => raisex("bad vflags"); }} Idecode(p: ref Picture): ref YCbCr{ sa := p.slices; n := 0;Lines 1–500 of 831. Load more
implement Mpegd; include "sys.m"; include "mpegio.m"; sys: Sys; idct: IDCT; Mpegi, Picture, Slice, MacroBlock, YCbCr, Pair: import Mpegio; intra_tab := array[64] of { 8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37, 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40, 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58, 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83, }; nintra_tab := array[64] of { * => 16 }; CLOFF: con 256; intraQ, nintraQ: array of int; rtmp: array of array of int; rflag := array[6] of int; rforw, dforw, rback, dback: int; rforw2, dforw2, rback2, dback2: int; ydb, ydf, cdb, cdf: int; vflags: int; past := array[3] of int; pinit := array[3] of { * => 128 * 8 }; zeros := array[64] of { * => 0 }; zeros1: array of int; clamp := array[CLOFF + 256 + CLOFF] of byte; width, height, w2, h2: int; mpi, mps, yadj, cadj, yskip: int; I, B0: ref YCbCr; Ps := array[2] of ref YCbCr; Rs := array[2] of ref YCbCr; P, B, R, M, N: ref YCbCr; pn: int = 0; rn: int = 0; zig := array[64] of { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, }; init(m: ref Mpegi) { sys = load Sys Sys->PATH; idct = load IDCT IDCT->PATH; if (idct == nil) { sys->print("could not open %s: %r\n", IDCT->PATH); exit; } idct->init(); width = m.width; height = m.height; w2 = width >> 1; h2 = height >> 1; mps = width >> 4; mpi = mps * height >> 4; yskip = 8 * width; yadj = 16 * width - (width - 16); cadj = 8 * w2 - (w2 - 8); I = frame(); Ps[0] = frame(); Ps[1] = frame(); Rs[0] = Ps[0]; Rs[1] = Ps[1]; B0 = frame(); for (i := 0; i < CLOFF; i++) clamp[i] = byte 0; for (i = 0; i < 256; i++) clamp[i + CLOFF] = byte i; for (i = CLOFF + 256; i < CLOFF + 256 + CLOFF; i++) clamp[i] = byte 255; if (m.intra == nil) intraQ = intra_tab; else intraQ = zigof(m.intra); if (m.nintra == nil) nintraQ = nintra_tab; else nintraQ = zigof(m.nintra); rtmp = array[6] of array of int; for (i = 0; i < 6; i++) rtmp[i] = array[64] of int; zeros1 = zeros[1:]; } zarray(n: int, v: byte): array of byte { return array[n] of { * => v }; } frame(): ref YCbCr { y := zarray(width * height, byte 0); b := zarray(w2 * h2, byte 128); r := zarray(w2 * h2, byte 128); return ref YCbCr(y, b, r); } zigof(a: array of int): array of int { z := array[64] of int; for (i := 0; i < 64; i++) z[zig[i]] = a[i]; return z; } invQ_intra(a: array of Pair, q: int, b: array of int) { (nil, t) := a[0]; b[0] = t * 8; b[1:] = zeros1; n := 1; i := 1; while (n < len a) { (r, l) := a[n++]; i += r; x := zig[i++]; if (l > 0) { v := l * q * intraQ[x] >> 3; if (v > 2047) b[x] = 2047; else b[x] = (v - 1) | 1; } else { v := (l * q * intraQ[x] + 7) >> 3; if (v < -2048) b[x] = -2048; else b[x] = v | 1; } #sys->print("%d %d %d %d\n", x, r, l, b[x]); } } invQ_nintra(a: array of Pair, q: int, b: array of int) { b[0:] = zeros; i := 0; for (n := 0; n < len a; n++) { (r, l) := a[n]; i += r; if (l == 0) { raisex("zero level"); i++; continue; } x := zig[i++]; if (l > 0) { v := ((l << 1) + 1) * q * nintraQ[x] >> 4; if (v > 2047) b[x] = 2047; else b[x] = (v - 1) | 1; } else { v := (((l << 1) - 1) * q * nintraQ[x] + 15) >> 4; if (v < -2048) b[x] = -2048; else b[x] = v | 1; } #sys->print("%d %d %d %d\n", x, r, l, b[x]); } } yzero(v: array of byte, base: int) { x := 0; i := 8; do { n := base; j := 8; do v[n++] = byte 0; while (--j > 0); base += width; } while (--i > 0); } czero(v: array of byte, base: int) { x := 0; i := 8; do { n := base; j := 8; do v[n++] = byte 128; while (--j > 0); base += w2; } while (--i > 0); } blockzero(d: ref YCbCr) { yzero(d.Y, ybase); yzero(d.Y, ybase + 8); yzero(d.Y, ybase + yskip); yzero(d.Y, ybase + 8 + yskip); czero(d.Cb, cbase); czero(d.Cr, cbase); } ydistr(a: array of int, v: array of byte, base: int) { x := 0; i := 8; do { n := base; j := 8; do v[n++] = clamp[a[x++] + CLOFF]; while (--j > 0); base += width; } while (--i > 0); } cdistr(a: array of int, v: array of byte, base: int) { x := 0; i := 8; do { n := base; j := 8; do v[n++] = clamp[a[x++] + CLOFF]; while (--j > 0); base += w2; } while (--i > 0); } invQ_intra_block(b: array of array of Pair, q: int, pred: int, d: ref YCbCr) { a, dc: array of int; if (pred) dc = past; else dc = pinit; p := dc[0]; for (i := 0; i < 4; i++) { a = rtmp[i]; #sys->print("%d\n", i); invQ_intra(b[i], q, a); p += a[0]; a[0] = p; #sys->print("%d\n", a[0]); idct->idct(a); } past[0] = p; for (i = 4; i < 6; i++) { p = dc[i - 3]; a = rtmp[i]; #sys->print("%d\n", i); invQ_intra(b[i], q, a); p += a[0]; a[0] = p; #sys->print("%d\n", a[0]); past[i - 3] = p; idct->idct(a); } ydistr(rtmp[0], d.Y, ybase); ydistr(rtmp[1], d.Y, ybase + 8); ydistr(rtmp[2], d.Y, ybase + yskip); ydistr(rtmp[3], d.Y, ybase + 8 + yskip); cdistr(rtmp[4], d.Cb, cbase); cdistr(rtmp[5], d.Cr, cbase); } invQ_nintra_block(b: array of array of Pair, q: int) { for (i := 0; i < 6; i++) { p := b[i]; if (p != nil) { a := rtmp[i]; #sys->print("%d\n", i); invQ_nintra(p, q, a); idct->idct(a); rflag[i] = 1; } else rflag[i] = 0; } } mbr, ybase, cbase: int; nextmb() { if (--mbr == 0) { ybase += yadj; cbase += cadj; mbr = mps; } else { ybase += 16; cbase += 8; } } copyblock(s, d: array of byte, b, n, w: int) { i := 8; do { d[b:] = s[b:b+n]; b += w; } while (--i > 0); } copyblockdisp(s, d: array of byte, b, n, w, p: int) { i := 8; p += b; do { d[b:] = s[p:p+n]; b += w; p += w; } while (--i > 0); } interpblock(s0, s1, d: array of byte, b, n, w, p0, p1: int) { i := 8; do { dx := b; s0x := b + p0; s1x := b + p1; j := n; do d[dx++] = byte ((int s0[s0x++] + int s1[s1x++] + 1) >> 1); while (--j > 0); b += w; } while (--i > 0); } deltablock(s: array of byte, r: array of int, d: array of byte, b, w, o: int) { rx := 0; i := 8; do { dx := b; sx := b + o; j := 8; do d[dx++] = clamp[CLOFF + int s[sx++] + r[rx++]]; while (--j > 0); b += w; } while (--i > 0); } deltainterpblock(s0, s1: array of byte, r: array of int, d: array of byte, b, w, o0, o1: int) { rx := 0; i := 8; do { dx := b; s0x := b + o0; s1x := b + o1; j := 8; do d[dx++] = clamp[CLOFF + ((int s0[s0x++] + int s1[s1x++] + 1) >> 1) + r[rx++]]; while (--j > 0); b += w; } while (--i > 0); } dispblock(s, d: array of byte, n, b, w, o: int) { if (rflag[n]) deltablock(s, rtmp[n], d, b, w, o); else copyblockdisp(s, d, b, 8, w, o); } genblock(s0, s1, d: array of byte, n, b, w, o0, o1: int) { if (rflag[n]) deltainterpblock(s0, s1, rtmp[n], d, b, w, o0, o1); else interpblock(s0, s1, d, b, 8, w, o0, o1); } copymb() { copyblock(R.Y, P.Y, ybase, 16, width); copyblock(R.Y, P.Y, ybase + yskip, 16, width); copyblock(R.Cb, P.Cb, cbase, 8, w2); copyblock(R.Cr, P.Cr, cbase, 8, w2); } deltamb() { dispblock(R.Y, P.Y, 0, ybase, width, 0); dispblock(R.Y, P.Y, 1, ybase + 8, width, 0); dispblock(R.Y, P.Y, 2, ybase + yskip, width, 0); dispblock(R.Y, P.Y, 3, ybase + 8 + yskip, width, 0); dispblock(R.Cb, P.Cb, 4, cbase, w2, 0); dispblock(R.Cr, P.Cr, 5, cbase, w2, 0); } copymbforw() { copyblockdisp(N.Y, B.Y, ybase, 16, width, ydf); copyblockdisp(N.Y, B.Y, ybase + yskip, 16, width, ydf); copyblockdisp(N.Cb, B.Cb, cbase, 8, w2, cdf); copyblockdisp(N.Cr, B.Cr, cbase, 8, w2, cdf); } copymbback() { copyblockdisp(M.Y, B.Y, ybase, 16, width, ydb); copyblockdisp(M.Y, B.Y, ybase + yskip, 16, width, ydb); copyblockdisp(M.Cb, B.Cb, cbase, 8, w2, cdb); copyblockdisp(M.Cr, B.Cr, cbase, 8, w2, cdb); } copymbbackforw() { interpblock(M.Y, N.Y, B.Y, ybase, 16, width, ydb, ydf); interpblock(M.Y, N.Y, B.Y, ybase + yskip, 16, width, ydb, ydf); interpblock(M.Cb, N.Cb, B.Cb, cbase, 8, w2, cdb, cdf); interpblock(M.Cr, N.Cr, B.Cr, cbase, 8, w2, cdb, cdf); } deltambforw() { dispblock(N.Y, B.Y, 0, ybase, width, ydf); dispblock(N.Y, B.Y, 1, ybase + 8, width, ydf); dispblock(N.Y, B.Y, 2, ybase + yskip, width, ydf); dispblock(N.Y, B.Y, 3, ybase + 8 + yskip, width, ydf); dispblock(N.Cb, B.Cb, 4, cbase, w2, cdf); dispblock(N.Cr, B.Cr, 5, cbase, w2, cdf); } deltambback() { dispblock(M.Y, B.Y, 0, ybase, width, ydb); dispblock(M.Y, B.Y, 1, ybase + 8, width, ydb); dispblock(M.Y, B.Y, 2, ybase + yskip, width, ydb); dispblock(M.Y, B.Y, 3, ybase + 8 + yskip, width, ydb); dispblock(M.Cb, B.Cb, 4, cbase, w2, cdb); dispblock(M.Cr, B.Cr, 5, cbase, w2, cdb); } deltambbackforw() { genblock(M.Y, N.Y, B.Y, 0, ybase, width, ydb, ydf); genblock(M.Y, N.Y, B.Y, 1, ybase + 8, width, ydb, ydf); genblock(M.Y, N.Y, B.Y, 2, ybase + yskip, width, ydb, ydf); genblock(M.Y, N.Y, B.Y, 3, ybase + 8 + yskip, width, ydb, ydf); genblock(M.Cb, N.Cb, B.Cb, 4, cbase, w2, cdb, cdf); genblock(M.Cr, N.Cr, B.Cr, 5, cbase, w2, cdb, cdf); } deltambinterp() { case vflags & (Mpegio->MB_MF | Mpegio->MB_MB) { Mpegio->MB_MF => deltambforw(); Mpegio->MB_MB => deltambback(); Mpegio->MB_MF | Mpegio->MB_MB => deltambbackforw(); * => raisex("bad vflags"); } } interpmb() { case vflags & (Mpegio->MB_MF | Mpegio->MB_MB) { Mpegio->MB_MF => copymbforw(); Mpegio->MB_MB => copymbback(); Mpegio->MB_MF | Mpegio->MB_MB => copymbbackforw(); * => raisex("bad vflags"); } } Idecode(p: ref Picture): ref YCbCr { sa := p.slices; n := 0;