aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/jpg/rgbycc.c
blob: d20cc789c638cd315c7f40e1f9f27e34f377ec7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <u.h>
#include <libc.h>
#include <draw.h>

float c1 = 1.402;
float c2 = 0.34414;
float c3 = 0.71414;
float c4 = 1.772;

int
closest(int Y, int Cb, int Cr)
{
	double r, g, b;
	double diff, min;
	int rgb, R, G, B, v, i;
	int y1, cb1, cr1;

	Cb -= 128;
	Cr -= 128;
	r = Y+c1*Cr;
	g = Y-c2*Cb-c3*Cr;
	b = Y+c4*Cb;

/*print("YCbCr: %d %d %d, RGB: %g %g %g\n", Y, Cb, Cr, r, g, b); */

	min = 1000000.;
	v = 1000;
	for(i=0; i<256; i++){
		rgb =  cmap2rgb(i);
		R = (rgb >> 16) & 0xFF;
		G = (rgb >> 8) & 0xFF;
		B = (rgb >> 0) & 0xFF;
		diff = (R-r)*(R-r) + (G-g)*(G-g) + (B-b)*(B-b);
		y1 = 0.5870*G + 0.114*B + 0.299*R;
		cb1 = (B-y1)/1.772;
		cr1 = (R-y1)/1.402;
		if(diff < min){
/*			if(Y==0 && y1!=0) */
/*				continue; */
			if(Y==256-16 && y1<256-16)
				continue;
/*			if(Cb==0 && cb1!=0) */
/*				continue; */
			if(Cb==256-16 && cb1<256-16)
				continue;
/*			if(Cr==0 && cr1!=0) */
/*				continue; */
			if(Cr==256-16 && cr1<256-16)
				continue;
/*print("%d %d %d\n", R, G, B); */
			min = diff;
			v = i;
		}
	}
	if(v > 255)
		abort();
	return v;
}

void
main(int argc, char *argv[])
{
	int i, rgb;
	int r, g, b;
	double Y, Cr, Cb;
	int y, cb, cr;
	uchar close[16*16*16];

/*print("%d\n", closest(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]))); */
/*exits("X"); */

	/* ycbcrmap */
	print("uint ycbcrmap[256] = {\n");
	for(i=0; i<256; i++){
		if(i%8 == 0)
			print("\t");
		rgb = cmap2rgb(i);
		r = (rgb>>16) & 0xFF;
		g = (rgb>>8) & 0xFF;
		b = (rgb>>0) & 0xFF;
		Y = 0.5870*g + 0.114*b + 0.299*r;
		Cr = (r-Y)/1.402 + 128.;
		Cb = (b-Y)/1.772 + 128.;
		if(Y<0. || Y>=256. || Cr<0. || Cr>=256. || Cb<0. || Cb>=256.)
			print("bad at %d: %d %d %d; %g %g %g\n", i, r, g, b, Y, Cb, Cr);
		r = Y;
		g = Cb;
		b = Cr;
		print("0x%.6ulX, ", (r<<16) | (g<<8) | b);
		if(i%8 == 7)
			print("\n");
	}
	print("};\n\n");

	/* closestycbcr */
	print("uchar closestycbcr[16*16*16] = {\n");
	for(y=0; y<256; y+=16)
	for(cb=0; cb<256; cb+=16)
	for(cr=0; cr<256; cr+=16)
		close[(cr/16)+16*((cb/16)+16*(y/16))] = closest(y, cb, cr);
if(0){
	/*weird: set white for nearly white */
	for(cb=128-32; cb<=128+32; cb+=16)
	for(cr=128-32; cr<=128+32; cr+=16)
		close[(cr/16)+16*((cb/16)+16*(255/16))] = 0;
	/*weird: set black for nearly black */
	for(cb=128-32; cb<=128+32; cb+=16)
	for(cr=128-32; cr<=128+32; cr+=16)
		close[(cr/16)+16*((cb/16)+16*(0/16))] = 255;
}
	for(i=0; i<16*16*16; i++){
		if(i%16 == 0)
			print("\t");
		print("%d,", close[i]);
		if(i%16 == 15)
			print("\n");
	}
	print("};\n\n");
	exits(nil);
}