📄 ycbcr.c
字号:
float ycbcrCoeffs[3] = { .299, .587, .114 };/* default coding range is CCIR Rec 601-1 with no headroom/footroom */unsigned long refBlackWhite[6] = { 0, 255, 128, 255, 128, 255 };#define LumaRed ycbcrCoeffs[0]#define LumaGreen ycbcrCoeffs[1]#define LumaBlue ycbcrCoeffs[2]long eRtotal = 0;long eGtotal = 0;long eBtotal = 0;long preveRtotal = 0;long preveGtotal = 0;long preveBtotal = 0;unsigned long AbseRtotal = 0;unsigned long AbseGtotal = 0;unsigned long AbseBtotal = 0;unsigned long eCodes = 0;unsigned long preveCodes = 0;unsigned long eBits = 0;unsigned long preveBits = 0;static void setupLumaTables();static int abs(int v) { return (v < 0 ? -v : v); }static double pct(int v,double range) { return (v*100. / range); }static void check(int R, int G, int B);float D1, D2;float D3, D4;float D5, D6;intmain(int argc, char* argv){ int R, G, B; if (argc > 1) { refBlackWhite[0] = 16; refBlackWhite[1] = 235; refBlackWhite[2] = 128; refBlackWhite[3] = 240; refBlackWhite[4] = 128; refBlackWhite[5] = 240; } D3 = 2 - 2*LumaRed; D4 = 2 - 2*LumaBlue; D1 = 1. / D3; D2 = 1. / D4; D5 = D3*LumaRed / LumaGreen; D6 = D4*LumaBlue / LumaGreen; setupLumaTables(); for (R = 0; R < 256; R++) { for (G = 0; G < 256; G++) for (B = 0; B < 256; B++) check(R, G, B); printf("[%3u] c %u/%u b %u/%u (R %u/%d/%u G %u/%d/%u B %u/%d/%u)\n" , R , eCodes - preveCodes, eCodes , eBits - preveBits, eBits , abs(AbseRtotal - preveRtotal), eRtotal , AbseRtotal , abs(AbseGtotal - preveGtotal), eGtotal , AbseGtotal , abs(AbseBtotal - preveBtotal), eBtotal , AbseBtotal ); preveRtotal = AbseRtotal; preveGtotal = AbseGtotal; preveBtotal = AbseBtotal; preveCodes = eCodes; preveBits = eBits; } printf("%u total codes\n", 256*256*256); printf("total error: %u codes %u bits (R %d/%u G %d/%u B %d/%u)\n" , eCodes , eBits , eRtotal , AbseRtotal , eGtotal , AbseGtotal , eBtotal , AbseBtotal ); return (0);}float *lumaRed;float *lumaGreen;float *lumaBlue;static float*setupLuma(float c){ float *v = (float *)_TIFFmalloc(256 * sizeof (float)); int i; for (i = 0; i < 256; i++) v[i] = c * i; return (v);}static voidsetupLumaTables(void){ lumaRed = setupLuma(LumaRed); lumaGreen = setupLuma(LumaGreen); lumaBlue = setupLuma(LumaBlue);}static unsignedV2Code(float f, unsigned long RB, unsigned long RW, int CR){ unsigned int c = (unsigned int)((((f)*(RW-RB)/CR)+RB)+.5); return (c > 255 ? 255 : c);}#define Code2V(c, RB, RW, CR) ((((c)-(int)RB)*(float)CR)/(float)(RW-RB))#define CLAMP(f,min,max) \ (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)staticvoidcheck(int R, int G, int B){ float Y, Cb, Cr; int iY, iCb, iCr; float rY, rCb, rCr; float rR, rG, rB; int eR, eG, eB; Y = lumaRed[R] + lumaGreen[G] + lumaBlue[B]; Cb = (B - Y)*D2; Cr = (R - Y)*D1; iY = V2Code(Y, refBlackWhite[0], refBlackWhite[1], 255); iCb = V2Code(Cb, refBlackWhite[2], refBlackWhite[3], 127); iCr = V2Code(Cr, refBlackWhite[4], refBlackWhite[5], 127); rCb = Code2V(iCb, refBlackWhite[2], refBlackWhite[3], 127); rCr = Code2V(iCr, refBlackWhite[4], refBlackWhite[5], 127); rY = Code2V(iY, refBlackWhite[0], refBlackWhite[1], 255); rR = rY + rCr*D3; rB = rY + rCb*D4; rG = rY - rCb*D6 - rCr*D5; eR = R - CLAMP(rR,0,255); eG = G - CLAMP(rG,0,255); eB = B - CLAMP(rB,0,255); if (abs(eR) > 1 || abs(eG) > 1 || abs(eB) > 1) { printf("R %u G %u B %u", R, G, B); printf(" Y %g Cb %g Cr %g", Y, Cb, Cr); printf(" iY %u iCb %u iCr %u", iY, iCb, iCr); printf("\n -> Y %g Cb %g Cr %g", rY, rCb, rCr); printf(" R %g (%u) G %g (%u) B %g (%u) E=[%d %d %d])\n" , rR, CLAMP(rR,0,255) , rG, CLAMP(rG,0,255) , rB, CLAMP(rB,0,255) , eR, eG, eB ); } eRtotal += eR; eGtotal += eG; eBtotal += eB; AbseRtotal += abs(eR); AbseGtotal += abs(eG); AbseBtotal += abs(eB); if (eR | eG | eB) eCodes++; eBits += abs(eR) + abs(eG) + abs(eB);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -