real64 dng_1d_concatenate::Evaluate (real64 x) const
	{
	
	real64 y = Pin_real64 (0.0, fFunction1.Evaluate (x), 1.0);
	
	return fFunction2.Evaluate (y);
	
	}
Exemple #2
0
dng_vector_3 XYtoXYZ (const dng_xy_coord &coord)
{

    dng_xy_coord temp = coord;

    // Restrict xy coord to someplace inside the range of real xy coordinates.
    // This prevents math from doing strange things when users specify
    // extreme temperature/tint coordinates.

    temp.x = Pin_real64 (0.000001, temp.x, 0.999999);
    temp.y = Pin_real64 (0.000001, temp.y, 0.999999);

    if (temp.x + temp.y > 0.999999)
    {
        real64 scale = 0.999999 / (temp.x + temp.y);
        temp.x *= scale;
        temp.y *= scale;
    }

    return dng_vector_3 (temp.x / temp.y,
                         1.0,
                         (1.0 - temp.x - temp.y) / temp.y);

}
Exemple #3
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;
	
	}
real64 dng_1d_function::EvaluateInverse (real64 y) const
	{
	
	const uint32 kMaxIterations = 30;
	const real64 kNearZero      = 1.0e-10;
	
	real64 x0 = 0.0;
	real64 y0 = Evaluate (x0);
	
	real64 x1 = 1.0;
	real64 y1 = Evaluate (x1);
	
	for (uint32 iteration = 0; iteration < kMaxIterations; iteration++)		
		{
		
		if (Abs_real64 (y1 - y0) < kNearZero)
			{
			break;
			}
		
		real64 x2 = Pin_real64 (0.0, 
								x1 + (y - y1) * (x1 - x0) / (y1 - y0),
								1.0);
		
		real64 y2 = Evaluate (x2);
		
		x0 = x1;
		y0 = y1;
		
		x1 = x2;
		y1 = y2;
		
		}
	
	return x1;
	
	}
Exemple #5
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);
		
		}
	
	}