30366c9f22
ras2tiff, sgi2tiff, sgisv, and ycbcr are completely removed from the distribution. The libtiff tools rgb2ycbcr and thumbnail are only built in the build tree for testing. Old files are put in new 'archive' subdirectory of the source repository, but not in distribution archives. These changes are made in order to lessen the maintenance burden.
169 lines
4.1 KiB
C
169 lines
4.1 KiB
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;
|
|
|
|
int
|
|
main(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 void
|
|
setupLumaTables(void)
|
|
{
|
|
lumaRed = setupLuma(LumaRed);
|
|
lumaGreen = setupLuma(LumaGreen);
|
|
lumaBlue = setupLuma(LumaBlue);
|
|
}
|
|
|
|
static unsigned
|
|
V2Code(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)
|
|
|
|
static
|
|
void
|
|
check(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);
|
|
}
|
|
/*
|
|
* Local Variables:
|
|
* mode: c
|
|
* c-basic-offset: 8
|
|
* fill-column: 78
|
|
* End:
|
|
*/
|