Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/LibTIFF4/tif_luv.c  view on Meta::CPAN


static void
L16toGry(LogLuvState* sp, uint8* op, tmsize_t n)
{
	int16* l16 = (int16*) sp->tbuf;
	uint8* gp = (uint8*) op;

	while (n-- > 0) {
		double Y = LogL16toY(*l16++);
		*gp++ = (uint8) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y)));
	}
}

static void
L16fromY(LogLuvState* sp, uint8* op, tmsize_t n)
{
	int16* l16 = (int16*) sp->tbuf;
	float* yp = (float*) op;

	while (n-- > 0)
		*l16++ = (int16) (LogL16fromY(*yp++, sp->encode_meth));
}

#if !LOGLUV_PUBLIC
static
#endif
void
XYZtoRGB24(float xyz[3], uint8 rgb[3])
{
	double	r, g, b;
					/* assume CCIR-709 primaries */
	r =  2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2];
	g = -1.022*xyz[0] +  1.978*xyz[1] +  0.044*xyz[2];
	b =  0.061*xyz[0] + -0.224*xyz[1] +  1.163*xyz[2];
					/* assume 2.0 gamma for speed */
	/* could use integer sqrt approx., but this is probably faster */
	rgb[0] = (uint8)((r<=0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r)));
	rgb[1] = (uint8)((g<=0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g)));
	rgb[2] = (uint8)((b<=0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b)));
}

#if !LOGLUV_PUBLIC
static
#endif
double
LogL10toY(int p10)		/* compute luminance from 10-bit LogL */
{
	if (p10 == 0)
		return (0.);
	return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.));
}

#if !LOGLUV_PUBLIC
static
#endif
int
LogL10fromY(double Y, int em)	/* get 10-bit LogL from Y */
{
	if (Y >= 15.742)
		return (0x3ff);
	else if (Y <= .00024283)
		return (0);
	else
		return itrunc(64.*(log2(Y) + 12.), em);
}

#define NANGLES		100
#define uv2ang(u, v)	( (NANGLES*.499999999/M_PI) \
				* atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES )

static int
oog_encode(double u, double v)		/* encode out-of-gamut chroma */
{
	static int	oog_table[NANGLES];
	static int	initialized = 0;
	register int	i;

	if (!initialized) {		/* set up perimeter table */
		double	eps[NANGLES], ua, va, ang, epsa;
		int	ui, vi, ustep;
		for (i = NANGLES; i--; )
			eps[i] = 2.;
		for (vi = UV_NVS; vi--; ) {
			va = UV_VSTART + (vi+.5)*UV_SQSIZ;
			ustep = uv_row[vi].nus-1;
			if (vi == UV_NVS-1 || vi == 0 || ustep <= 0)
				ustep = 1;
			for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) {
				ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
				ang = uv2ang(ua, va);
				i = (int) ang;
				epsa = fabs(ang - (i+.5));
				if (epsa < eps[i]) {
					oog_table[i] = uv_row[vi].ncum + ui;
					eps[i] = epsa;
				}
			}
		}
		for (i = NANGLES; i--; )	/* fill any holes */
			if (eps[i] > 1.5) {
				int	i1, i2;
				for (i1 = 1; i1 < NANGLES/2; i1++)
					if (eps[(i+i1)%NANGLES] < 1.5)
						break;
				for (i2 = 1; i2 < NANGLES/2; i2++)
					if (eps[(i+NANGLES-i2)%NANGLES] < 1.5)
						break;
				if (i1 < i2)
					oog_table[i] =
						oog_table[(i+i1)%NANGLES];
				else
					oog_table[i] =
						oog_table[(i+NANGLES-i2)%NANGLES];
			}
		initialized = 1;
	}
	i = (int) uv2ang(u, v);		/* look up hue angle */
	return (oog_table[i]);
}

#undef uv2ang



( run in 0.587 second using v1.01-cache-2.11-cpan-56fb94df46f )