10b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
20b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener// Copyright 2006-2008 Adobe Systems Incorporated
30b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener// All Rights Reserved.
40b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener//
50b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener// NOTICE:  Adobe permits you to use, modify, and distribute this file in
60b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener// accordance with the terms of the Adobe license agreement accompanying it.
70b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
80b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
90b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_camera_profile.cpp#1 $ */
100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/* $DateTime: 2012/05/30 13:28:51 $ */
110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/* $Change: 832332 $ */
120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/* $Author: tknoll $ */
130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_camera_profile.h"
150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_1d_table.h"
170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_assertions.h"
180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_color_space.h"
190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_host.h"
200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_exceptions.h"
210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_image_writer.h"
220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_info.h"
230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_parse_utils.h"
24c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener#include "dng_safe_arithmetic.h"
250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_tag_codes.h"
260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_tag_types.h"
270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_temperature.h"
280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener#include "dng_xy_coord.h"
290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerconst char * kProfileName_Embedded = "Embedded";
330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerconst char * kAdobeCalibrationSignature = "com.adobe";
350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_camera_profile::dng_camera_profile ()
390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	:	fName ()
410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fCalibrationIlluminant1 (lsUnknown)
420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fCalibrationIlluminant2 (lsUnknown)
430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fColorMatrix1 ()
440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fColorMatrix2 ()
450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fForwardMatrix1 ()
460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fForwardMatrix2 ()
470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fReductionMatrix1 ()
480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fReductionMatrix2 ()
490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fFingerprint ()
500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fCopyright ()
510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fEmbedPolicy (pepAllowCopying)
520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fHueSatDeltas1 ()
530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fHueSatDeltas2 ()
540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fHueSatMapEncoding (encoding_Linear)
550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fLookTable ()
560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fLookTableEncoding (encoding_Linear)
570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fBaselineExposureOffset (0, 100)
580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fDefaultBlackRender (defaultBlackRender_Auto)
590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fToneCurve ()
600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fProfileCalibrationSignature ()
610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fUniqueCameraModelRestriction ()
620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fWasReadFromDNG (false)
630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fWasReadFromDisk (false)
640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fWasBuiltinMatrix (false)
650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	,	fWasStubbed (false)
660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fToneCurve.SetInvalid ();
700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_camera_profile::~dng_camera_profile ()
760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerreal64 dng_camera_profile::IlluminantToTemperature (uint32 light)
830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	switch (light)
860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsStandardLightA:
890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsTungsten:
900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return 2850.0;
920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsISOStudioTungsten:
950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return 3200.0;
970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsD50:
1000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return 5000.0;
1020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsD55:
1050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsDaylight:
1060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsFineWeather:
1070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsFlash:
1080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsStandardLightB:
1090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return 5500.0;
1110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsD65:
1140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsStandardLightC:
1150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsCloudyWeather:
1160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return 6500.0;
1180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsD75:
1210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsShade:
1220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return 7500.0;
1240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsDaylightFluorescent:
1270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return (5700.0 + 7100.0) * 0.5;
1290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsDayWhiteFluorescent:
1320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return (4600.0 + 5500.0) * 0.5;
1340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsCoolWhiteFluorescent:
1370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsFluorescent:
1380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return (3800.0 + 4500.0) * 0.5;
1400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsWhiteFluorescent:
1430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return (3250.0 + 3800.0) * 0.5;
1450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case lsWarmWhiteFluorescent:
1480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return (2600.0 + 3250.0) * 0.5;
1500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		default:
1530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return 0.0;
1550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
1580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
1600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/******************************************************************************/
1620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::NormalizeColorMatrix (dng_matrix &m)
1640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
1650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (m.NotEmpty ())
1670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
1680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Find scale factor to normalize the matrix.
1700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_vector coord = m * PCStoXYZ ();
1720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		real64 maxCoord = coord.MaxEntry ();
1740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (maxCoord > 0.0 && (maxCoord < 0.99 || maxCoord > 1.01))
1760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
1770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m.Scale (1.0 / maxCoord);
1790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
1810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Round to four decimal places.
1830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		m.Round (10000);
1850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
1870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
1890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/******************************************************************************/
1910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetColorMatrix1 (const dng_matrix &m)
1930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
1940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fColorMatrix1 = m;
1960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	NormalizeColorMatrix (fColorMatrix1);
1980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	ClearFingerprint ();
2000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/******************************************************************************/
2040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetColorMatrix2 (const dng_matrix &m)
2060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fColorMatrix2 = m;
2090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	NormalizeColorMatrix (fColorMatrix2);
2110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	ClearFingerprint ();
2130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/******************************************************************************/
2170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener// Make sure the forward matrix maps to exactly the PCS.
2190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::NormalizeForwardMatrix (dng_matrix &m)
2210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (m.NotEmpty ())
2240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
2250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_vector cameraOne;
2270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		cameraOne.SetIdentity (m.Cols ());
2290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_vector xyz = m * cameraOne;
2310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		m = PCStoXYZ ().AsDiagonal () *
2330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			Invert (xyz.AsDiagonal ()) *
2340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m;
2350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
2370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/******************************************************************************/
2410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetForwardMatrix1 (const dng_matrix &m)
2430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fForwardMatrix1 = m;
2460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fForwardMatrix1.Round (10000);
2480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	ClearFingerprint ();
2500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/******************************************************************************/
2540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetForwardMatrix2 (const dng_matrix &m)
2560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fForwardMatrix2 = m;
2590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fForwardMatrix2.Round (10000);
2610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	ClearFingerprint ();
2630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
2670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetReductionMatrix1 (const dng_matrix &m)
2690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fReductionMatrix1 = m;
2720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fReductionMatrix1.Round (10000);
2740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	ClearFingerprint ();
2760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/******************************************************************************/
2800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetReductionMatrix2 (const dng_matrix &m)
2820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fReductionMatrix2 = m;
2850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fReductionMatrix2.Round (10000);
2870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	ClearFingerprint ();
2890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
2910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
2930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerbool dng_camera_profile::HasColorMatrix1 () const
2950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
2960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
2970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	return fColorMatrix1.Cols () == 3 &&
2980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fColorMatrix1.Rows ()  > 1;
2990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerbool dng_camera_profile::HasColorMatrix2 () const
3050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	return fColorMatrix2.Cols () == 3 &&
3080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fColorMatrix2.Rows () == fColorMatrix1.Rows ();
3090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetHueSatDeltas1 (const dng_hue_sat_map &deltas1)
3150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fHueSatDeltas1 = deltas1;
3180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	ClearFingerprint ();
3200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetHueSatDeltas2 (const dng_hue_sat_map &deltas2)
3260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fHueSatDeltas2 = deltas2;
3290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	ClearFingerprint ();
3310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetLookTable (const dng_hue_sat_map &table)
3370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fLookTable = table;
3400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	ClearFingerprint ();
3420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerstatic void FingerprintMatrix (dng_md5_printer_stream &printer,
3480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener							   const dng_matrix &matrix)
3490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	tag_matrix tag (0, matrix);
3520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// Tag's Put routine doesn't write the header, only the data
3540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	tag.Put (printer);
3560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerstatic void FingerprintHueSatMap (dng_md5_printer_stream &printer,
3620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								  const dng_hue_sat_map &map)
3630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (map.IsNull ())
3660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		return;
3670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	uint32 hues;
3690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	uint32 sats;
3700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	uint32 vals;
3710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	map.GetDivisions (hues, sats, vals);
3730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	printer.Put_uint32 (hues);
3750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	printer.Put_uint32 (sats);
3760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	printer.Put_uint32 (vals);
3770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	for (uint32 val = 0; val < vals; val++)
3790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		for (uint32 hue = 0; hue < hues; hue++)
3800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			for (uint32 sat = 0; sat < sats; sat++)
3810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
3820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				dng_hue_sat_map::HSBModify modify;
3840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				map.GetDelta (hue, sat, val, modify);
3860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				printer.Put_real32 (modify.fHueShift);
3880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				printer.Put_real32 (modify.fSatScale);
3890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				printer.Put_real32 (modify.fValScale);
3900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
3920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
3940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
3960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
3970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::CalculateFingerprint () const
3980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
3990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	DNG_ASSERT (!fWasStubbed, "CalculateFingerprint on stubbed profile");
4010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	dng_md5_printer_stream printer;
4030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// MD5 hash is always calculated on little endian data.
4050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	printer.SetLittleEndian ();
4070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// The data that we fingerprint closely matches that saved
4090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// by the profile_tag_set class in dng_image_writer.cpp, with
4100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// the exception of the fingerprint itself.
4110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (HasColorMatrix1 ())
4130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
4140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		uint32 colorChannels = ColorMatrix1 ().Rows ();
4160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		printer.Put_uint16 ((uint16) fCalibrationIlluminant1);
4180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		FingerprintMatrix (printer, fColorMatrix1);
4200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fForwardMatrix1.Rows () == fColorMatrix1.Cols () &&
4220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			fForwardMatrix1.Cols () == fColorMatrix1.Rows ())
4230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
4240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			FingerprintMatrix (printer, fForwardMatrix1);
4260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
4280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (colorChannels > 3 && fReductionMatrix1.Rows () *
4300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								 fReductionMatrix1.Cols () == colorChannels * 3)
4310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
4320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			FingerprintMatrix (printer, fReductionMatrix1);
4340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
4360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (HasColorMatrix2 ())
4380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
4390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			printer.Put_uint16 ((uint16) fCalibrationIlluminant2);
4410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			FingerprintMatrix (printer, fColorMatrix2);
4430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			if (fForwardMatrix2.Rows () == fColorMatrix2.Cols () &&
4450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				fForwardMatrix2.Cols () == fColorMatrix2.Rows ())
4460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
4470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				FingerprintMatrix (printer, fForwardMatrix2);
4490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
4510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			if (colorChannels > 3 && fReductionMatrix2.Rows () *
4530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener									 fReductionMatrix2.Cols () == colorChannels * 3)
4540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
4550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				FingerprintMatrix (printer, fReductionMatrix2);
4570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
4590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
4610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		printer.Put (fName.Get    (),
4630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					 fName.Length ());
4640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		printer.Put (fProfileCalibrationSignature.Get    (),
4660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					 fProfileCalibrationSignature.Length ());
4670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		printer.Put_uint32 (fEmbedPolicy);
4690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		printer.Put (fCopyright.Get    (),
4710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					 fCopyright.Length ());
4720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		bool haveHueSat1 = HueSatDeltas1 ().IsValid ();
4740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		bool haveHueSat2 = HueSatDeltas2 ().IsValid () &&
4760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener						   HasColorMatrix2 ();
4770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (haveHueSat1)
4790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
4800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			FingerprintHueSatMap (printer, fHueSatDeltas1);
4820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
4840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (haveHueSat2)
4860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
4870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			FingerprintHueSatMap (printer, fHueSatDeltas2);
4890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
4910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (haveHueSat1 || haveHueSat2)
4930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
4940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			if (fHueSatMapEncoding != 0)
4960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
4970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
4980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				printer.Put_uint32 (fHueSatMapEncoding);
4990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
5010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
5030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fLookTable.IsValid ())
5050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
5060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			FingerprintHueSatMap (printer, fLookTable);
5080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			if (fLookTableEncoding != 0)
5100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
5110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				printer.Put_uint32 (fLookTableEncoding);
5130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
5150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
5170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fBaselineExposureOffset.IsValid ())
5190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
5200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			if (fBaselineExposureOffset.As_real64 () != 0.0)
5220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
5230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				printer.Put_real64 (fBaselineExposureOffset.As_real64 ());
5250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
5270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
5290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fDefaultBlackRender != 0)
5310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
5320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			printer.Put_int32 (fDefaultBlackRender);
5340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
5360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fToneCurve.IsValid ())
5380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
5390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			for (uint32 i = 0; i < fToneCurve.fCoord.size (); i++)
5410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
5420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				printer.Put_real32 ((real32) fToneCurve.fCoord [i].h);
5440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				printer.Put_real32 ((real32) fToneCurve.fCoord [i].v);
5450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
5470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
5490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
5510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fFingerprint = printer.Result ();
5530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
5550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/******************************************************************************/
5570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerbool dng_camera_profile::ValidForwardMatrix (const dng_matrix &m)
5590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
5600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	const real64 kThreshold = 0.01;
5620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (m.NotEmpty ())
5640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
5650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_vector cameraOne;
5670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		cameraOne.SetIdentity (m.Cols ());
5690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_vector xyz = m * cameraOne;
5710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_vector pcs = PCStoXYZ ();
5730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (Abs_real64 (xyz [0] - pcs [0]) > kThreshold ||
5750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			Abs_real64 (xyz [1] - pcs [1]) > kThreshold ||
5760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			Abs_real64 (xyz [2] - pcs [2]) > kThreshold)
5770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
5780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
5800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
5820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
5840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	return true;
5860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
5880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/******************************************************************************/
5900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerbool dng_camera_profile::IsValid (uint32 channels) const
5920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
5930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// For Monochrome images, we ignore the camera profile.
5950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (channels == 1)
5970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
5980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
5990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		return true;
6000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
6020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// ColorMatrix1 is required for all color images.
6040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fColorMatrix1.Cols () != 3 ||
6060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fColorMatrix1.Rows () != channels)
6070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
6080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		#if qDNGValidate
6100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ReportError ("ColorMatrix1 is wrong size");
6120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		#endif
6140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		return false;
6160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
6180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// ColorMatrix2 is optional, but it must be valid if present.
6200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fColorMatrix2.Cols () != 0 ||
6220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fColorMatrix2.Rows () != 0)
6230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
6240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fColorMatrix2.Cols () != 3 ||
6260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			fColorMatrix2.Rows () != channels)
6270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
6280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#if qDNGValidate
6300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			ReportError ("ColorMatrix2 is wrong size");
6320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#endif
6340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
6360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
6380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
6400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// ForwardMatrix1 is optional, but it must be valid if present.
6420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fForwardMatrix1.Cols () != 0 ||
6440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fForwardMatrix1.Rows () != 0)
6450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
6460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fForwardMatrix1.Rows () != 3 ||
6480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			fForwardMatrix1.Cols () != channels)
6490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
6500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#if qDNGValidate
6520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			ReportError ("ForwardMatrix1 is wrong size");
6540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#endif
6560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
6580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
6600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Make sure ForwardMatrix1 does a valid mapping.
6620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (!ValidForwardMatrix (fForwardMatrix1))
6640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
6650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#if qDNGValidate
6670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			ReportError ("ForwardMatrix1 does not map equal camera values to XYZ D50");
6690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#endif
6710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
6730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
6750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
6770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// ForwardMatrix2 is optional, but it must be valid if present.
6790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fForwardMatrix2.Cols () != 0 ||
6810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fForwardMatrix2.Rows () != 0)
6820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
6830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fForwardMatrix2.Rows () != 3 ||
6850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			fForwardMatrix2.Cols () != channels)
6860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
6870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#if qDNGValidate
6890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			ReportError ("ForwardMatrix2 is wrong size");
6910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#endif
6930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
6950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
6970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
6980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Make sure ForwardMatrix2 does a valid mapping.
6990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (!ValidForwardMatrix (fForwardMatrix2))
7010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
7020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#if qDNGValidate
7040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			ReportError ("ForwardMatrix2 does not map equal camera values to XYZ D50");
7060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#endif
7080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
7100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
7120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
7140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// ReductionMatrix1 is optional, but it must be valid if present.
7160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fReductionMatrix1.Cols () != 0 ||
7180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fReductionMatrix1.Rows () != 0)
7190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
7200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fReductionMatrix1.Cols () != channels ||
7220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			fReductionMatrix1.Rows () != 3)
7230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
7240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#if qDNGValidate
7260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			ReportError ("ReductionMatrix1 is wrong size");
7280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#endif
7300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
7320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
7340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
7360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// ReductionMatrix2 is optional, but it must be valid if present.
7380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fReductionMatrix2.Cols () != 0 ||
7400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fReductionMatrix2.Rows () != 0)
7410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
7420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fReductionMatrix2.Cols () != channels ||
7440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			fReductionMatrix2.Rows () != 3)
7450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
7460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#if qDNGValidate
7480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			ReportError ("ReductionMatrix2 is wrong size");
7500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#endif
7520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
7540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
7560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
7580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// Make sure ColorMatrix1 is invertable.
7600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	try
7620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
7630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (fReductionMatrix1.NotEmpty ())
7650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
7660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			(void) Invert (fColorMatrix1,
7680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener						   fReductionMatrix1);
7690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
7710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		else
7730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
7740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			(void) Invert (fColorMatrix1);
7760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
7780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
7800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	catch (...)
7820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
7830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		#if qDNGValidate
7850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ReportError ("ColorMatrix1 is not invertable");
7870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		#endif
7890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		return false;
7910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
7930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	// Make sure ColorMatrix2 is invertable.
7950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fColorMatrix2.NotEmpty ())
7970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
7980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
7990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		try
8000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
8010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			if (fReductionMatrix2.NotEmpty ())
8030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
8040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				(void) Invert (fColorMatrix2,
8060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener							   fReductionMatrix2);
8070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
8090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			else
8110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
8120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				(void) Invert (fColorMatrix2);
8140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
8160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
8180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		catch (...)
8200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
8210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#if qDNGValidate
8230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			ReportError ("ColorMatrix2 is not invertable");
8250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			#endif
8270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
8290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
8310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
8330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	return true;
8350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
8370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
8390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerbool dng_camera_profile::EqualData (const dng_camera_profile &profile) const
8410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
8420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	return fCalibrationIlluminant1				== profile.fCalibrationIlluminant1				&&
8440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fCalibrationIlluminant2				== profile.fCalibrationIlluminant2				&&
8450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fColorMatrix1						== profile.fColorMatrix1						&&
8460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fColorMatrix2						== profile.fColorMatrix2						&&
8470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fForwardMatrix1						== profile.fForwardMatrix1						&&
8480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fForwardMatrix2						== profile.fForwardMatrix2						&&
8490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fReductionMatrix1					== profile.fReductionMatrix1					&&
8500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fReductionMatrix2					== profile.fReductionMatrix2					&&
8510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fHueSatDeltas1						== profile.fHueSatDeltas1						&&
8520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fHueSatDeltas2						== profile.fHueSatDeltas2						&&
8530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fHueSatMapEncoding					== profile.fHueSatMapEncoding					&&
8540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fLookTable							== profile.fLookTable							&&
8550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fLookTableEncoding					== profile.fLookTableEncoding					&&
8560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fDefaultBlackRender					== profile.fDefaultBlackRender					&&
8570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fToneCurve							== profile.fToneCurve							&&
8580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fBaselineExposureOffset.As_real64 () == profile.fBaselineExposureOffset.As_real64 () &&
8590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		   fProfileCalibrationSignature			== profile.fProfileCalibrationSignature;
8600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
8620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
8640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::ReadHueSatMap (dng_stream &stream,
8660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener										dng_hue_sat_map &hueSatMap,
8670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener										uint32 hues,
8680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener										uint32 sats,
8690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener										uint32 vals,
8700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener										bool skipSat0)
8710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
8720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	hueSatMap.SetDivisions (hues, sats, vals);
8740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	for (uint32 val = 0; val < vals; val++)
8760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
8770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		for (uint32 hue = 0; hue < hues; hue++)
8790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
8800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			for (uint32 sat = skipSat0 ? 1 : 0; sat < sats; sat++)
8820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
8830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				dng_hue_sat_map::HSBModify modify;
8850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				modify.fHueShift = stream.Get_real32 ();
8870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				modify.fSatScale = stream.Get_real32 ();
8880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				modify.fValScale = stream.Get_real32 ();
8890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				hueSatMap.SetDelta (hue, sat, val, modify);
8910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
8930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
8950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
8970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
8980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
8990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
9010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::Parse (dng_stream &stream,
9030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								dng_camera_profile_info &profileInfo)
9040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
9050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetUniqueCameraModelRestriction (profileInfo.fUniqueCameraModel.Get ());
9070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (profileInfo.fProfileName.NotEmpty ())
9090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
9100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		SetName (profileInfo.fProfileName.Get ());
9120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
9140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetCopyright (profileInfo.fProfileCopyright.Get ());
9160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetEmbedPolicy (profileInfo.fEmbedPolicy);
9180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetCalibrationIlluminant1 (profileInfo.fCalibrationIlluminant1);
9200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetColorMatrix1 (profileInfo.fColorMatrix1);
9220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (profileInfo.fForwardMatrix1.NotEmpty ())
9240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
9250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		SetForwardMatrix1 (profileInfo.fForwardMatrix1);
9270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
9290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (profileInfo.fReductionMatrix1.NotEmpty ())
9310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
9320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		SetReductionMatrix1 (profileInfo.fReductionMatrix1);
9340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
9360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (profileInfo.fColorMatrix2.NotEmpty ())
9380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
9390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		SetCalibrationIlluminant2 (profileInfo.fCalibrationIlluminant2);
9410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		SetColorMatrix2 (profileInfo.fColorMatrix2);
9430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (profileInfo.fForwardMatrix2.NotEmpty ())
9450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
9460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			SetForwardMatrix2 (profileInfo.fForwardMatrix2);
9480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
9500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (profileInfo.fReductionMatrix2.NotEmpty ())
9520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
9530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			SetReductionMatrix2 (profileInfo.fReductionMatrix2);
9550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
9570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
9590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetProfileCalibrationSignature (profileInfo.fProfileCalibrationSignature.Get ());
9610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (profileInfo.fHueSatDeltas1Offset != 0 &&
9630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		profileInfo.fHueSatDeltas1Count  != 0)
9640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
9650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		TempBigEndian setEndianness (stream, profileInfo.fBigEndian);
9670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		stream.SetReadPosition (profileInfo.fHueSatDeltas1Offset);
9690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
970c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener		bool skipSat0 = (profileInfo.fHueSatDeltas1Count == SafeUint32Mult(
971c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener														   profileInfo.fProfileHues,
972c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener														   SafeUint32Sub(profileInfo.fProfileSats, 1),
973c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener														   profileInfo.fProfileVals, 3));
9740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ReadHueSatMap (stream,
9760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   fHueSatDeltas1,
9770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   profileInfo.fProfileHues,
9780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   profileInfo.fProfileSats,
9790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   profileInfo.fProfileVals,
9800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   skipSat0);
9810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
9830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (profileInfo.fHueSatDeltas2Offset != 0 &&
9850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		profileInfo.fHueSatDeltas2Count  != 0)
9860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
9870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		TempBigEndian setEndianness (stream, profileInfo.fBigEndian);
9890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		stream.SetReadPosition (profileInfo.fHueSatDeltas2Offset);
9910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
992c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener		bool skipSat0 = (profileInfo.fHueSatDeltas2Count == SafeUint32Mult(
993c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener														   profileInfo.fProfileHues,
994c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener														   SafeUint32Sub(profileInfo.fProfileSats, 1),
995c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener														   profileInfo.fProfileVals, 3));
9960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
9970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ReadHueSatMap (stream,
9980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   fHueSatDeltas2,
9990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   profileInfo.fProfileHues,
10000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   profileInfo.fProfileSats,
10010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   profileInfo.fProfileVals,
10020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   skipSat0);
10030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
10050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (profileInfo.fLookTableOffset != 0 &&
10070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		profileInfo.fLookTableCount  != 0)
10080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
10090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		TempBigEndian setEndianness (stream, profileInfo.fBigEndian);
10110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		stream.SetReadPosition (profileInfo.fLookTableOffset);
10130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
1014c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener		bool skipSat0 = (profileInfo.fLookTableCount == SafeUint32Mult(
1015c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener													   profileInfo.fLookTableHues,
1016c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener													   SafeUint32Sub(profileInfo.fLookTableSats, 1),
1017c89552e7ed1e0ea69c69addf2bb5de011188d297Florian Kriener														 profileInfo.fLookTableVals, 3));
10180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ReadHueSatMap (stream,
10200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   fLookTable,
10210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   profileInfo.fLookTableHues,
10220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   profileInfo.fLookTableSats,
10230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   profileInfo.fLookTableVals,
10240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener					   skipSat0);
10250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
10270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if ((profileInfo.fToneCurveCount & 1) == 0)
10290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
10300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		TempBigEndian setEndianness (stream, profileInfo.fBigEndian);
10320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		stream.SetReadPosition (profileInfo.fToneCurveOffset);
10340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		uint32 points = profileInfo.fToneCurveCount / 2;
10360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fToneCurve.fCoord.resize (points);
10380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		for (size_t i = 0; i < points; i++)
10400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
10410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			dng_point_real64 point;
10430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			point.h = stream.Get_real32 ();
10450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			point.v = stream.Get_real32 ();
10460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			fToneCurve.fCoord [i] = point;
10480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
10500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
10520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetHueSatMapEncoding (profileInfo.fHueSatMapEncoding);
10540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetLookTableEncoding (profileInfo.fLookTableEncoding);
10560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetBaselineExposureOffset (profileInfo.fBaselineExposureOffset.As_real64 ());
10580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	SetDefaultBlackRender (profileInfo.fDefaultBlackRender);
10600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
10620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
10640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerbool dng_camera_profile::ParseExtended (dng_stream &stream)
10660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
10670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	try
10690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
10700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_camera_profile_info profileInfo;
10720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (!profileInfo.ParseExtended (stream))
10740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
10750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return false;
10760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
10770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		Parse (stream, profileInfo);
10790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		return true;
10810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
10830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	catch (...)
10850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
10860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Eat parsing errors.
10880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
10900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	return false;
10920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
10940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
10960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
10970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::SetFourColorBayer ()
10980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
10990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	uint32 j;
11010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (!IsValid (3))
11030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
11040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		ThrowProgramError ();
11050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
11060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fColorMatrix1.NotEmpty ())
11080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
11090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_matrix m (4, 3);
11110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		for (j = 0; j < 3; j++)
11130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
11140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m [0] [j] = fColorMatrix1 [0] [j];
11150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m [1] [j] = fColorMatrix1 [1] [j];
11160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m [2] [j] = fColorMatrix1 [2] [j];
11170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m [3] [j] = fColorMatrix1 [1] [j];
11180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
11190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fColorMatrix1 = m;
11210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
11230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fColorMatrix2.NotEmpty ())
11250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
11260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_matrix m (4, 3);
11280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		for (j = 0; j < 3; j++)
11300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
11310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m [0] [j] = fColorMatrix2 [0] [j];
11320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m [1] [j] = fColorMatrix2 [1] [j];
11330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m [2] [j] = fColorMatrix2 [2] [j];
11340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			m [3] [j] = fColorMatrix2 [1] [j];
11350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
11360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		fColorMatrix2 = m;
11380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
11400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fReductionMatrix1.Clear ();
11420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fReductionMatrix2.Clear ();
11430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fForwardMatrix1.Clear ();
11450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fForwardMatrix2.Clear ();
11460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
11480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
11500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienerdng_hue_sat_map * dng_camera_profile::HueSatMapForWhite (const dng_xy_coord &white) const
11520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
11530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (fHueSatDeltas1.IsValid ())
11550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
11560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// If we only have the first table, just use it for any color temperature.
11580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (!fHueSatDeltas2.IsValid ())
11600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
11610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return new dng_hue_sat_map (fHueSatDeltas1);
11630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
11650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Else we need to interpolate based on color temperature.
11670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		real64 temperature1 = CalibrationTemperature1 ();
11690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		real64 temperature2 = CalibrationTemperature2 ();
11700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (temperature1 <= 0.0 ||
11720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			temperature2 <= 0.0 ||
11730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			temperature1 == temperature2)
11740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
11750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			return new dng_hue_sat_map (fHueSatDeltas1);
11770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
11790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		bool reverseOrder = temperature1 > temperature2;
11810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (reverseOrder)
11830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
11840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			real64 temp  = temperature1;
11850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			temperature1 = temperature2;
11860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			temperature2 = temp;
11870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
11880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Convert to temperature/offset space.
11900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		dng_temperature td (white);
11920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Find fraction to weight the first calibration.
11940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		real64 g;
11960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
11970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (td.Temperature () <= temperature1)
11980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			g = 1.0;
11990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		else if (td.Temperature () >= temperature2)
12010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			g = 0.0;
12020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		else
12040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
12050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			real64 invT = 1.0 / td.Temperature ();
12070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			g = (invT                 - (1.0 / temperature2)) /
12090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				((1.0 / temperature1) - (1.0 / temperature2));
12100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
12120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Fix up if we swapped the order.
12140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (reverseOrder)
12160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
12170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			g = 1.0 - g;
12180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
12190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		// Do the interpolation.
12210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		return dng_hue_sat_map::Interpolate (HueSatDeltas1 (),
12230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener											 HueSatDeltas2 (),
12240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener											 g);
12250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
12270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	return NULL;
12290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
12310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
12330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid dng_camera_profile::Stub ()
12350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
12360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	(void) Fingerprint ();
12380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	dng_hue_sat_map nullTable;
12400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fHueSatDeltas1 = nullTable;
12420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fHueSatDeltas2 = nullTable;
12430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fLookTable = nullTable;
12450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fToneCurve.SetInvalid ();
12470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	fWasStubbed = true;
12490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
12510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
12530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid SplitCameraProfileName (const dng_string &name,
12550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener							 dng_string &baseName,
12560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener							 int32 &version)
12570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
12580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	baseName = name;
12600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	version = 0;
12620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	uint32 len = baseName.Length ();
12640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (len > 5 && baseName.EndsWith (" beta"))
12660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
12670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		baseName.Truncate (len - 5);
12690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		version += -10;
12710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
12730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	else if (len > 7)
12750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
12760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		char lastChar = name.Get () [len - 1];
12780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (lastChar >= '0' && lastChar <= '9')
12800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
12810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			dng_string temp = name;
12830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			temp.Truncate (len - 1);
12850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12860b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			if (temp.EndsWith (" beta "))
12870b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
12880b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12890b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				baseName.Truncate (len - 7);
12900b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12910b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				version += ((int32) (lastChar - '0')) - 10;
12920b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12930b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
12940b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12950b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
12960b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12970b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
12980b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
12990b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	len = baseName.Length ();
13000b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13010b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	if (len > 3)
13020b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
13030b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13040b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		char lastChar = name.Get () [len - 1];
13050b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13060b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		if (lastChar >= '0' && lastChar <= '9')
13070b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
13080b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13090b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			dng_string temp = name;
13100b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13110b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			temp.Truncate (len - 1);
13120b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13130b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			if (temp.EndsWith (" v"))
13140b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				{
13150b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13160b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				baseName.Truncate (len - 3);
13170b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13180b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				version += ((int32) (lastChar - '0')) * 100;
13190b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13200b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener				}
13210b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13220b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
13230b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13240b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
13250b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13260b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
13270b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13280b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
13290b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13300b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Krienervoid BuildHueSatMapEncodingTable (dng_memory_allocator &allocator,
13310b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								  uint32 encoding,
13320b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								  AutoPtr<dng_1d_table> &encodeTable,
13330b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								  AutoPtr<dng_1d_table> &decodeTable,
13340b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener								  bool subSample)
13350b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	{
13360b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13370b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	encodeTable.Reset ();
13380b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	decodeTable.Reset ();
13390b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13400b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	switch (encoding)
13410b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		{
13420b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13430b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case encoding_Linear:
13440b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
13450b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13460b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			break;
13470b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13480b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
13490b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13500b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		case encoding_sRGB:
13510b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
13520b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13530b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			encodeTable.Reset (new dng_1d_table);
13540b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			decodeTable.Reset (new dng_1d_table);
13550b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13560b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			const dng_1d_function & curve = dng_function_GammaEncode_sRGB::Get ();
13570b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13580b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			encodeTable->Initialize (allocator,
13590b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener									 curve,
13600b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener									 subSample);
13610b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13620b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			const dng_1d_inverse inverse (curve);
13630b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13640b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			decodeTable->Initialize (allocator,
13650b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener									 inverse,
13660b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener									 subSample);
13670b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13680b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			break;
13690b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13700b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
13710b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13720b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		default:
13730b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			{
13740b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13750b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			DNG_REPORT ("Unsupported hue sat map / look table encoding.");
13760b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13770b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			break;
13780b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13790b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener			}
13800b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13810b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener		}
13820b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13830b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener	}
13840b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener
13850b098b759cf9a2a8659babaf8c3b74e1b48ca604Florian Kriener/*****************************************************************************/
1386