Skip to content

Commit

Permalink
dd selectable color palettes and keep more precision for errDiv
Browse files Browse the repository at this point in the history
  • Loading branch information
dschmenk committed Dec 6, 2024
1 parent 0df3fe5 commit 6ae6a34
Show file tree
Hide file tree
Showing 3 changed files with 278 additions and 109 deletions.
173 changes: 64 additions & 109 deletions src/dhgr.tk/utils/dhgrrgb.pla
Original file line number Diff line number Diff line change
Expand Up @@ -14,72 +14,50 @@ const MAX_RGB = 512
const MIN_RGB = -256

byte[] ntscChroma
// Imperical 0-255 R G B
// Imperical 0-255 R G B
byte[] = 64, 51, 125 // BLUE
byte[] = 0, 108, 64 // GREEN
byte[] = 64, 77, 3 // BROWN
byte[] = 128, 20, 64 // RED
//// Calculated 0-255 R G B
//byte[] = 32, 46, 120 // BLUE
//byte[] = 8, 126, 32 // GREEN
//byte[] = 96, 82, 8 // BROWN
//byte[] = 120, 2, 96 // RED
// Calculated 0-255 R G B
byte[] = 32, 46, 120 // BLUE
byte[] = 8, 126, 32 // GREEN
byte[] = 96, 82, 8 // BROWN
byte[] = 120, 2, 96 // RED
// Idealized 0-255 R G B
byte[] = 64, 48, 128 // BLUE
byte[] = 16, 112, 64 // GREEN
byte[] = 64, 80, 0 // BROWN
byte[] = 112, 16, 64 // RED
byte[12] ntscCycle
byte[256+3] gamma
var rgbErr // Running color error array
byte errDiv = 2
byte errDiv = 3
var arg

def abs(n)
return n < 0 ?? -n :: n
end

def max(a, b)
return a < b ?? b :: a
end

def min(a, b)
return a < b ?? a :: b
end

def dist(x1, y1, z1, x2, y2, z2)#2
res[t_i32] xx, yy

x2 = x2 - x1
y2 = y2 - y1
z2 = z2 - z1
loadi16(x2)
muli16(x2)
store32(@xx)
loadi16(y2)
muli16(y2)
store32(@yy)
loadi16(z2)
muli16(z2)
add32(@yy)
add32(@xx)
store32(@xx)
return xx:[0], xx:[1]
res[t_i32] xx, yy

x2 = x2 - x1
y2 = y2 - y1
z2 = z2 - z1
loadi16(x2)
muli16(x2)
store32(@xx)
loadi16(y2)
muli16(y2)
store32(@yy)
loadi16(z2)
muli16(z2)
add32(@yy)
add32(@xx)
store32(@xx)
return xx:[0], xx:[1]
end

def dotprod(x1, y1, z1, x2, y2, z2)
return x1*x2 + y1*y2 + z1*z2
end

// Next error
def nextErr(rgb, closest)
return (rgb - closest + 1) / 2
end

def rgbClamp(rgb)
//return rgb > MAX_RGB ?? MAX_RGB :: (rgb < MIN_RGB ?? MIN_RGB :: rgb)
return rgb
end

def rgbPix(r, g, b, x, y)#0
def rgbPix(r, g, b, nr, ng, nb, x, y)#0
var errptr
var pr, pg, pb
var nr, ng, nb
var lr, lg, lb
var cr, cg, cb, cx
byte i
Expand All @@ -103,19 +81,15 @@ def rgbPix(r, g, b, x, y)#0
pb = pb + ntscCycle[i+BLU]
next
pd:[0], pd:[1] = dist(r, g, b, pr, pg, pb)
// Look ahead in chroma cycle for possible better match
// Look ahead in chroma cycle for possible better match for next RGB pixel
i = ((x + 1) & 3) * 3
lr = pr - ntscCycle[i+RED] + ntscChroma[i+RED]
lg = pg - ntscCycle[i+GRN] + ntscChroma[i+GRN]
lb = pb - ntscCycle[i+BLU] + ntscChroma[i+BLU]
if errDiv
nr = r + (errptr=>[3+RED] + nextErr(r, lr)) / errDiv
ng = g + (errptr=>[3+GRN] + nextErr(g, lg)) / errDiv
nb = b + (errptr=>[3+BLU] + nextErr(b, lb)) / errDiv
else
nr = r
ng = g
nb = b
nr = nr + (errptr=>[3+RED] + r - lr) / errDiv
ng = ng + (errptr=>[3+GRN] + g - lg) / errDiv
nb = nb + (errptr=>[3+BLU] + b - lb) / errDiv
fin
nd:[0], nd:[1] = dist(nr, ng, nb, lr, lg, lb)
// Current 1/4 chroma color
Expand All @@ -127,18 +101,18 @@ def rgbPix(r, g, b, x, y)#0
load32(@cd)
if islt32(@pd) and islt32(@nd)
// RGB better matched with current 1/4 chroma color
nr = nextErr(r, cr)
ng = nextErr(g, cg)
nb = nextErr(b, cb)
nr = r - cr
ng = g - cg
nb = b - cb
ntscCycle[i+RED] = ntscChroma[i+RED]
ntscCycle[i+GRN] = ntscChroma[i+GRN]
ntscCycle[i+BLU] = ntscChroma[i+BLU]
dhgrSet(x, y)
else
// RGB closer to black
nr = nextErr(r, pr)
ng = nextErr(g, pg)
nb = nextErr(b, pb)
nr = r - pr
ng = g - pg
nb = b - pb
ntscCycle[i+RED] = 0
ntscCycle[i+GRN] = 0
ntscCycle[i+BLU] = 0
Expand All @@ -162,10 +136,11 @@ end
def rgbInit#0
var i

if not gamma
if not gamma[1]
for i = 0 to 255
loadi16(i)
muli16(i)
addi16(127)
divi16(255)
store32(@gamma + i)
next
Expand All @@ -188,41 +163,8 @@ def rgbExit#0
dhgrMode(DHGR_TEXT_MODE)
end

def rgb3Spans(rs, gs, bs, re, ge, be, rm, gm, bm, y)#0
var i, j

memset(@ntscCycle, 0, 12)
for j = y to y + 2
for i = 0 to 63
rgbPix((i>>rs)|re, (i>>gs)|ge, (i>>bs)|be, i, j)
next
for i = 64 to 127
rgbPix(rm, gm, bm, i, j)
next
next
end

def rgbTest#0
var i

rgbInit
rgb3Spans(0,5,5, 0, 0, 0, 63, 0, 0, 0)
rgb3Spans(5,0,5, 0, 0, 0, 0,63, 0, 3)
rgb3Spans(5,5,0, 0, 0, 0, 0, 0,63, 6)
rgb3Spans(0,0,0, 0, 0, 0, 63,63,63, 9)
rgb3Spans(0,1,1, 0, 0, 0, 63,31,31, 12)
rgb3Spans(1,0,1, 0, 0, 0, 31,63,31, 15)
rgb3Spans(1,1,0, 0, 0, 0, 31,31,63, 18)
rgb3Spans(5,5,5, 16,16,16, 16,16,16, 21)
rgb3Spans(5,5,5, 32,32,32, 32,32,32, 24)
rgb3Spans(5,5,5, 48,48,48, 48,48,48, 27)
rgb3Spans(5,5,5, 63,63,63, 63,63,63, 30)
getc
rgbExit
end

def rgbImportExport(rgbfile, dhgrfile)#0
byte refnum, r, g, b
byte refnum, r, g, b, nxtr, nxtg, nxtb
var i, j
var rgbScanline, rgbptr

Expand All @@ -234,12 +176,18 @@ def rgbImportExport(rgbfile, dhgrfile)#0
for j = 0 to 191
fileio:read(refnum, rgbScanline, 560 * 3)
rgbptr = rgbScanline
nxtr = gamma[rgbptr->RED]
nxtg = gamma[rgbptr->GRN]
nxtb = gamma[rgbptr->BLU]
for i = 0 to 559
r = gamma[rgbptr->RED]
g = gamma[rgbptr->GRN]
b = gamma[rgbptr->BLU]
r = nxtr
g = nxtg
b = nxtb
rgbptr = rgbptr + 3
rgbPix(r, g, b, i, j)
nxtr = gamma[rgbptr->RED]
nxtg = gamma[rgbptr->GRN]
nxtb = gamma[rgbptr->BLU]
rgbPix(r, g, b, nxtr, nxtg, nxtb, i, j)
next
if ^$C000 == $83
break
Expand All @@ -261,11 +209,8 @@ arg = argNext(argFirst)
if ^arg
while ^(arg + 1) == '-'
when toupper(^(arg + 2))
is 'T' // Run color test
rgbTest
break
is 'L' // Use linear RGB transfer instead of gama
gamma = 1
gamma[1] = 1
break
is 'E' // Set error strength
if ^arg > 2
Expand All @@ -275,6 +220,16 @@ if ^arg
fin
fin
break
is 'C' // Use calculated chroma values
for gamma = 0 to 11
ntscChroma[gamma] = ntscChroma[gamma + 12]
next
break
is 'I' // Use idealized chroma values
for gamma = 0 to 11
ntscChroma[gamma] = ntscChroma[gamma + 24]
next
break
wend
arg = argNext(arg)
loop
Expand Down
Loading

0 comments on commit 6ae6a34

Please sign in to comment.