I enjoyed optimizing the no shader version.
On my pc 20 ms with standard programming
SETFONT 0,2
GLOBAL pixels%[],id%=0
IF DOESFILEEXIST("test.png")
LOADSPRITE "test.png",id
ENDIF
SPRITE2MEM (pixels[],id)
GETSPRITESIZE id, sx%, sy%
dtime% = GETTIMERALL()
C64ize()
MEM2SPRITE(pixels[],id,sx,sy)
dtime% = GETTIMERALL()-dtime%
DRAWSPRITE id,0,0
SAVESPRITE "test.bmp", id
PRINT dtime%,10,300
SHOWSCREEN
MOUSEWAIT
END
FUNCTION C64ize:
// weighting of color components
LOCAL x%,y%,c%, r%,g%,b%, dr%,dg%,db%
LOCAL mindist, dist, ibest, i
LOCAL c64_pal[]
DIMDATA c64_pal[], _
0x00 , 0x00 , 0x00, 0, _
0xff , 0xff , 0xff, 0, _
0x88 , 0x00 , 0x00, 0, _
0xaa , 0xff , 0xee, 0, _
0xcc , 0x44 , 0xcc, 0, _
0x00 , 0xcc , 0x55, 0, _
0x00 , 0x00 , 0xaa, 0, _
0xee , 0xee , 0x77, 0, _
0xdd , 0x88 , 0x55, 0, _
0x66 , 0x44 , 0x00, 0, _
0xff , 0x77 , 0x77, 0, _
0x33 , 0x33 , 0x33, 0, _
0x77 , 0x77 , 0x77, 0, _
0xaa , 0xff , 0x66, 0, _
0x00 , 0x88 , 0xff, 0, _
0xbb , 0xbb , 0xbb, 0
FOR i=0 TO 15
c64_pal[i*4+3] = RGB(c64_pal[i*4], c64_pal[i*4+1], c64_pal[i*4+2])
NEXT
FOR x=0 TO 319 STEP 2
FOR y=0 TO 239
ind=x+y*320
c = pixels[ind]
c = bAND(c, 0xffffff)
r=bAND(c, 0xff)/2
g=bAND(ASR(c,8), 0xff)/2
b=bAND(ASR(c,16), 0xff)/2
mindist=0
c = pixels[ind+1]
c = bAND(c, 0xffffff)
INC r,bAND(c, 0xff)/2
INC g,bAND(ASR(c,8), 0xff)/2
INC b,bAND(ASR(c,16), 0xff)/2
ibest=0
FOR i=0 TO 15
db=b - c64_pal[i*4+2]
dg=g - c64_pal[i*4+1]
dr=r - c64_pal[i*4 ]
dist=dr*dr+dg*dg+db*db
IF i=0 OR dist<mindist
mindist=dist
ibest=i
ENDIF
NEXT
fillcolour=bOR(c64_pal[ibest*4+3], ASL(255, 24))
pixels[ind]=fillcolour
pixels[ind+1]=fillcolour
NEXT
NEXT
ENDFUNCTION