From 8ac23f05dd183d3ca54c89d9e0a6f01acab113dc Mon Sep 17 00:00:00 2001 From: David Schmenk Date: Tue, 19 Nov 2024 10:31:00 -0800 Subject: [PATCH] Switch to dot product for closeset chroma match --- src/samplesrc/dcgrrgb.pla | 106 ++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 43 deletions(-) diff --git a/src/samplesrc/dcgrrgb.pla b/src/samplesrc/dcgrrgb.pla index 40619b8..d6d6178 100644 --- a/src/samplesrc/dcgrrgb.pla +++ b/src/samplesrc/dcgrrgb.pla @@ -10,6 +10,7 @@ const RED_MSK = $7C00 const BLU = 0 const GRN = 1 const RED = 2 +const ERR_MIN = 31 byte[12] ntscCycle byte[] ntscChroma @@ -19,15 +20,28 @@ byte[] ntscChroma //byte[] = 1, 77, 64 // BROWN //byte[] = 64, 20, 128 // RED // Imperical 0-63 B G R -byte[] = 32, 14, 16 // BLUE -byte[] = 16, 28, 0 // GREEN -byte[] = 0, 18, 16 // BROWN -byte[] = 16, 4, 32 // RED +//byte[] = 32, 14, 16 // BLUE +//byte[] = 16, 28, 0 // GREEN +//byte[] = 0, 18, 16 // BROWN +//byte[] = 16, 4, 32 // RED // Ideal/simplified 0-63 B G R -//byte[] = 32, 16, 16 // BLUE -//byte[] = 16, 32, 0 // GREEN -//byte[] = 0, 16, 16 // BROWN -//byte[] = 16, 0, 32 // RED +//byte[] = 32, 16, 16 // BLUE +//byte[] = 16, 32, 0 // GREEN +//byte[] = 0, 16, 16 // BROWN +//byte[] = 16, 0, 32 // RED +// Test 0-63 B G R +byte[] = 63, 0, 0 // BLUE +byte[] = 0, 63, 0 // GREEN +byte[] = 0, 31, 31 // BROWN +byte[] = 0, 0, 63 // RED +//byte[] = 64, 28, 32 // BLUE +//byte[] = 32, 56, 0 // GREEN +//byte[] = 0, 36, 32 // BROWN +//byte[] = 32, 8, 64 // RED +//byte[] = 64, 32, 32 // BLUE +//byte[] = 32, 26, 0 // GREEN +//byte[] = 0, 32, 32 // BROWN +//byte[] = 32, 0, 64 // RED var er, eg, eb // Running error @@ -43,55 +57,53 @@ def max(a, b) return a < b ?? b :: a end +def min(a, b) + return a < b ?? a :: b +end + +def errmin(v) + return v >= 0 +end + +def dotprod(x1, y1, z1, x2, y2, z2) + return X1*x2 + y1*y2 + z1*z2 +end + def rgbpix(r, g, b, x, y)#0 var cr, cg, cb, cx - var dr, dg, db - var zdist, cdist + var zdot, cdot byte i // Error propogation - //r = r - er/4 - //g = g - eg/4 - //b = b - eb/4 - //puts("Match: "); puti(x & 3); putln - //puti(r); putc(',');puti(g); putc(',');puti(b); putln - //puts("Cycle:\n") + r = r + er/2 + g = g + eg/2 + b = b + eb/2 cr = 0 cg = 0 cb = 0 - // Sum current chroma cycle + // Project RGB on chroma cycle with zero current 1/4 chroma for cx = x - 1 downto x - 3 i = (cx & 3) * 3 - //puti(ntscCycle[i+RED]; putc(',') - //puti(ntscCycle[i+GRN]; putc(',') - //puti(ntscCycle[i+BLU]; putln cr = cr + ntscCycle[i+RED] cg = cg + ntscCycle[i+GRN] cb = cb + ntscCycle[i+BLU] next - //puts("-------------\n") - //puti(cr); putc(',');puti(cg); putc(',');puti(cb); putln - // Subtract off chroma cycle from RGB pixel + zdot = dotprod(r, g, b, cr, cg, cb) + // Save error for zero 1/4 cycle er = r - cr eg = g - cg eb = b - cb - zdist = er*er + eg*eg + eb*eb // Distance to zero (black) + // Add current 1/4 chroma color i = (x & 3) * 3 - dr = er - ntscChroma[i+RED] - dg = eg - ntscChroma[i+GRN] - db = eb - ntscChroma[i+BLU] - cdist = dr*dr + dg*dg + db*db // Distance to chroma color - //puts("-------------\n") - //puti(ntscChroma[i+RED]); putc(',') - //puti(ntscChroma[i+GRN]); putc(',') - //puti(ntscChroma[i+BLU]); putln - //puts("Dist to Zero (Black):"); puti(zdist); putln - //puts("Dist to Chroma Color:"); puti(cdist); putln - if cdist < zdist - // RGB closer to chroma color - er = dr - eg = dg - eb = db + cr = cr + ntscChroma[i+RED] + cg = cg + ntscChroma[i+GRN] + cb = cb + ntscChroma[i+BLU] + cdot = dotprod(r, g, b, cr, cg, cb) + if cdot > zdot + // RGB better matched with 1/4 chroma color + er = r - cr + eg = g - cg + eb = b - cb ntscCycle[i+RED] = ntscChroma[i+RED] ntscCycle[i+GRN] = ntscChroma[i+GRN] ntscCycle[i+BLU] = ntscChroma[i+BLU] @@ -102,7 +114,9 @@ def rgbpix(r, g, b, x, y)#0 ntscCycle[i+GRN] = 0 ntscCycle[i+BLU] = 0 fin - //getc + //er = min(63, max(-63, er)) + //eg = min(63, max(-63, eg)) + //eb = min(63, max(-63, eb)) end def rgbTest#0 @@ -111,29 +125,35 @@ def rgbTest#0 for i = 0 to 63 rgbpix(i, 0, 0, i, 0) next + er, eg, eb, = 0, 0, 0 memset(@ntscCycle, 0, 12) for i = 0 to 63 rgbpix(0, i, 0, i, 2) next + er, eg, eb, = 0, 0, 0 memset(@ntscCycle, 0, 12) for i = 0 to 63 rgbpix(0, 0, i, i, 4) next + er, eg, eb, = 0, 0, 0 memset(@ntscCycle, 0, 12) for i = 0 to 63 rgbpix(i, i, i, i, 6) next + er, eg, eb, = 0, 0, 0 memset(@ntscCycle, 0, 12) for i = 0 to 63 - rgbpix(i, i>>1, i>>1, i, 8) + rgbpix(i, i>>2, i>>2, i, 8) next + er, eg, eb, = 0, 0, 0 memset(@ntscCycle, 0, 12) for i = 0 to 63 - rgbpix(i>>1, i, i>>1, i, 10) + rgbpix(i>>2, i, i>>2, i, 10) next + er, eg, eb, = 0, 0, 0 memset(@ntscCycle, 0, 12) for i = 0 to 63 - rgbpix(i>>1, i>>1, i, i, 12) + rgbpix(i>>2, i>>2, i, i, 12) next end