/*****************************************************************************/
// Copyright 2006-2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE:  Adobe permits you to use, modify, and distribute this file in
// accordance with the terms of the Adobe license agreement accompanying it.
/*****************************************************************************/

/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_camera_profile.cpp#1 $ */ 
/* $DateTime: 2012/05/30 13:28:51 $ */
/* $Change: 832332 $ */
/* $Author: tknoll $ */

#include "dng_camera_profile.h"

#include "dng_1d_table.h"
#include "dng_assertions.h"
#include "dng_color_space.h"
#include "dng_host.h"
#include "dng_exceptions.h"
#include "dng_image_writer.h"
#include "dng_info.h"
#include "dng_parse_utils.h"
#include "dng_safe_arithmetic.h"
#include "dng_tag_codes.h"
#include "dng_tag_types.h"
#include "dng_temperature.h"
#include "dng_xy_coord.h"

/*****************************************************************************/

const char * kProfileName_Embedded = "Embedded";

const char * kAdobeCalibrationSignature = "com.adobe";

/*****************************************************************************/

dng_camera_profile::dng_camera_profile ()

	:	fName ()
	,	fCalibrationIlluminant1 (lsUnknown)
	,	fCalibrationIlluminant2 (lsUnknown)
	,	fColorMatrix1 ()
	,	fColorMatrix2 ()
	,	fForwardMatrix1 ()
	,	fForwardMatrix2 ()
	,	fReductionMatrix1 ()
	,	fReductionMatrix2 ()
	,	fFingerprint ()
	,	fCopyright ()
	,	fEmbedPolicy (pepAllowCopying)
	,	fHueSatDeltas1 ()
	,	fHueSatDeltas2 ()
	,	fHueSatMapEncoding (encoding_Linear)
	,	fLookTable ()
	,	fLookTableEncoding (encoding_Linear)
	,	fBaselineExposureOffset (0, 100)
	,	fDefaultBlackRender (defaultBlackRender_Auto)
	,	fToneCurve ()
	,	fProfileCalibrationSignature ()
	,	fUniqueCameraModelRestriction ()
	,	fWasReadFromDNG (false)
	,	fWasReadFromDisk (false)
	,	fWasBuiltinMatrix (false)
	,	fWasStubbed (false)
	
	{

	fToneCurve.SetInvalid ();

	}

/*****************************************************************************/

dng_camera_profile::~dng_camera_profile ()
	{
	
	}

/*****************************************************************************/

real64 dng_camera_profile::IlluminantToTemperature (uint32 light)
	{
	
	switch (light)
		{
		
		case lsStandardLightA:
		case lsTungsten:
			{
			return 2850.0;
			}
			
		case lsISOStudioTungsten:
			{
			return 3200.0;
			}
			
		case lsD50:
			{
			return 5000.0;
			}
			
		case lsD55:
		case lsDaylight:
		case lsFineWeather:
		case lsFlash:
		case lsStandardLightB:
			{
			return 5500.0;
			}
			
		case lsD65:
		case lsStandardLightC:
		case lsCloudyWeather:
			{
			return 6500.0;
			}
			
		case lsD75:
		case lsShade:
			{
			return 7500.0;
			}
			
		case lsDaylightFluorescent:
			{
			return (5700.0 + 7100.0) * 0.5;
			}
			
		case lsDayWhiteFluorescent:
			{
			return (4600.0 + 5500.0) * 0.5;
			}
			
		case lsCoolWhiteFluorescent:
		case lsFluorescent:
			{
			return (3800.0 + 4500.0) * 0.5;
			}
			
		case lsWhiteFluorescent:
			{
			return (3250.0 + 3800.0) * 0.5;
			}
			
		case lsWarmWhiteFluorescent:
			{
			return (2600.0 + 3250.0) * 0.5;
			}
			
		default:
			{
			return 0.0;
			}
			
		}
	
	}

/******************************************************************************/

void dng_camera_profile::NormalizeColorMatrix (dng_matrix &m)
	{
	
	if (m.NotEmpty ())
		{
	
		// Find scale factor to normalize the matrix.
		
		dng_vector coord = m * PCStoXYZ ();
		
		real64 maxCoord = coord.MaxEntry ();
		
		if (maxCoord > 0.0 && (maxCoord < 0.99 || maxCoord > 1.01))
			{
			
			m.Scale (1.0 / maxCoord);
			
			}
			
		// Round to four decimal places.
		
		m.Round (10000);
		
		}
			
	}

/******************************************************************************/

void dng_camera_profile::SetColorMatrix1 (const dng_matrix &m)
	{
	
	fColorMatrix1 = m;
	
	NormalizeColorMatrix (fColorMatrix1);

	ClearFingerprint ();
	
	}

/******************************************************************************/

void dng_camera_profile::SetColorMatrix2 (const dng_matrix &m)
	{
	
	fColorMatrix2 = m;
	
	NormalizeColorMatrix (fColorMatrix2);
	
	ClearFingerprint ();

	}
		
/******************************************************************************/

// Make sure the forward matrix maps to exactly the PCS.

void dng_camera_profile::NormalizeForwardMatrix (dng_matrix &m)
	{
	
	if (m.NotEmpty ())
		{
		
		dng_vector cameraOne;
		
		cameraOne.SetIdentity (m.Cols ());
		
		dng_vector xyz = m * cameraOne;
		
		m = PCStoXYZ ().AsDiagonal () *
			Invert (xyz.AsDiagonal ()) *
			m;
		
		}
	
	}

/******************************************************************************/

void dng_camera_profile::SetForwardMatrix1 (const dng_matrix &m)
	{
	
	fForwardMatrix1 = m;
	
	fForwardMatrix1.Round (10000);
	
	ClearFingerprint ();
	
	}

/******************************************************************************/

void dng_camera_profile::SetForwardMatrix2 (const dng_matrix &m)
	{
	
	fForwardMatrix2 = m;
	
	fForwardMatrix2.Round (10000);
	
	ClearFingerprint ();
	
	}

/*****************************************************************************/

void dng_camera_profile::SetReductionMatrix1 (const dng_matrix &m)
	{
	
	fReductionMatrix1 = m;
	
	fReductionMatrix1.Round (10000);
	
	ClearFingerprint ();

	}

/******************************************************************************/

void dng_camera_profile::SetReductionMatrix2 (const dng_matrix &m)
	{
	
	fReductionMatrix2 = m;
	
	fReductionMatrix2.Round (10000);
	
	ClearFingerprint ();

	}

/*****************************************************************************/

bool dng_camera_profile::HasColorMatrix1 () const
	{
	
	return fColorMatrix1.Cols () == 3 &&
		   fColorMatrix1.Rows ()  > 1;
	
	}
		
/*****************************************************************************/

bool dng_camera_profile::HasColorMatrix2 () const
	{

	return fColorMatrix2.Cols () == 3 &&
		   fColorMatrix2.Rows () == fColorMatrix1.Rows ();
	
	}
		
/*****************************************************************************/

void dng_camera_profile::SetHueSatDeltas1 (const dng_hue_sat_map &deltas1)
	{

	fHueSatDeltas1 = deltas1;

	ClearFingerprint ();

	}

/*****************************************************************************/

void dng_camera_profile::SetHueSatDeltas2 (const dng_hue_sat_map &deltas2)
	{

	fHueSatDeltas2 = deltas2;

	ClearFingerprint ();

	}

/*****************************************************************************/

void dng_camera_profile::SetLookTable (const dng_hue_sat_map &table)
	{

	fLookTable = table;

	ClearFingerprint ();

	}

/*****************************************************************************/

static void FingerprintMatrix (dng_md5_printer_stream &printer,
							   const dng_matrix &matrix)
	{

	tag_matrix tag (0, matrix);
	
	// Tag's Put routine doesn't write the header, only the data

	tag.Put (printer);

	}

/*****************************************************************************/

static void FingerprintHueSatMap (dng_md5_printer_stream &printer,
								  const dng_hue_sat_map &map)
	{

	if (map.IsNull ())
		return;

	uint32 hues;
	uint32 sats;
	uint32 vals;

	map.GetDivisions (hues, sats, vals);

	printer.Put_uint32 (hues);
	printer.Put_uint32 (sats);
	printer.Put_uint32 (vals);

	for (uint32 val = 0; val < vals; val++)
		for (uint32 hue = 0; hue < hues; hue++)
			for (uint32 sat = 0; sat < sats; sat++)
				{

				dng_hue_sat_map::HSBModify modify;

				map.GetDelta (hue, sat, val, modify);

				printer.Put_real32 (modify.fHueShift);
				printer.Put_real32 (modify.fSatScale);
				printer.Put_real32 (modify.fValScale);

				}

	}

/*****************************************************************************/

void dng_camera_profile::CalculateFingerprint () const
	{
	
	DNG_ASSERT (!fWasStubbed, "CalculateFingerprint on stubbed profile");

	dng_md5_printer_stream printer;

	// MD5 hash is always calculated on little endian data.

	printer.SetLittleEndian ();
	
	// The data that we fingerprint closely matches that saved
	// by the profile_tag_set class in dng_image_writer.cpp, with
	// the exception of the fingerprint itself.
	
	if (HasColorMatrix1 ())
		{

		uint32 colorChannels = ColorMatrix1 ().Rows ();
		
		printer.Put_uint16 ((uint16) fCalibrationIlluminant1);

		FingerprintMatrix (printer, fColorMatrix1);
		
		if (fForwardMatrix1.Rows () == fColorMatrix1.Cols () &&
			fForwardMatrix1.Cols () == fColorMatrix1.Rows ())
			{
			
			FingerprintMatrix (printer, fForwardMatrix1);
			
			}
		
		if (colorChannels > 3 && fReductionMatrix1.Rows () *
								 fReductionMatrix1.Cols () == colorChannels * 3)
			{
			
			FingerprintMatrix (printer, fReductionMatrix1);
			
			}
		
		if (HasColorMatrix2 ())
			{
			
			printer.Put_uint16 ((uint16) fCalibrationIlluminant2);
			
			FingerprintMatrix (printer, fColorMatrix2);
		
			if (fForwardMatrix2.Rows () == fColorMatrix2.Cols () &&
				fForwardMatrix2.Cols () == fColorMatrix2.Rows ())
				{
				
				FingerprintMatrix (printer, fForwardMatrix2);
				
				}
		
			if (colorChannels > 3 && fReductionMatrix2.Rows () *
									 fReductionMatrix2.Cols () == colorChannels * 3)
				{
				
				FingerprintMatrix (printer, fReductionMatrix2);
				
				}
				
			}
		
		printer.Put (fName.Get    (),
					 fName.Length ());

		printer.Put (fProfileCalibrationSignature.Get    (),
					 fProfileCalibrationSignature.Length ());

		printer.Put_uint32 (fEmbedPolicy);
		
		printer.Put (fCopyright.Get    (),
					 fCopyright.Length ());
					 
		bool haveHueSat1 = HueSatDeltas1 ().IsValid ();
		
		bool haveHueSat2 = HueSatDeltas2 ().IsValid () &&
						   HasColorMatrix2 ();

		if (haveHueSat1)
			{
			
			FingerprintHueSatMap (printer, fHueSatDeltas1);
			
			}
			
		if (haveHueSat2)
			{
			
			FingerprintHueSatMap (printer, fHueSatDeltas2);
			
			}

		if (haveHueSat1 || haveHueSat2)
			{

			if (fHueSatMapEncoding != 0)
				{

				printer.Put_uint32 (fHueSatMapEncoding);

				}
			
			}
			
		if (fLookTable.IsValid ())
			{
			
			FingerprintHueSatMap (printer, fLookTable);

			if (fLookTableEncoding != 0)
				{

				printer.Put_uint32 (fLookTableEncoding);

				}
			
			}

		if (fBaselineExposureOffset.IsValid ())
			{
			
			if (fBaselineExposureOffset.As_real64 () != 0.0)
				{

				printer.Put_real64 (fBaselineExposureOffset.As_real64 ());

				}
			
			}

		if (fDefaultBlackRender != 0)
			{
			
			printer.Put_int32 (fDefaultBlackRender);
			
			}
			
		if (fToneCurve.IsValid ())
			{
			
			for (uint32 i = 0; i < fToneCurve.fCoord.size (); i++)
				{
				
				printer.Put_real32 ((real32) fToneCurve.fCoord [i].h);
				printer.Put_real32 ((real32) fToneCurve.fCoord [i].v);
				
				}
				
			}
			
		}

	fFingerprint = printer.Result ();

	}

/******************************************************************************/

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;
	
	}

/******************************************************************************/

bool dng_camera_profile::IsValid (uint32 channels) const
	{
	
	// For Monochrome images, we ignore the camera profile.
		
	if (channels == 1)
		{
		
		return true;
		
		}
		
	// ColorMatrix1 is required for all color images.
		
	if (fColorMatrix1.Cols () != 3 ||
		fColorMatrix1.Rows () != channels)
		{
		
		#if qDNGValidate
	
		ReportError ("ColorMatrix1 is wrong size");
					 
		#endif
					 
		return false;
		
		}
		
	// ColorMatrix2 is optional, but it must be valid if present.
	
	if (fColorMatrix2.Cols () != 0 ||
		fColorMatrix2.Rows () != 0)
		{
		
		if (fColorMatrix2.Cols () != 3 ||
			fColorMatrix2.Rows () != channels)
			{
			
			#if qDNGValidate
		
			ReportError ("ColorMatrix2 is wrong size");
						 
			#endif
					 
			return false;
			
			}
		
		}
		
	// ForwardMatrix1 is optional, but it must be valid if present.
	
	if (fForwardMatrix1.Cols () != 0 ||
		fForwardMatrix1.Rows () != 0)
		{
		
		if (fForwardMatrix1.Rows () != 3 ||
			fForwardMatrix1.Cols () != channels)
			{
			
			#if qDNGValidate
		
			ReportError ("ForwardMatrix1 is wrong size");
						 
			#endif
						 
			return false;
			
			}

		// Make sure ForwardMatrix1 does a valid mapping.
		
		if (!ValidForwardMatrix (fForwardMatrix1))
			{
			
			#if qDNGValidate
		
			ReportError ("ForwardMatrix1 does not map equal camera values to XYZ D50");
						 
			#endif
						 
			return false;
		
			}
				
		}

	// ForwardMatrix2 is optional, but it must be valid if present.
	
	if (fForwardMatrix2.Cols () != 0 ||
		fForwardMatrix2.Rows () != 0)
		{
		
		if (fForwardMatrix2.Rows () != 3 ||
			fForwardMatrix2.Cols () != channels)
			{
			
			#if qDNGValidate
		
			ReportError ("ForwardMatrix2 is wrong size");
						 
			#endif
						 
			return false;
			
			}

		// Make sure ForwardMatrix2 does a valid mapping.
		
		if (!ValidForwardMatrix (fForwardMatrix2))
			{
			
			#if qDNGValidate
		
			ReportError ("ForwardMatrix2 does not map equal camera values to XYZ D50");
						 
			#endif
						 
			return false;
		
			}
				
		}

	// ReductionMatrix1 is optional, but it must be valid if present.
	
	if (fReductionMatrix1.Cols () != 0 ||
		fReductionMatrix1.Rows () != 0)
		{
		
		if (fReductionMatrix1.Cols () != channels ||
			fReductionMatrix1.Rows () != 3)
			{
			
			#if qDNGValidate
		
			ReportError ("ReductionMatrix1 is wrong size");
						 
			#endif
					 
			return false;
			
			}
		
		}
	
	// ReductionMatrix2 is optional, but it must be valid if present.
	
	if (fReductionMatrix2.Cols () != 0 ||
		fReductionMatrix2.Rows () != 0)
		{
		
		if (fReductionMatrix2.Cols () != channels ||
			fReductionMatrix2.Rows () != 3)
			{
			
			#if qDNGValidate
		
			ReportError ("ReductionMatrix2 is wrong size");
						 
			#endif
					 
			return false;
			
			}
		
		}
		
	// Make sure ColorMatrix1 is invertable.
	
	try
		{
		
		if (fReductionMatrix1.NotEmpty ())
			{
			
			(void) Invert (fColorMatrix1,
						   fReductionMatrix1);
			
			}
			
		else
			{
		
			(void) Invert (fColorMatrix1);
			
			}
		
		}
		
	catch (...)
		{
			
		#if qDNGValidate
	
		ReportError ("ColorMatrix1 is not invertable");
					 
		#endif
					 
		return false;
	
		}
		
	// Make sure ColorMatrix2 is invertable.
	
	if (fColorMatrix2.NotEmpty ())
		{
						
		try
			{
			
			if (fReductionMatrix2.NotEmpty ())
				{
				
				(void) Invert (fColorMatrix2,
							   fReductionMatrix2);
				
				}
				
			else
				{
			
				(void) Invert (fColorMatrix2);
				
				}

			}
			
		catch (...)
			{
				
			#if qDNGValidate
	
			ReportError ("ColorMatrix2 is not invertable");
						 
			#endif
						 
			return false;
		
			}
			
		}

	return true;
	
	}
		
/*****************************************************************************/

bool dng_camera_profile::EqualData (const dng_camera_profile &profile) const
	{

	return fCalibrationIlluminant1				== profile.fCalibrationIlluminant1				&&
		   fCalibrationIlluminant2				== profile.fCalibrationIlluminant2				&&
		   fColorMatrix1						== profile.fColorMatrix1						&&
		   fColorMatrix2						== profile.fColorMatrix2						&&
		   fForwardMatrix1						== profile.fForwardMatrix1						&&
		   fForwardMatrix2						== profile.fForwardMatrix2						&&
		   fReductionMatrix1					== profile.fReductionMatrix1					&&
		   fReductionMatrix2					== profile.fReductionMatrix2					&&
		   fHueSatDeltas1						== profile.fHueSatDeltas1						&&
		   fHueSatDeltas2						== profile.fHueSatDeltas2						&&
		   fHueSatMapEncoding					== profile.fHueSatMapEncoding					&&
		   fLookTable							== profile.fLookTable							&&
		   fLookTableEncoding					== profile.fLookTableEncoding					&&
		   fDefaultBlackRender					== profile.fDefaultBlackRender					&&
		   fToneCurve							== profile.fToneCurve							&&
		   fBaselineExposureOffset.As_real64 () == profile.fBaselineExposureOffset.As_real64 () &&
		   fProfileCalibrationSignature			== profile.fProfileCalibrationSignature;

	}
		
/*****************************************************************************/

void dng_camera_profile::ReadHueSatMap (dng_stream &stream,
										dng_hue_sat_map &hueSatMap,
										uint32 hues,
										uint32 sats,
										uint32 vals,
										bool skipSat0)
	{

	hueSatMap.SetDivisions (hues, sats, vals);

	for (uint32 val = 0; val < vals; val++)
		{

		for (uint32 hue = 0; hue < hues; hue++)
			{

			for (uint32 sat = skipSat0 ? 1 : 0; sat < sats; sat++)
				{

				dng_hue_sat_map::HSBModify modify;

				modify.fHueShift = stream.Get_real32 ();
				modify.fSatScale = stream.Get_real32 ();
				modify.fValScale = stream.Get_real32 ();

				hueSatMap.SetDelta (hue, sat, val, modify);
				
				}
				
			}
			
		}
	
	}

/*****************************************************************************/

void dng_camera_profile::Parse (dng_stream &stream,
								dng_camera_profile_info &profileInfo)
	{
	
	SetUniqueCameraModelRestriction (profileInfo.fUniqueCameraModel.Get ());

	if (profileInfo.fProfileName.NotEmpty ())
		{
		
		SetName (profileInfo.fProfileName.Get ());
		
		}
	
	SetCopyright (profileInfo.fProfileCopyright.Get ());

	SetEmbedPolicy (profileInfo.fEmbedPolicy);

	SetCalibrationIlluminant1 (profileInfo.fCalibrationIlluminant1);
			
	SetColorMatrix1 (profileInfo.fColorMatrix1);
			
	if (profileInfo.fForwardMatrix1.NotEmpty ())
		{
		
		SetForwardMatrix1 (profileInfo.fForwardMatrix1);
		
		}
		
	if (profileInfo.fReductionMatrix1.NotEmpty ())
		{
		
		SetReductionMatrix1 (profileInfo.fReductionMatrix1);
		
		}
		
	if (profileInfo.fColorMatrix2.NotEmpty ())
		{
		
		SetCalibrationIlluminant2 (profileInfo.fCalibrationIlluminant2);
		
		SetColorMatrix2 (profileInfo.fColorMatrix2);
					
		if (profileInfo.fForwardMatrix2.NotEmpty ())
			{
			
			SetForwardMatrix2 (profileInfo.fForwardMatrix2);
			
			}
		
		if (profileInfo.fReductionMatrix2.NotEmpty ())
			{
			
			SetReductionMatrix2 (profileInfo.fReductionMatrix2);
			
			}
		
		}

	SetProfileCalibrationSignature (profileInfo.fProfileCalibrationSignature.Get ());

	if (profileInfo.fHueSatDeltas1Offset != 0 &&
		profileInfo.fHueSatDeltas1Count  != 0)
		{

		TempBigEndian setEndianness (stream, profileInfo.fBigEndian);

		stream.SetReadPosition (profileInfo.fHueSatDeltas1Offset);
		
		bool skipSat0 = (profileInfo.fHueSatDeltas1Count == SafeUint32Mult(
														   profileInfo.fProfileHues,
														   SafeUint32Sub(profileInfo.fProfileSats, 1),
														   profileInfo.fProfileVals, 3));

		ReadHueSatMap (stream,
					   fHueSatDeltas1,
					   profileInfo.fProfileHues,
					   profileInfo.fProfileSats,
					   profileInfo.fProfileVals,
					   skipSat0);

		}

	if (profileInfo.fHueSatDeltas2Offset != 0 &&
		profileInfo.fHueSatDeltas2Count  != 0)
		{

		TempBigEndian setEndianness (stream, profileInfo.fBigEndian);

		stream.SetReadPosition (profileInfo.fHueSatDeltas2Offset);

		bool skipSat0 = (profileInfo.fHueSatDeltas2Count == SafeUint32Mult(
														   profileInfo.fProfileHues,
														   SafeUint32Sub(profileInfo.fProfileSats, 1),
														   profileInfo.fProfileVals, 3));

		ReadHueSatMap (stream,
					   fHueSatDeltas2,
					   profileInfo.fProfileHues,
					   profileInfo.fProfileSats,
					   profileInfo.fProfileVals,
					   skipSat0);

		}

	if (profileInfo.fLookTableOffset != 0 &&
		profileInfo.fLookTableCount  != 0)
		{

		TempBigEndian setEndianness (stream, profileInfo.fBigEndian);

		stream.SetReadPosition (profileInfo.fLookTableOffset);

		bool skipSat0 = (profileInfo.fLookTableCount == SafeUint32Mult(
													   profileInfo.fLookTableHues,
													   SafeUint32Sub(profileInfo.fLookTableSats, 1),
														 profileInfo.fLookTableVals, 3));

		ReadHueSatMap (stream,
					   fLookTable,
					   profileInfo.fLookTableHues,
					   profileInfo.fLookTableSats,
					   profileInfo.fLookTableVals,
					   skipSat0);

		}

	if ((profileInfo.fToneCurveCount & 1) == 0)
		{

		TempBigEndian setEndianness (stream, profileInfo.fBigEndian);

		stream.SetReadPosition (profileInfo.fToneCurveOffset);

		uint32 points = profileInfo.fToneCurveCount / 2;

		fToneCurve.fCoord.resize (points);

		for (size_t i = 0; i < points; i++)
			{

			dng_point_real64 point;

			point.h = stream.Get_real32 ();
			point.v = stream.Get_real32 ();

			fToneCurve.fCoord [i] = point;

			}
			
		}

	SetHueSatMapEncoding (profileInfo.fHueSatMapEncoding);
		
	SetLookTableEncoding (profileInfo.fLookTableEncoding);

	SetBaselineExposureOffset (profileInfo.fBaselineExposureOffset.As_real64 ());

	SetDefaultBlackRender (profileInfo.fDefaultBlackRender);
		
	}
		
/*****************************************************************************/

bool dng_camera_profile::ParseExtended (dng_stream &stream)
	{

	try
		{
		
		dng_camera_profile_info profileInfo;
		
		if (!profileInfo.ParseExtended (stream))
			{
			return false;
			}
			
		Parse (stream, profileInfo);

		return true;

		}
		
	catch (...)
		{
		
		// Eat parsing errors.
		
		}

	return false;

	}

/*****************************************************************************/

void dng_camera_profile::SetFourColorBayer ()
	{
	
	uint32 j;
	
	if (!IsValid (3))
		{
		ThrowProgramError ();
		}
		
	if (fColorMatrix1.NotEmpty ())
		{
		
		dng_matrix m (4, 3);
		
		for (j = 0; j < 3; j++)
			{
			m [0] [j] = fColorMatrix1 [0] [j];
			m [1] [j] = fColorMatrix1 [1] [j];
			m [2] [j] = fColorMatrix1 [2] [j];
			m [3] [j] = fColorMatrix1 [1] [j];
			}
			
		fColorMatrix1 = m;
		
		}
	
	if (fColorMatrix2.NotEmpty ())
		{
		
		dng_matrix m (4, 3);
		
		for (j = 0; j < 3; j++)
			{
			m [0] [j] = fColorMatrix2 [0] [j];
			m [1] [j] = fColorMatrix2 [1] [j];
			m [2] [j] = fColorMatrix2 [2] [j];
			m [3] [j] = fColorMatrix2 [1] [j];
			}
			
		fColorMatrix2 = m;
		
		}
			
	fReductionMatrix1.Clear ();
	fReductionMatrix2.Clear ();
	
	fForwardMatrix1.Clear ();
	fForwardMatrix2.Clear ();
	
	}

/*****************************************************************************/

dng_hue_sat_map * dng_camera_profile::HueSatMapForWhite (const dng_xy_coord &white) const
	{
	
	if (fHueSatDeltas1.IsValid ())
		{

		// If we only have the first table, just use it for any color temperature.
		
		if (!fHueSatDeltas2.IsValid ())
			{
			
			return new dng_hue_sat_map (fHueSatDeltas1);
			
			}
			
		// Else we need to interpolate based on color temperature.
		
		real64 temperature1 = CalibrationTemperature1 ();
		real64 temperature2 = CalibrationTemperature2 ();
		
		if (temperature1 <= 0.0 ||
			temperature2 <= 0.0 ||
			temperature1 == temperature2)
			{
			
			return new dng_hue_sat_map (fHueSatDeltas1);
			
			}
			
		bool reverseOrder = temperature1 > temperature2;
		
		if (reverseOrder)
			{
			real64 temp  = temperature1;
			temperature1 = temperature2;
			temperature2 = temp;
			}

		// Convert to temperature/offset space.
		
		dng_temperature td (white);
		
		// Find fraction to weight the first calibration.
		
		real64 g;
		
		if (td.Temperature () <= temperature1)
			g = 1.0;
		
		else if (td.Temperature () >= temperature2)
			g = 0.0;
		
		else
			{
			
			real64 invT = 1.0 / td.Temperature ();
			
			g = (invT                 - (1.0 / temperature2)) /
				((1.0 / temperature1) - (1.0 / temperature2));
				
			}
			
		// Fix up if we swapped the order.
		
		if (reverseOrder)
			{
			g = 1.0 - g;
			}
		
		// Do the interpolation.
		
		return dng_hue_sat_map::Interpolate (HueSatDeltas1 (),
											 HueSatDeltas2 (),
											 g);
		
		}
		
	return NULL;

	}

/*****************************************************************************/

void dng_camera_profile::Stub ()
	{
	
	(void) Fingerprint ();
	
	dng_hue_sat_map nullTable;
	
	fHueSatDeltas1 = nullTable;
	fHueSatDeltas2 = nullTable;
	
	fLookTable = nullTable;
	
	fToneCurve.SetInvalid ();
	
	fWasStubbed = true;
	
	}

/*****************************************************************************/

void SplitCameraProfileName (const dng_string &name,
							 dng_string &baseName,
							 int32 &version)
	{
	
	baseName = name;
	
	version = 0;
	
	uint32 len = baseName.Length ();
	
	if (len > 5 && baseName.EndsWith (" beta"))
		{
		
		baseName.Truncate (len - 5);
		
		version += -10;
		
		}
		
	else if (len > 7)
		{
		
		char lastChar = name.Get () [len - 1];
		
		if (lastChar >= '0' && lastChar <= '9')
			{
			
			dng_string temp = name;
			
			temp.Truncate (len - 1);
			
			if (temp.EndsWith (" beta "))
				{
				
				baseName.Truncate (len - 7);
				
				version += ((int32) (lastChar - '0')) - 10;
				
				}
				
			}
			
		}
		
	len = baseName.Length ();
	
	if (len > 3)
		{
		
		char lastChar = name.Get () [len - 1];
		
		if (lastChar >= '0' && lastChar <= '9')
			{
			
			dng_string temp = name;
			
			temp.Truncate (len - 1);
			
			if (temp.EndsWith (" v"))
				{
				
				baseName.Truncate (len - 3);
				
				version += ((int32) (lastChar - '0')) * 100;
				
				}
				
			}
			
		}

	}

/*****************************************************************************/

void BuildHueSatMapEncodingTable (dng_memory_allocator &allocator,
								  uint32 encoding,
								  AutoPtr<dng_1d_table> &encodeTable,
								  AutoPtr<dng_1d_table> &decodeTable,
								  bool subSample)
	{

	encodeTable.Reset ();
	decodeTable.Reset ();
	
	switch (encoding)
		{
		
		case encoding_Linear:
			{

			break;

			}
		
		case encoding_sRGB:
			{

			encodeTable.Reset (new dng_1d_table);
			decodeTable.Reset (new dng_1d_table);

			const dng_1d_function & curve = dng_function_GammaEncode_sRGB::Get ();

			encodeTable->Initialize (allocator,
									 curve,
									 subSample);

			const dng_1d_inverse inverse (curve);

			decodeTable->Initialize (allocator,
									 inverse,
									 subSample);

			break;

			}

		default:
			{

			DNG_REPORT ("Unsupported hue sat map / look table encoding.");

			break;

			}
		
		}

	}
							
/*****************************************************************************/
