Example #1
0
bool dng_camera_profile::ValidForwardMatrix (const dng_matrix &m)
	{
	
	const real64 kThreshold = 0.01;
	
	if (m.NotEmpty ())
		{
		
		dng_vector cameraOne;
		
		cameraOne.SetIdentity (m.Cols ());
		
		dng_vector xyz = m * cameraOne;
		
		dng_vector pcs = PCStoXYZ ();
		
		if (Abs_real64 (xyz [0] - pcs [0]) > kThreshold ||
			Abs_real64 (xyz [1] - pcs [1]) > kThreshold ||
			Abs_real64 (xyz [2] - pcs [2]) > kThreshold)
			{
			
			return false;
			
			}
			
		}
		
	return true;
	
	}
Example #2
0
dng_xy_coord dng_color_spec::NeutralToXY (const dng_vector &neutral)
	{
	
	const uint32 kMaxPasses = 30;
	
	if (fChannels == 1)
		{
		
		return PCStoXY ();
		
		}
	
	dng_xy_coord last = D50_xy_coord ();
	
	for (uint32 pass = 0; pass < kMaxPasses; pass++)
		{
		
		dng_matrix xyzToCamera = FindXYZtoCamera (last);
		
		dng_xy_coord next = XYZtoXY (Invert (xyzToCamera) * neutral);
		
		if (Abs_real64 (next.x - last.x) +
			Abs_real64 (next.y - last.y) < 0.0000001)
			{
			
			return next;
			
			}
			
		// If we reach the limit without converging, we are most likely
		// in a two value oscillation.  So take the average of the last
		// two estimates and give up.
			
		if (pass == kMaxPasses - 1)
			{
			
			next.x = (last.x + next.x) * 0.5;
			next.y = (last.y + next.y) * 0.5;
			
			}
			
		last = next;
		
		}
		
	return last;
	
	}
Example #3
0
void dng_srational::Set_real64 (real64 x, int32 dd)
	{

	if (x == 0.0)
		{

		*this = dng_srational (0, 1);

		}

	if (dd == 0)
		{

		real64 y = Abs_real64 (x);

		if (y >= 32768.0)
			{
			dd = 1;
			}

		else if (y >= 1.0)
			{
			dd = 32768;
			}

		else
			{
			dd = 32768 * 32768;
			}

		}

	*this = dng_srational (Round_int32 (x * dd), dd);

	}
Example #4
0
static dng_matrix Invert3by3 (const dng_matrix &A)
	{
	
	real64 a00 = A [0] [0];
	real64 a01 = A [0] [1];
	real64 a02 = A [0] [2];
	real64 a10 = A [1] [0];
	real64 a11 = A [1] [1];
	real64 a12 = A [1] [2];
	real64 a20 = A [2] [0];
	real64 a21 = A [2] [1];
	real64 a22 = A [2] [2];
	
	real64 temp [3] [3];

	temp [0] [0] = a11 * a22 - a21 * a12;
	temp [0] [1] = a21 * a02 - a01 * a22;
	temp [0] [2] = a01 * a12 - a11 * a02;
	temp [1] [0] = a20 * a12 - a10 * a22;
	temp [1] [1] = a00 * a22 - a20 * a02;
	temp [1] [2] = a10 * a02 - a00 * a12;
	temp [2] [0] = a10 * a21 - a20 * a11;
	temp [2] [1] = a20 * a01 - a00 * a21;
	temp [2] [2] = a00 * a11 - a10 * a01;

	real64 det = (a00 * temp [0] [0] +
				  a01 * temp [1] [0] +
				  a02 * temp [2] [0]);

	if (Abs_real64 (det) < kNearZero)
		{
		
		ThrowMatrixMath ();
					 
		}

	dng_matrix B (3, 3);
	
	for (uint32 j = 0; j < 3; j++)	
		for (uint32 k = 0; k < 3; k++)
			{
			
			B [j] [k] = temp [j] [k] / det;
			
			}
			
	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;
	
	}
Example #6
0
static dng_matrix InvertNbyN (const dng_matrix &A)
	{
	
	uint32 i;
	uint32 j;
	uint32 k;
	
	uint32 n = A.Rows ();
	
	real64 temp [kMaxColorPlanes] [kMaxColorPlanes * 2];
	
	for (i = 0; i < n; i++)
		for (j = 0; j < n; j++)
			{
			
			temp [i] [j    ] = A [i] [j];
			
			temp [i] [j + n] = (i == j ? 1.0 : 0.0);
			
			}
			
	for (i = 0; i < n; i++)
		{
		
		real64 alpha = temp [i] [i];
		
		if (Abs_real64 (alpha) < kNearZero)
			{
			
			ThrowMatrixMath ();
						 
			}
			
		for (j = 0; j < n * 2; j++)
			{
			
			temp [i] [j] /= alpha;
			
			}
			
		for (k = 0; k < n; k++)
			{
			
			if (i != k)
				{
				
				real64 beta = temp [k] [i];
				
				for (j = 0; j < n * 2; j++)
					{
					
					temp [k] [j] -= beta * temp [i] [j];
					
					}
				
				}
			
			}
			
		}
		
	dng_matrix B (n, n);
	
	for (i = 0; i < n; i++)
		for (j = 0; j < n; j++)
			{
			
			B [i] [j] = temp [i] [j + n];
			
			}
			
	return B;

	}
Example #7
0
void dng_shared::PostParse (dng_host & /* host */,
							dng_exif & /* exif */)
	{

	// Fill in default values for DNG images.

	if (fDNGVersion != 0)
		{

		// Support for DNG versions before 1.0.0.0.

		if (fDNGVersion < dngVersion_1_0_0_0)
			{

			#if qDNGValidate

			ReportWarning ("DNGVersion less than 1.0.0.0");

			#endif

			// The CalibrationIlluminant tags were added just before
			// DNG version 1.0.0.0, and were hardcoded before that.

			fCameraProfile.fCalibrationIlluminant1 = lsStandardLightA;
			fCameraProfile.fCalibrationIlluminant2 = lsD65;

			fDNGVersion = dngVersion_1_0_0_0;

			}

		// Default value for DNGBackwardVersion tag.

		if (fDNGBackwardVersion == 0)
			{

			fDNGBackwardVersion = fDNGVersion & 0xFFFF0000;

			}

		// Check DNGBackwardVersion value.

		if (fDNGBackwardVersion < dngVersion_1_0_0_0)
			{

			#if qDNGValidate

			ReportWarning ("DNGBackwardVersion less than 1.0.0.0");

			#endif

			fDNGBackwardVersion = dngVersion_1_0_0_0;

			}

		if (fDNGBackwardVersion > fDNGVersion)
			{

			#if qDNGValidate

			ReportWarning ("DNGBackwardVersion > DNGVersion");

			#endif

			fDNGBackwardVersion = fDNGVersion;

			}

		// Check UniqueCameraModel.

		if (fUniqueCameraModel.IsEmpty ())
			{

			#if qDNGValidate

			ReportWarning ("Missing or invalid UniqueCameraModel");

			#endif

			fUniqueCameraModel.Set ("Digital Negative");

			}

		// If we don't know the color depth yet, it must be a monochrome DNG.

		if (fCameraProfile.fColorPlanes == 0)
			{

			fCameraProfile.fColorPlanes = 1;

			}

		// Check color info.

		if (fCameraProfile.fColorPlanes > 1)
			{

			// Check illuminant pair.

			if (fCameraProfile.fColorMatrix2.NotEmpty ())
				{

				if (fCameraProfile.fCalibrationIlluminant1 == lsUnknown ||
					(fCameraProfile.fCalibrationIlluminant2 == lsUnknown ||
					(fCameraProfile.fCalibrationIlluminant1 == fCameraProfile.fCalibrationIlluminant2)))
					{

					#if qDNGValidate

					ReportWarning ("Invalid CalibrationIlluminant pair");

					#endif

					fCameraProfile.fColorMatrix2 = dng_matrix ();

					}

				}

			// If the colorimetric reference is the ICC profile PCS, then the
			// data must already be white balanced.  The "AsShotWhiteXY" is required
			// to be the ICC Profile PCS white point.

			if (fColorimetricReference == crICCProfilePCS)
				{

				if (fAsShotNeutral.NotEmpty ())
					{

					#if qDNGValidate

					ReportWarning ("AsShotNeutral not allowed for this "
								   "ColorimetricReference value");

					#endif

					fAsShotNeutral.Clear ();

					}

				dng_xy_coord pcs = PCStoXY ();

				#if qDNGValidate

				if (fAsShotWhiteXY.IsValid ())
					{

					if (Abs_real64 (fAsShotWhiteXY.x - pcs.x) > 0.01 ||
						Abs_real64 (fAsShotWhiteXY.y - pcs.y) > 0.01)
						{

						ReportWarning ("AsShotWhiteXY does not match the ICC Profile PCS");

						}

					}

				#endif

				fAsShotWhiteXY = pcs;

				}

			else
				{

				// Warn if both AsShotNeutral and AsShotWhiteXY are specified.

				if (fAsShotNeutral.NotEmpty () && fAsShotWhiteXY.IsValid ())
					{

					#if qDNGValidate

					ReportWarning ("Both AsShotNeutral and AsShotWhiteXY included");

					#endif

					fAsShotWhiteXY = dng_xy_coord ();

					}

				// Warn if neither AsShotNeutral nor AsShotWhiteXY are specified.

				#if qDNGValidate

				if (fAsShotNeutral.IsEmpty () && !fAsShotWhiteXY.IsValid ())
					{

					ReportWarning ("Neither AsShotNeutral nor AsShotWhiteXY included",
								   "legal but not recommended");

					}

				#endif

				}

			// Default values of calibration signatures are required for legacy
			// compatiblity.

			if (fCameraProfile.fCalibrationIlluminant1 == lsStandardLightA &&
				fCameraProfile.fCalibrationIlluminant2 == lsD65            &&
				fCameraCalibration1.Rows () == fCameraProfile.fColorPlanes &&
				fCameraCalibration1.Cols () == fCameraProfile.fColorPlanes &&
				fCameraCalibration2.Rows () == fCameraProfile.fColorPlanes &&
				fCameraCalibration2.Cols () == fCameraProfile.fColorPlanes &&
				fCameraCalibrationSignature.IsEmpty ()                     &&
				fCameraProfile.fProfileCalibrationSignature.IsEmpty ()     )
				{

				fCameraCalibrationSignature.Set (kAdobeCalibrationSignature);

				fCameraProfile.fProfileCalibrationSignature.Set (kAdobeCalibrationSignature);

				}

			}

		// Check BaselineNoise.

		if (fBaselineNoise.As_real64 () <= 0.0)
			{

			#if qDNGValidate

			ReportWarning ("Invalid BaselineNoise");

			#endif

			fBaselineNoise = dng_urational (1, 1);

			}

		// Check BaselineSharpness.

		if (fBaselineSharpness.As_real64 () <= 0.0)
			{

			#if qDNGValidate

			ReportWarning ("Invalid BaselineSharpness");

			#endif

			fBaselineSharpness = dng_urational (1, 1);

			}

		// Check NoiseProfile.

		if (!fNoiseProfile.IsValid () && fNoiseProfile.NumFunctions () != 0)
			{

			#if qDNGValidate

			ReportWarning ("Invalid NoiseProfile");

			#endif

			fNoiseProfile = dng_noise_profile ();

			}

		// Check LinearResponseLimit.

		if (fLinearResponseLimit.As_real64 () < 0.5 ||
			fLinearResponseLimit.As_real64 () > 1.0)
			{

			#if qDNGValidate

			ReportWarning ("Invalid LinearResponseLimit");

			#endif

			fLinearResponseLimit = dng_urational (1, 1);

			}

		// Check ShadowScale.

		if (fShadowScale.As_real64 () <= 0.0)
			{

			#if qDNGValidate

			ReportWarning ("Invalid ShadowScale");

			#endif

			fShadowScale = dng_urational (1, 1);

			}

		}

	}