static void
cvtClump(unsigned char* op, uint32* raster, uint32 ch, uint32 cw, uint32 w)
{
	float Y, Cb = 0, Cr = 0;
	uint32 j, k;
	/*
	 * Convert ch-by-cw block of RGB
	 * to YCbCr and sample accordingly.
	 */
	for (k = 0; k < ch; k++) {
		for (j = 0; j < cw; j++) {
			uint32 RGB = (raster - k*w)[j];
			Y = lumaRed[TIFFGetR(RGB)] +
			    lumaGreen[TIFFGetG(RGB)] +
			    lumaBlue[TIFFGetB(RGB)];
			/* accumulate chrominance */
			Cb += (TIFFGetB(RGB) - Y) * D1;
			Cr += (TIFFGetR(RGB) - Y) * D2;
			/* emit luminence */
			*op++ = V2Code(Y,
			    refBlackWhite[0], refBlackWhite[1], 255);
		}
		for (; j < horizSubSampling; j++)
			*op++ = Yzero;
	}
	for (; k < vertSubSampling; k++) {
		for (j = 0; j < horizSubSampling; j++)
			*op++ = Yzero;
	}
	/* emit sampled chrominance values */
	*op++ = V2Code(Cb / (ch*cw), refBlackWhite[2], refBlackWhite[3], 127);
	*op++ = V2Code(Cr / (ch*cw), refBlackWhite[4], refBlackWhite[5], 127);
}
Example #2
0
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);
}
static void
setupLumaTables(void)
{
	lumaRed = setupLuma(LumaRed);
	lumaGreen = setupLuma(LumaGreen);
	lumaBlue = setupLuma(LumaBlue);
	D1 = 1.F/(2.F - 2.F*LumaBlue);
	D2 = 1.F/(2.F - 2.F*LumaRed);
	Yzero = V2Code(0, refBlackWhite[0], refBlackWhite[1], 255);
}