| #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); |
| } |