diff options
Diffstat (limited to 'appl/wm/mpeg/remap.b')
| -rw-r--r-- | appl/wm/mpeg/remap.b | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/appl/wm/mpeg/remap.b b/appl/wm/mpeg/remap.b new file mode 100644 index 00000000..4432048c --- /dev/null +++ b/appl/wm/mpeg/remap.b @@ -0,0 +1,128 @@ +implement Remap; + +include "sys.m"; +include "mpegio.m"; + +Mpegi, YCbCr: import Mpegio; + +CLOFF: con 255; + +width, height, w2, h2: int; +out: array of byte; +ered, egrn, eblu: array of int; +b0r1, b1, r0: array of int; +clamp := array[CLOFF + 256 + CLOFF] of int; +clamp16 := array[CLOFF + 256 + CLOFF] of int; + +init(m: ref Mpegi) +{ + width = m.width; + height = m.height; + w2 = width >> 1; + h2 = height >> 1; + out = array[width * height] of byte; + b0r1 = array[w2] of int; + b1 = array[w2] of int; + r0 = array[w2] of int; + ered = array[width + 1] of int; + egrn = array[width + 1] of int; + eblu = array[width + 1] of int; + for (i := 0; i < CLOFF; i++) { + clamp[i] = 0; + clamp16[i] = 0; + } + for (i = 0; i < 256; i++) { + clamp[i + CLOFF] = i; + clamp16[i + CLOFF] = i >> 4; + } + for (i = CLOFF + 256; i < CLOFF + 256 + CLOFF; i++) { + clamp[i] = 255; + clamp16[i] = 255 >> 4; + } +} + +include "closest.m"; +include "rgbvmap.m"; + +# rgb(y, cb, cr: int): (int, int, int) +# { +# Y := real y; +# Cb := real (cb - 128); +# Cr := real (cr - 128); +# r := int (Y+1.402*Cr); +# g := int (Y-0.34414*Cb-0.71414*Cr); +# b := int (Y+1.772*Cb); +# return (r, g, b); +# } + +B: con 16; +M: con (1 << B); +B0: con int (-0.34414 * real M); +B1: con int (1.772 * real M); +R0: con int (1.402 * real M); +R1: con int (-0.71414 * real M); + +remap(p: ref Mpegio->YCbCr): array of byte +{ + Y := p.Y; + Cb := p.Cb; + Cr := p.Cr; + for (e := 0; e <= width; e++) + ered[e] = 0; + egrn[0:] = ered[0:]; + eblu[0:] = ered[0:]; + m := 0; + n := 0; + for (i := 0; i < h2; i++) { + for (j := 0; j < w2; j++) { + cb := int Cb[m] - 128; + cr := int Cr[m] - 128; + b0r1[j] = B0 * cb + R1 * cr; + b1[j] = B1 * cb; + r0[j] = R0 * cr; + m++; + } + j = 2; + do { + ex := 0; + er := 0; + eg := 0; + eb := 0; + for (k := 0; k < w2; k++) { + l := 2; + do { + y := int Y[n] << B; + r := clamp[((y + r0[k]) >> B) + CLOFF] + ered[ex]; + g := clamp[((y + b0r1[k]) >> B) + CLOFF] + egrn[ex]; + b := clamp[((y + b1[k]) >> B) + CLOFF] + eblu[ex]; + rc := clamp16[r + CLOFF]; + gc := clamp16[g + CLOFF]; + bc := clamp16[b + CLOFF]; + col := int closest[bc + 16 * (gc + 16 * rc)]; + out[n++] = byte col; + + col *= 3; + r -= int rgbvmap[col + 0]; + t := (3 * r) >> 4; + ered[ex] = t + er; + ered[ex + 1] += t; + er = r - 3 * t; + + g -= int rgbvmap[col + 1]; + t = (3 * g) >> 4; + egrn[ex] = t + eg; + egrn[ex + 1] += t; + eg = g - 3 * t; + + b -= int rgbvmap[col + 2]; + t = (3 * b) >> 4; + eblu[ex] = t + eb; + eblu[ex + 1] += t; + eb = b - 3 * t; + ex++; + } while (--l > 0); + } + } while (--j > 0); + } + return out; +} |
