1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-01-08 22:30:48 +00:00

Switch to dot product for closeset chroma match

This commit is contained in:
David Schmenk 2024-11-19 10:31:00 -08:00
parent ee397da178
commit 8ac23f05dd

View File

@ -10,6 +10,7 @@ const RED_MSK = $7C00
const BLU = 0 const BLU = 0
const GRN = 1 const GRN = 1
const RED = 2 const RED = 2
const ERR_MIN = 31
byte[12] ntscCycle byte[12] ntscCycle
byte[] ntscChroma byte[] ntscChroma
@ -19,15 +20,28 @@ byte[] ntscChroma
//byte[] = 1, 77, 64 // BROWN //byte[] = 1, 77, 64 // BROWN
//byte[] = 64, 20, 128 // RED //byte[] = 64, 20, 128 // RED
// Imperical 0-63 B G R // Imperical 0-63 B G R
byte[] = 32, 14, 16 // BLUE //byte[] = 32, 14, 16 // BLUE
byte[] = 16, 28, 0 // GREEN //byte[] = 16, 28, 0 // GREEN
byte[] = 0, 18, 16 // BROWN //byte[] = 0, 18, 16 // BROWN
byte[] = 16, 4, 32 // RED //byte[] = 16, 4, 32 // RED
// Ideal/simplified 0-63 B G R // Ideal/simplified 0-63 B G R
//byte[] = 32, 16, 16 // BLUE //byte[] = 32, 16, 16 // BLUE
//byte[] = 16, 32, 0 // GREEN //byte[] = 16, 32, 0 // GREEN
//byte[] = 0, 16, 16 // BROWN //byte[] = 0, 16, 16 // BROWN
//byte[] = 16, 0, 32 // RED //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 var er, eg, eb // Running error
@ -43,55 +57,53 @@ def max(a, b)
return a < b ?? b :: a return a < b ?? b :: a
end 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 def rgbpix(r, g, b, x, y)#0
var cr, cg, cb, cx var cr, cg, cb, cx
var dr, dg, db var zdot, cdot
var zdist, cdist
byte i byte i
// Error propogation // Error propogation
//r = r - er/4 r = r + er/2
//g = g - eg/4 g = g + eg/2
//b = b - eb/4 b = b + eb/2
//puts("Match: "); puti(x & 3); putln
//puti(r); putc(',');puti(g); putc(',');puti(b); putln
//puts("Cycle:\n")
cr = 0 cr = 0
cg = 0 cg = 0
cb = 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 for cx = x - 1 downto x - 3
i = (cx & 3) * 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] cr = cr + ntscCycle[i+RED]
cg = cg + ntscCycle[i+GRN] cg = cg + ntscCycle[i+GRN]
cb = cb + ntscCycle[i+BLU] cb = cb + ntscCycle[i+BLU]
next next
//puts("-------------\n") zdot = dotprod(r, g, b, cr, cg, cb)
//puti(cr); putc(',');puti(cg); putc(',');puti(cb); putln // Save error for zero 1/4 cycle
// Subtract off chroma cycle from RGB pixel
er = r - cr er = r - cr
eg = g - cg eg = g - cg
eb = b - cb eb = b - cb
zdist = er*er + eg*eg + eb*eb // Distance to zero (black) // Add current 1/4 chroma color
i = (x & 3) * 3 i = (x & 3) * 3
dr = er - ntscChroma[i+RED] cr = cr + ntscChroma[i+RED]
dg = eg - ntscChroma[i+GRN] cg = cg + ntscChroma[i+GRN]
db = eb - ntscChroma[i+BLU] cb = cb + ntscChroma[i+BLU]
cdist = dr*dr + dg*dg + db*db // Distance to chroma color cdot = dotprod(r, g, b, cr, cg, cb)
//puts("-------------\n") if cdot > zdot
//puti(ntscChroma[i+RED]); putc(',') // RGB better matched with 1/4 chroma color
//puti(ntscChroma[i+GRN]); putc(',') er = r - cr
//puti(ntscChroma[i+BLU]); putln eg = g - cg
//puts("Dist to Zero (Black):"); puti(zdist); putln eb = b - cb
//puts("Dist to Chroma Color:"); puti(cdist); putln
if cdist < zdist
// RGB closer to chroma color
er = dr
eg = dg
eb = db
ntscCycle[i+RED] = ntscChroma[i+RED] ntscCycle[i+RED] = ntscChroma[i+RED]
ntscCycle[i+GRN] = ntscChroma[i+GRN] ntscCycle[i+GRN] = ntscChroma[i+GRN]
ntscCycle[i+BLU] = ntscChroma[i+BLU] ntscCycle[i+BLU] = ntscChroma[i+BLU]
@ -102,7 +114,9 @@ def rgbpix(r, g, b, x, y)#0
ntscCycle[i+GRN] = 0 ntscCycle[i+GRN] = 0
ntscCycle[i+BLU] = 0 ntscCycle[i+BLU] = 0
fin fin
//getc //er = min(63, max(-63, er))
//eg = min(63, max(-63, eg))
//eb = min(63, max(-63, eb))
end end
def rgbTest#0 def rgbTest#0
@ -111,29 +125,35 @@ def rgbTest#0
for i = 0 to 63 for i = 0 to 63
rgbpix(i, 0, 0, i, 0) rgbpix(i, 0, 0, i, 0)
next next
er, eg, eb, = 0, 0, 0
memset(@ntscCycle, 0, 12) memset(@ntscCycle, 0, 12)
for i = 0 to 63 for i = 0 to 63
rgbpix(0, i, 0, i, 2) rgbpix(0, i, 0, i, 2)
next next
er, eg, eb, = 0, 0, 0
memset(@ntscCycle, 0, 12) memset(@ntscCycle, 0, 12)
for i = 0 to 63 for i = 0 to 63
rgbpix(0, 0, i, i, 4) rgbpix(0, 0, i, i, 4)
next next
er, eg, eb, = 0, 0, 0
memset(@ntscCycle, 0, 12) memset(@ntscCycle, 0, 12)
for i = 0 to 63 for i = 0 to 63
rgbpix(i, i, i, i, 6) rgbpix(i, i, i, i, 6)
next next
er, eg, eb, = 0, 0, 0
memset(@ntscCycle, 0, 12) memset(@ntscCycle, 0, 12)
for i = 0 to 63 for i = 0 to 63
rgbpix(i, i>>1, i>>1, i, 8) rgbpix(i, i>>2, i>>2, i, 8)
next next
er, eg, eb, = 0, 0, 0
memset(@ntscCycle, 0, 12) memset(@ntscCycle, 0, 12)
for i = 0 to 63 for i = 0 to 63
rgbpix(i>>1, i, i>>1, i, 10) rgbpix(i>>2, i, i>>2, i, 10)
next next
er, eg, eb, = 0, 0, 0
memset(@ntscCycle, 0, 12) memset(@ntscCycle, 0, 12)
for i = 0 to 63 for i = 0 to 63
rgbpix(i>>1, i>>1, i, i, 12) rgbpix(i>>2, i>>2, i, i, 12)
next next
end end