Esempio n. 1
0
dng_matrix_3by3 MapWhiteMatrix (const dng_xy_coord &white1,
						        const dng_xy_coord &white2)
	{
	
	// Use the linearized Bradford adaptation matrix.
	
	dng_matrix_3by3 Mb ( 0.8951,  0.2664, -0.1614,
		 		        -0.7502,  1.7135,  0.0367,
		  			     0.0389, -0.0685,  1.0296);
	
	dng_vector_3 w1 = Mb * XYtoXYZ (white1);
	dng_vector_3 w2 = Mb * XYtoXYZ (white2);
	
	// Negative white coordinates are kind of meaningless.
	
	w1 [0] = Max_real64 (w1 [0], 0.0);
	w1 [1] = Max_real64 (w1 [1], 0.0);
	w1 [2] = Max_real64 (w1 [2], 0.0);
	
	w2 [0] = Max_real64 (w2 [0], 0.0);
	w2 [1] = Max_real64 (w2 [1], 0.0);
	w2 [2] = Max_real64 (w2 [2], 0.0);

	// Limit scaling to something reasonable.
	
	dng_matrix_3by3 A;
	
	A [0] [0] = Pin_real64 (0.1, w1 [0] > 0.0 ? w2 [0] / w1 [0] : 10.0, 10.0);
	A [1] [1] = Pin_real64 (0.1, w1 [1] > 0.0 ? w2 [1] / w1 [1] : 10.0, 10.0);
	A [2] [2] = Pin_real64 (0.1, w1 [2] > 0.0 ? w2 [2] / w1 [2] : 10.0, 10.0);
		
	dng_matrix_3by3 B = Invert (Mb) * A * Mb;
	
	return B;
	
	}
Esempio n. 2
0
dng_vector_3 PCStoXYZ ()
{

    return XYtoXYZ (PCStoXY ());

}
Esempio n. 3
0
void dng_color_spec::SetWhiteXY (const dng_xy_coord &white)
	{
	
	fWhiteXY = white;
	
	// Deal with monochrome cameras.
	
	if (fChannels == 1)
		{
		
		fCameraWhite.SetIdentity (1);
		
		fCameraToPCS = PCStoXYZ ().AsColumn ();
		
		return;
		
		}
	
	// Interpolate an matric values for this white point.
	
	dng_matrix colorMatrix;
	dng_matrix forwardMatrix;
	dng_matrix reductionMatrix;
	dng_matrix cameraCalibration;
	
	colorMatrix = FindXYZtoCamera (fWhiteXY,
								   &forwardMatrix,
								   &reductionMatrix,
								   &cameraCalibration);
								   
	// Find the camera white values.
	
	fCameraWhite = colorMatrix * XYtoXYZ (fWhiteXY);
	
	real64 whiteScale = 1.0 / MaxEntry (fCameraWhite);
	
	for (uint32 j = 0; j < fChannels; j++)
		{
		
		// We don't support non-positive values for camera neutral values.
		
		fCameraWhite [j] = Pin_real64 (0.001,
									   whiteScale * fCameraWhite [j], 
									   1.0);
		
		}
		
	// Find PCS to Camera transform. Scale matrix so PCS white can just be
	// reached when the first camera channel saturates
	
	fPCStoCamera = colorMatrix * MapWhiteMatrix (PCStoXY (), fWhiteXY);
		
	real64 scale = MaxEntry (fPCStoCamera * PCStoXYZ ());
	
	fPCStoCamera = (1.0 / scale) * fPCStoCamera;

	// If we have a forward matrix, then just use that.
	
	if (forwardMatrix.NotEmpty ())
		{
		
		dng_matrix individualToReference = Invert (fAnalogBalance * cameraCalibration);
		
		dng_vector refCameraWhite = individualToReference * fCameraWhite;
		
		fCameraToPCS = forwardMatrix *
					   Invert (refCameraWhite.AsDiagonal ()) *
					   individualToReference;
		
		}
		
	// Else we need to use the adapt in XYZ method.
	
	else
		{

		// Invert this PCS to camera matrix.  Note that if there are more than three
		// camera channels, this inversion is non-unique.
		
		fCameraToPCS = Invert (fPCStoCamera, reductionMatrix);
		
		}
	
	}