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