aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/jpg/rgbycc.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-04-21 22:19:33 +0000
committerrsc <devnull@localhost>2004-04-21 22:19:33 +0000
commit28994509cc11ac6a5443054dfae1fedfb69039bc (patch)
tree9d5adcd11af2708db0ecc246e008c308ca0f97d4 /src/cmd/jpg/rgbycc.c
parenta01e58366c54804f15f84d6e21d13f2e4080977a (diff)
downloadplan9port-28994509cc11ac6a5443054dfae1fedfb69039bc.tar.gz
plan9port-28994509cc11ac6a5443054dfae1fedfb69039bc.tar.bz2
plan9port-28994509cc11ac6a5443054dfae1fedfb69039bc.zip
Why not?
Diffstat (limited to 'src/cmd/jpg/rgbycc.c')
-rw-r--r--src/cmd/jpg/rgbycc.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/cmd/jpg/rgbycc.c b/src/cmd/jpg/rgbycc.c
new file mode 100644
index 00000000..3654a2d2
--- /dev/null
+++ b/src/cmd/jpg/rgbycc.c
@@ -0,0 +1,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);
+}