Beispiel #1
0
McoStatus ScanCal::_localcal(PWlinear **linear, MultiLcal *gcal, MultiLcal **lcal, long num, double *in, double *out)
{
	McoStatus status; 
	long i, m, j, local;
	double rgb[3], lch[3], caled[3];
	double white[3];
	
	white[0] = 96.42;
	white[1] = 100.0;
	white[2] = 82.49;
	
	m = 0;
	for (i=0; i<num; i++){
		rgb[0] = in[m];
		rgb[1] = in[m+1];
		rgb[2] = in[m+2];
		
		status = _linearstrech(3, linear, 1, rgb);
		if(status != MCO_SUCCESS)	return status;
		
		for(j = 0; j < 3; j++){
			if(rgb[j] < 0)	rgb[j] = 0;
			if(rgb[j] > 255)	rgb[j] = 255.0;
		}	
			
		status = gcal->apply(1, rgb, caled);
		if(status != MCO_SUCCESS)	return status;
		xyztonxyzinplace(caled, white, 1);
		nxyztoLabinplace(caled, 1);
		labtolch(caled, lch);
		
	
		if(lch[1] > GRAY_THRESHOLD){
			local = _select_local(lch);
			status = lcal[local]->apply(1, rgb, caled);
			if(status != MCO_SUCCESS)	return status;
			xyztonxyzinplace(caled, white, 1);
			nxyztoLabinplace(caled, 1);
		}

//fix cyan here, may introduce new bug
/*
		if(lch[1] > GRAY_THRESHOLD && lch[2] > 215 && lch[2] < 250){
			status = _cyan->apply(1, rgb, caled);
			if(status != MCO_SUCCESS)	return status;
			xyztonxyzinplace(caled, white, 1);
			nxyztoLabinplace(caled, 1);
		}
*/
		
		out[m] = caled[0];
		out[m+1] = caled[1];
		out[m+2] = caled[2];
		m += 3;
	}
			
	return MCO_SUCCESS;		
}
Beispiel #2
0
void labtolchinplace(double *LAB, long num)
{
	long i;
	
	for(i = 0; i < num; i++){
		labtolch(LAB, LAB);
		LAB += 3;
	}	
}
Beispiel #3
0
McoStatus FindBlack::findMinMaxOpt(double *lab, double *Kmin,double *Kmax,double *Kopt)
{
int32 i,km,kp,c;
double *gammutSurfaceManyBlack;
double *gammutSurfaceManyBlackL;
double x23[2];
double lch[3];
double x11[101]; // find 100 black values
double y[101];
double x2n[50];
double y2n[GAM_DIM_K*50];
Boolean start = TRUE;
double	best_s;
double Kmint,Kmaxt;

Kmint = -1;
Kmaxt = -1;

labtolch(lab,lch);

km = floor(*Kmin);
kp = ceil(*Kmax);

if ((lab[1]*lab[1]+lab[2]*lab[2]) <= 1.0)
	{
	
	for (i=0; i<50; i++) x2n[i] = (double)i*2;
	
	for (i=km; i<=kp; i++) x11[i] = (double)i/100;
	
	c = 1+kp-km;
	
	spline2(x1,x2n,neutralmins,GAM_DIM_K,50,y2n);
	splint2_clip(x1,x2n,neutralmins,y2n,GAM_DIM_K,50,lab[0],x11,c,y);
	}
else
	{

	gammutSurfaceManyBlack = (double*)McoLockHandle(_gammutSurfaceManyBlackH);
	gammutSurfaceManyBlackL = (double*)McoLockHandle(_gammutSurfaceManyBlackLH);

	x23[0] = lch[2];
	x23[1] = lab[0];


	for (i=km; i<=kp; i++) x11[i] = (double)i/100;
	
	c = 1+kp-km;

	splint3_s3_clip(x1,x2,gammutSurfaceManyBlackL,gammutSurfaceManyBlack,y2a,GAM_DIM_K,72,50,x23,x11,c,y);

	McoUnlockHandle(_gammutSurfaceManyBlackH);
	McoUnlockHandle(_gammutSurfaceManyBlackLH);
	}
best_s = 0;

c = 0;


for (i=km; i<=kp; i++)
	{
	if ((y[c] > 0) && (y[c] + 0.8 > lch[1])) // insert a small tolerence here
		{
		if (start) 
			{
			Kmint = (double)i;
			start = FALSE;
			}
		Kmaxt = (double)i;
		}
	if (y[c] > best_s) 
		{
		best_s = y[c];
		*Kopt = (double)i;
		}
	c++;
	}
*Kmin = Kmint;
*Kmax = Kmaxt;	
	
	
if (*Kmin == -1) *Kmin = *Kopt;	
if (*Kmax == -1) *Kmax = *Kopt;	

return MCO_SUCCESS;
}
Beispiel #4
0
// evaluate using the table (for gamut compression)
// labo = the original lab value
// labg = the gamut compressed lab value
// labt = the tweaked compressed value
McoStatus Tweak_Patch::eval(double *labo,double *labg,double *labt,int32 num)
{
int	i;
double	a,b,c;
int32	a1,a2,b1,b2,c1,c2;
int32	ai1,ai2,bi1,bi2,ci1,ci2;
double t,u,v;
double	r1,r2,r3,r4,r5,r6,r7,r8;
double	*p1,*p2,*p3,*p4,*p5,*p6,*p7,*p8;
double *table;
double	lch[3];

if (type == Calibrate_Tweak) return MCO_FAILURE;

table = (double *)McoLockHandle(labTableH);

for (i=0; i<num; i++)	
	{
	a = labo[0]*0.32;
	b = 16 + labo[1]*0.125;
	c = 16 + labo[2]*0.125;

	if (a >= 32) a = 31.999999;
	if (a < 0) a = 0;
	if (b >= 32) b = 31.999999;
	if (b < 0) b = 0;
	if (c >= 32) c = 31.999999;
	if (c < 0) c = 0;
				
	a1 = ((int32)a)*3267;
	a2 = a1 + 3267;
	b1 = ((int32)b)*99;
	b2 = b1 + 99;
	c1 = ((int32)c)*3;
	c2 = c1 + 3;

	t = a - (int32)a;
	u = b - (int32)b;
	v = c - (int32)c;

	r1 = (1-u)*(1-v);
	r2 = (1-u)*v;
	r3 = u*(1-v);
	r4 = u*v;
	r5 = t*r1;
	r6 = t*r2;
	r7 = t*r3;
	r8 = t*r4;
	a = (1-t);
	r1 = a*r1;
	r2 = a*r2;
	r3 = a*r3;
	r4 = a*r4;

	p1 = table +a1+b1+c1;
	p2 = table +a1+b1+c2;
	p3 = table +a1+b2+c1;
	p4 = table +a1+b2+c2;
	p5 = table +a2+b1+c1;
	p6 = table +a2+b1+c2;
	p7 = table +a2+b2+c1;
	p8 = table +a2+b2+c2;
				
	labtolch(labg,lch);			
				
	lch[0] += r1*(*(p1++)) +
		r2*(*(p2++)) +
		r3*(*(p3++)) +
		r4*(*(p4++)) +
		r5*(*(p5++)) +
		r6*(*(p6++)) +
		r7*(*(p7++)) +
		r8*(*(p8++));
		
	lch[1] += r1*(*(p1++)) +
		r2*(*(p2++)) +
		r3*(*(p3++)) +
		r4*(*(p4++)) +
		r5*(*(p5++)) +
		r6*(*(p6++)) +
		r7*(*(p7++)) +
		r8*(*(p8++));	
		
	lch[2] += r1*(*(p1)) +
		r2*(*(p2)) +
		r3*(*(p3)) +
		r4*(*(p4)) +
		r5*(*(p5)) +
		r6*(*(p6)) +
		r7*(*(p7)) +
		r8*(*(p8));
		
	if (lch[2] <0) lch[2] = 360 + lch[2];
	if (lch[2] >=360) lch[2] = lch[2] - 360;	
		
	lchtolab(lch,labt);		
		
	labo+=3;
	labg+=3;
	labt+=3;
	}	
	
	
McoUnlockHandle(labTableH);							 
return MCO_SUCCESS;
}
Beispiel #5
0
// Modify the table with a list of tweaks
McoStatus Tweak_Patch::Modify_Table(int num_tw,Tweak_Element **tweaks)
{
int i,j,k,m,n = 0;
double	L_dist,a_dist,b_dist;
double  dL,da,db,dc,dh;
double *lab,*labp;
double	L,a,b;
double	L2,a2,b2;
double	scale;
double stepL;
double Lr,Cr;
double lch1[3],lch2[3],labt[3];

stepL = 100.0/32.0;
lab = (double *)McoLockHandle(labTableH);
labp = lab;


if (type == Calibrate_Tweak) 
	{
	for (k=0; k<num_tw; k++) if (tweaks[k]->type == Calibrate_Tweak)
		{
		lab = labp;
		dL = tweaks[k]->lab_p[0] - tweaks[k]->lab_g[0];
		da = tweaks[k]->lab_p[1] - tweaks[k]->lab_g[1];
		db = tweaks[k]->lab_p[2] - tweaks[k]->lab_g[2];

		Lr = tweaks[k]->Lr;
		Cr = tweaks[k]->Cr;
		Cr = Cr * 2.55;
		
		if ((Lr == 0) || (Cr == 0)) return MCO_FAILURE;
		Lr = (12500*0.00008*100+100*(Lr*Lr)-12500*2.995732274)/(Lr*Lr);
		Cr = (12500*0.00008*100+100*(Cr*Cr)-12500*2.995732274)/(Cr*Cr);

			for(i = 0; i < 33; i++){
				L = i*stepL;
				L_dist = L-tweaks[k]->lab_g[0];
				L_dist *= L_dist;
				L_dist *= (100-Lr)*0.00008;
				for(j = -16; j <= 16; j++){				
					if (j < 16) a = j*8;
					else a = 127.0;
					a_dist = a - tweaks[k]->lab_g[1];
					a_dist *= a_dist;
					a_dist *= (100-Cr)*0.00008;
					for(m = -16; m <= 16; m++){
						if (m < 16) b = m*8;
						else b = 127.0;
						b_dist = b - tweaks[k]->lab_g[2];
						b_dist *= b_dist;
						b_dist *= (100-Cr)*0.00008;
						scale = exp(-(L_dist+a_dist+b_dist));	
						//save to a structure
						L2 = L+dL;
						a2 = a+da;
						b2 = b+db;
						lab[0] = (1-scale)*lab[0]+scale*L2;
						lab[1] = (1-scale)*lab[1]+scale*a2;
						lab[2] = (1-scale)*lab[2]+scale*b2;
						lab +=3;
						n+=3;
					}
				}
			}
		}
	}
else if (type == GamutComp_Tweak) 
	{	
	for (k=0; k<num_tw; k++) if (tweaks[k]->type == GamutComp_Tweak)
		{
		lab = labp;
		labtolch(tweaks[k]->lab_p,lch1);
		labtolch(tweaks[k]->lab_g,lch2);
		dL = lch2[0] - lch1[0];
		dc = lch2[1] - lch1[1];
		dh = lch2[2] - lch1[2];
		
		if (dh > 180) dh = dh - 360;
		if (dh < -180) dh = 360 + dh;

		Lr = tweaks[k]->Lr;
		Cr = tweaks[k]->Cr;
		Cr = Cr * 2.55;
		
		if ((Lr == 0) || (Cr == 0)) return MCO_FAILURE;
		Lr = (12500*0.00008*100+100*(Lr*Lr)-12500*2.995732274)/(Lr*Lr);
		Cr = (12500*0.00008*100+100*(Cr*Cr)-12500*2.995732274)/(Cr*Cr);

			for(i = 0; i < 33; i++){
				L = i*stepL;
				L_dist = L-tweaks[k]->lab_d[0];
				L_dist *= L_dist;
				L_dist *= (100-Lr)*0.00008;
				for(j = -16; j <= 16; j++){				
					if (j < 16) a = j*8;
					else a = 127.0;
					a_dist = a - tweaks[k]->lab_d[1];
					a_dist *= a_dist;
					a_dist *= (100-Cr)*0.00008;
					for(m = -16; m <= 16; m++){
						if (m < 16) b = m*8;
						else b = 127.0;
						b_dist = b - tweaks[k]->lab_d[2];
						b_dist *= b_dist;
						b_dist *= (100-Cr)*0.00008;
						scale = exp(-(L_dist+a_dist+b_dist));	
						//save to a structure
						lab[0] = (1-scale)*lab[0]+scale*dL;
						lab[1] = (1-scale)*lab[1]+scale*dc;
						lab[2] = (1-scale)*lab[2]+scale*dh;
						lab +=3;
						n+=3;
					}
				}
			}
		}
	}
McoUnlockHandle(labTableH);
return MCO_SUCCESS;
}