1 float ycbcrCoeffs[3] = { .299, .587, .114 };
2 /* default coding range is CCIR Rec 601-1 with no headroom/footroom */
3 unsigned long refBlackWhite[6] = { 0, 255, 128, 255, 128, 255 };
5 #define LumaRed ycbcrCoeffs[0]
6 #define LumaGreen ycbcrCoeffs[1]
7 #define LumaBlue ycbcrCoeffs[2]
15 unsigned long AbseRtotal = 0;
16 unsigned long AbseGtotal = 0;
17 unsigned long AbseBtotal = 0;
18 unsigned long eCodes = 0;
19 unsigned long preveCodes = 0;
20 unsigned long eBits = 0;
21 unsigned long preveBits = 0;
23 static void setupLumaTables();
24 static int abs(int v) { return (v < 0 ? -v : v); }
25 static double pct(int v,double range) { return (v*100. / range); }
26 static void check(int R, int G, int B);
33 main(int argc, char** argv)
38 refBlackWhite[0] = 16;
39 refBlackWhite[1] = 235;
40 refBlackWhite[2] = 128;
41 refBlackWhite[3] = 240;
42 refBlackWhite[4] = 128;
43 refBlackWhite[5] = 240;
49 D5 = D3*LumaRed / LumaGreen;
50 D6 = D4*LumaBlue / LumaGreen;
52 for (R = 0; R < 256; R++) {
53 for (G = 0; G < 256; G++)
54 for (B = 0; B < 256; B++)
56 printf("[%3u] c %u/%u b %u/%u (R %u/%d/%u G %u/%d/%u B %u/%d/%u)\n"
58 , eCodes - preveCodes, eCodes
59 , eBits - preveBits, eBits
60 , abs(AbseRtotal - preveRtotal), eRtotal , AbseRtotal
61 , abs(AbseGtotal - preveGtotal), eGtotal , AbseGtotal
62 , abs(AbseBtotal - preveBtotal), eBtotal , AbseBtotal
64 preveRtotal = AbseRtotal;
65 preveGtotal = AbseGtotal;
66 preveBtotal = AbseBtotal;
70 printf("%u total codes\n", 256*256*256);
71 printf("total error: %u codes %u bits (R %d/%u G %d/%u B %d/%u)\n"
74 , eRtotal , AbseRtotal
75 , eGtotal , AbseGtotal
76 , eBtotal , AbseBtotal
88 float *v = (float *)_TIFFmalloc(256 * sizeof (float));
90 for (i = 0; i < 256; i++)
98 lumaRed = setupLuma(LumaRed);
99 lumaGreen = setupLuma(LumaGreen);
100 lumaBlue = setupLuma(LumaBlue);
104 V2Code(float f, unsigned long RB, unsigned long RW, int CR)
106 unsigned int c = (unsigned int)((((f)*(RW-RB)/CR)+RB)+.5);
107 return (c > 255 ? 255 : c);
110 #define Code2V(c, RB, RW, CR) ((((c)-(int)RB)*(float)CR)/(float)(RW-RB))
112 #define CLAMP(f,min,max) \
113 (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
117 check(int R, int G, int B)
125 Y = lumaRed[R] + lumaGreen[G] + lumaBlue[B];
128 iY = V2Code(Y, refBlackWhite[0], refBlackWhite[1], 255);
129 iCb = V2Code(Cb, refBlackWhite[2], refBlackWhite[3], 127);
130 iCr = V2Code(Cr, refBlackWhite[4], refBlackWhite[5], 127);
131 rCb = Code2V(iCb, refBlackWhite[2], refBlackWhite[3], 127);
132 rCr = Code2V(iCr, refBlackWhite[4], refBlackWhite[5], 127);
133 rY = Code2V(iY, refBlackWhite[0], refBlackWhite[1], 255);
136 rG = rY - rCb*D6 - rCr*D5;
137 eR = R - CLAMP(rR,0,255);
138 eG = G - CLAMP(rG,0,255);
139 eB = B - CLAMP(rB,0,255);
140 if (abs(eR) > 1 || abs(eG) > 1 || abs(eB) > 1) {
141 printf("R %u G %u B %u", R, G, B);
142 printf(" Y %g Cb %g Cr %g", Y, Cb, Cr);
143 printf(" iY %u iCb %u iCr %u", iY, iCb, iCr);
144 printf("\n -> Y %g Cb %g Cr %g", rY, rCb, rCr);
145 printf(" R %g (%u) G %g (%u) B %g (%u) E=[%d %d %d])\n"
146 , rR, CLAMP(rR,0,255)
147 , rG, CLAMP(rG,0,255)
148 , rB, CLAMP(rB,0,255)
155 AbseRtotal += abs(eR);
156 AbseGtotal += abs(eG);
157 AbseBtotal += abs(eB);
160 eBits += abs(eR) + abs(eG) + abs(eB);