SecondReality/GRAB/COL.C
2017-09-24 01:45:36 +02:00

326 lines
6.8 KiB
C

#include <stdio.h>
#include <bios.h>
#include <malloc.h>
#include <memory.h>
int colsreserved=1;
int setback255=0;
int filetype; /* 1=LBM */
int backcol=255;
unsigned char far *vram=(char far *)0xa0000000;
union REGS reg;
unsigned char far pic[64000];
unsigned char far pic1[64000];
unsigned char far pic2[64000];
unsigned char far bigpal[8192*3];
unsigned char far bigpalhsv[8192*3];
unsigned int bigcnt[8192];
unsigned int bigcntbak[8192];
int bigpalpnt,bigpalnum;
unsigned char palmap[256];
unsigned char far pal1[768];
unsigned char far pal2[768];
unsigned char far palhsv[768];
unsigned char far tmphsv[768];
unsigned char far pal[768];
unsigned char far defpal[16*3]={
00,00,00,
00,00,40,
00,40,00,
00,40,40,
40,00,00,
40,00,40,
40,20,00,
40,40,40,
20,20,20,
20,20,60,
20,60,20,
20,60,60,
60,20,20,
60,20,60,
60,60,20,
60,60,60,
};
int eschit(void)
{
return(kbhit());
}
#include "loadlbm.c"
main(int argc,char *argv[])
{
int a,b,c,d,x,y;
printf("\nColorMixer V1.0 (C) 1991 Sami Tammilehto \n\n");
if(argc==1)
{
printf("usage: col [?###] <src1> <src2>\n"
"when picture is in screen, press space to\n"
"toggle pics/palette, ESC to exit.\n"
"!### means reserve ### first colors for other\n"
"purposes (leave empty/to default pal)\n");
return(0);
}
if(*argv[1]=='?')
{
colsreserved=atoi(argv[1]+1);
argv[1]=argv[2];
argv[2]=argv[3];
}
bigpalpnt=0;
printf("Processing, please wait...\n");
printf("File: %s",argv[1]);
memset(pic,0,64000);
memset(pal,0,768);
loadlbm(argv[1]); printf("100%%\n");
memcpy(pic1,pic,64000);
memcpy(pal1,pal,768);
analyze(pic1,pal1);
printf("File: %s",argv[2]);
memset(pic,0,64000);
memset(pal,0,768);
loadlbm(argv[2]); printf("100%%\n");
memcpy(pic2,pic,64000);
memcpy(pal2,pal,768);
analyze(pic2,pal2);
bigpalnum=bigpalpnt;
printf("Colors in big palette: %i\n",bigpalnum);
printf("Combining and optimizing palettes...\n");
memset(pal,0,768);
memcpy(pal,defpal,16*3);
createpal();
printf("Remapping first picture... \n");
remap(pic1,pal1,pal);
printf("Remapping second picture... \n");
remap(pic2,pal2,pal);
reg.x.ax=0x13;
int86(0x10,&reg,&reg);
{
outp(0x3c8,0);
for(a=0;a<768;a++) outp(0x3c9,pal[a]);
}
for(;;)
{
memset(vram,0,64000);
for(a=0;a<16;a++) for(b=0;b<16;b++)
{
x=a*12; y=b*10;
for(c=0;c<11;c++) for(d=0;d<9;d++)
{
*(vram+x+c+(y+d)*320)=b+a*16;
}
}
a=getch();
if(a==13 || a==27) break;
memcpy(vram,pic1,64000);
a=getch();
if(a==13 || a==27) break;
memcpy(vram,pic2,64000);
a=getch();
if(a==13 || a==27) break;
}
reg.x.ax=0x3;
int86(0x10,&reg,&reg);
}
unsigned colcnt[256];
int analyze(unsigned char *pic,unsigned char *pal)
{
int a,b,c,x,y;
printf("Generating big palette and calculating relative color importances...\n");
memset(colcnt,0,256*2);
for(y=0;y<200;y++) for(x=0;x<320;x++)
{
colcnt[pic[x+y*320]]++;
}
for(a=0;a<256;a++)
{
if(colcnt[a]!=0)
{
bigpal[bigpalpnt*3+0]=pal[a*3+0];
bigpal[bigpalpnt*3+1]=pal[a*3+1];
bigpal[bigpalpnt*3+2]=pal[a*3+2];
bigcnt[bigpalpnt++]=colcnt[a];
}
}
}
int createpal(void)
{
int testval,testcnt;
int colors=256-colsreserved,firstcol=colsreserved;
int xr,xb,xg,xh,xs,xv;
int a,b,c,d,e,f,g,h;
int x,y;
int s;
rgb2hsv(bigpalhsv,bigpal,bigpalnum);
for(testcnt=0;testcnt<5;testcnt++)
{
switch(testcnt)
{
case 0 : testval=0; break;
case 1 : testval=1; break;
case 2 : testval=3; break;
case 3 : testval=5; break;
case 4 : testval=8; break;
}
memset(pal+firstcol*3,0,colors*3);
memcpy(bigcntbak,bigcnt,bigpalnum*2);
for(a=0;a<colors;)
{
printf("Processing pass %i/5: %i%% complete \r",testcnt+1,100*a/256);
{
unsigned int c;
c=0; /* max */
d=0; /* maxcolowner */
for(b=0;b<bigpalnum;b++)
{
if(bigcnt[b]>c) { c=bigcnt[b]; d=b; }
}
if(c==0) { testcnt=999; break; }
s=d; bigcnt[d]=0;
}
{
xr=bigpal[s*3+0];
xg=bigpal[s*3+1];
xb=bigpal[s*3+2];
xh=bigpalhsv[s*3+0];
xs=bigpalhsv[s*3+1];
xv=bigpalhsv[s*3+2];
c=999; /* difference */
for(b=firstcol;b<a+firstcol;b++)
{
f=b*3;
g=((xr-(unsigned int)pal[f+0]));
e=(g<0?-g:g);
g=((xg-(unsigned int)pal[f+1]));
e+=(g<0?-g:g);
g=((xb-(unsigned int)pal[f+2]));
e+=(g<0?-g:g);
/*g=((xh-(unsigned int)palhsv[f+0]));
e=(g<0?-g:g)*2;
g=((xs-(unsigned int)palhsv[f+1]));
e+=(g<0?-g:g)*2;
g=((xv-(unsigned int)palhsv[f+2]));
e+=(g<0?-g:g);*/
if(e<c) { c=e; }
}
}
if(c>testval)
{
d=a+firstcol;
pal[d*3]=bigpal[s*3];
pal[d*3+1]=bigpal[s*3+1];
pal[d*3+2]=bigpal[s*3+2];
rgb2hsv(palhsv+d*3,pal+d*3,1);
a++;
}
}
memcpy(bigcnt,bigcntbak,bigpalnum*2);
}
rgb2hsv(palhsv,pal,256);
}
int remap(unsigned char *pic,unsigned char *spal,unsigned char *pal)
{
int xr,xb,xg,xh,xs,xv;
int a,b,c,d,e,f,g,h;
memset(palmap,0,256);
rgb2hsv(tmphsv,spal,256);
for(a=0;a<256;a++)
{
printf("Processing: %i%% complete \r",100*a/256/2);
xr=spal[a*3+0];
xg=spal[a*3+1];
xb=spal[a*3+2];
xh=tmphsv[a*3+0];
xs=tmphsv[a*3+1];
xv=tmphsv[a*3+2];
h=0; c=999; /* difference */
for(b=colsreserved;b<256;b++)
{
f=b*3;
/*g=(xh-(unsigned int)palhsv[f+0]);
e=(g<0?-g:g)*2;
g=(xs-(unsigned int)palhsv[f+1]);
e+=(g<0?-g:g);
g=(xv-(unsigned int)palhsv[f+2]);
e+=(g<0?-g:g)*2;*/
g=((xr-(unsigned int)pal[f+0]));
e=(g<0?-g:g);
g=((xg-(unsigned int)pal[f+1]));
e+=(g<0?-g:g);
g=((xb-(unsigned int)pal[f+2]));
e+=(g<0?-g:g);
if(e<c) { c=e; h=b; }
}
palmap[a]=h;
}
for(a=0;a<200;a++)
{
printf("Processing: %i%% complete \r",100*a/200/2+50);
for(b=0;b<320;b++)
{
pic[a*320+b]=palmap[pic[a*320+b]];
}
}
}
int minval(int v1,int v2,int v3)
{
if(v1<v2 && v1<v3) return(v1);
if(v2<v1 && v2<v3) return(v2);
if(v3<v1 && v3<v2) return(v3);
return(v1);
}
int maxval(int v1,int v2,int v3)
{
if(v1>v2 && v1>v3) return(v1);
if(v2>v1 && v2>v3) return(v2);
if(v3>v1 && v3>v2) return(v3);
return(v1);
}
int rgb2hsv(unsigned char *dst,unsigned char *src,int num)
{
int cr,cg,cb;
int tmp,i;
int xr,xg,xb,zh,zs,zv;
for(i=0;i<num;i++)
{
xr=*(src++);
xg=*(src++);
xb=*(src++);
/* value */
zv=maxval(xr,xg,xb);
/* saturation */
tmp=minval(xr,xg,xb);
if(zv==0) zs=0; else zs=63*(zv-tmp)/zv;
/* hue */
if(zs==0) zh=127;
else
{
cr=100*(zv-xr)/(zv-tmp);
cg=100*(zv-xg)/(zv-tmp);
cb=100*(zv-xb)/(zv-tmp);
if(xr==zv) zh=cb-cg;
if(xg==zv) zh=200+cr-cb;
if(xb==zv) zh=400+cg-cr;
if(zh<0) zh+=500;
zh/=8;
}
*(dst++)=zh;
*(dst++)=zs;
*(dst++)=zv;
}
}