From ab987e10f154f5536bb8fd936ae0966e909fa969 Mon Sep 17 00:00:00 2001 From: luxagraf Date: Thu, 15 Jun 2023 15:58:59 -0500 Subject: added all my scripts --- gpr/source/lib/dng_sdk/dng_camera_profile.cpp | 1381 +++++++++++++++++++++++++ 1 file changed, 1381 insertions(+) create mode 100644 gpr/source/lib/dng_sdk/dng_camera_profile.cpp (limited to 'gpr/source/lib/dng_sdk/dng_camera_profile.cpp') diff --git a/gpr/source/lib/dng_sdk/dng_camera_profile.cpp b/gpr/source/lib/dng_sdk/dng_camera_profile.cpp new file mode 100644 index 0000000..6983b6d --- /dev/null +++ b/gpr/source/lib/dng_sdk/dng_camera_profile.cpp @@ -0,0 +1,1381 @@ +/*****************************************************************************/ +// Copyright 2006-2008 Adobe Systems Incorporated +// All Rights Reserved. +// +// NOTICE: Adobe permits you to use, modify, and distribute this file in +// accordance with the terms of the Adobe license agreement accompanying it. +/*****************************************************************************/ + +/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_camera_profile.cpp#1 $ */ +/* $DateTime: 2012/05/30 13:28:51 $ */ +/* $Change: 832332 $ */ +/* $Author: tknoll $ */ + +#include "dng_camera_profile.h" + +#include "dng_1d_table.h" +#include "dng_assertions.h" +#include "dng_color_space.h" +#include "dng_host.h" +#include "dng_exceptions.h" +#include "dng_image_writer.h" +#include "dng_info.h" +#include "dng_parse_utils.h" +#include "dng_tag_codes.h" +#include "dng_tag_types.h" +#include "dng_temperature.h" +#include "dng_xy_coord.h" + +/*****************************************************************************/ + +const char * kProfileName_Embedded = "Embedded"; + +const char * kAdobeCalibrationSignature = "com.adobe"; + +/*****************************************************************************/ + +dng_camera_profile::dng_camera_profile () + + : fName () + , fCalibrationIlluminant1 (lsUnknown) + , fCalibrationIlluminant2 (lsUnknown) + , fColorMatrix1 () + , fColorMatrix2 () + , fForwardMatrix1 () + , fForwardMatrix2 () + , fReductionMatrix1 () + , fReductionMatrix2 () + , fFingerprint () + , fCopyright () + , fEmbedPolicy (pepAllowCopying) + , fHueSatDeltas1 () + , fHueSatDeltas2 () + , fHueSatMapEncoding (encoding_Linear) + , fLookTable () + , fLookTableEncoding (encoding_Linear) + , fBaselineExposureOffset (0, 100) + , fDefaultBlackRender (defaultBlackRender_Auto) + , fToneCurve () + , fProfileCalibrationSignature () + , fUniqueCameraModelRestriction () + , fWasReadFromDNG (false) + , fWasReadFromDisk (false) + , fWasBuiltinMatrix (false) + , fWasStubbed (false) + + { + + fToneCurve.SetInvalid (); + + } + +/*****************************************************************************/ + +dng_camera_profile::~dng_camera_profile () + { + + } + +/*****************************************************************************/ + +real64 dng_camera_profile::IlluminantToTemperature (uint32 light) + { + + switch (light) + { + + case lsStandardLightA: + case lsTungsten: + { + return 2850.0; + } + + case lsISOStudioTungsten: + { + return 3200.0; + } + + case lsD50: + { + return 5000.0; + } + + case lsD55: + case lsDaylight: + case lsFineWeather: + case lsFlash: + case lsStandardLightB: + { + return 5500.0; + } + + case lsD65: + case lsStandardLightC: + case lsCloudyWeather: + { + return 6500.0; + } + + case lsD75: + case lsShade: + { + return 7500.0; + } + + case lsDaylightFluorescent: + { + return (5700.0 + 7100.0) * 0.5; + } + + case lsDayWhiteFluorescent: + { + return (4600.0 + 5500.0) * 0.5; + } + + case lsCoolWhiteFluorescent: + case lsFluorescent: + { + return (3800.0 + 4500.0) * 0.5; + } + + case lsWhiteFluorescent: + { + return (3250.0 + 3800.0) * 0.5; + } + + case lsWarmWhiteFluorescent: + { + return (2600.0 + 3250.0) * 0.5; + } + + default: + { + return 0.0; + } + + } + + } + +/******************************************************************************/ + +void dng_camera_profile::NormalizeColorMatrix (dng_matrix &m) + { + + if (m.NotEmpty ()) + { + + // Find scale factor to normalize the matrix. + + dng_vector coord = m * PCStoXYZ (); + + real64 maxCoord = coord.MaxEntry (); + + if (maxCoord > 0.0 && (maxCoord < 0.99 || maxCoord > 1.01)) + { + + m.Scale (1.0 / maxCoord); + + } + + // Round to four decimal places. + + m.Round (10000); + + } + + } + +/******************************************************************************/ + +void dng_camera_profile::SetColorMatrix1 (const dng_matrix &m) + { + + fColorMatrix1 = m; + + NormalizeColorMatrix (fColorMatrix1); + + ClearFingerprint (); + + } + +/******************************************************************************/ + +void dng_camera_profile::SetColorMatrix2 (const dng_matrix &m) + { + + fColorMatrix2 = m; + + NormalizeColorMatrix (fColorMatrix2); + + ClearFingerprint (); + + } + +/******************************************************************************/ + +// Make sure the forward matrix maps to exactly the PCS. + +void dng_camera_profile::NormalizeForwardMatrix (dng_matrix &m) + { + + if (m.NotEmpty ()) + { + + dng_vector cameraOne; + + cameraOne.SetIdentity (m.Cols ()); + + dng_vector xyz = m * cameraOne; + + m = PCStoXYZ ().AsDiagonal () * + Invert (xyz.AsDiagonal ()) * + m; + + } + + } + +/******************************************************************************/ + +void dng_camera_profile::SetForwardMatrix1 (const dng_matrix &m) + { + + fForwardMatrix1 = m; + + fForwardMatrix1.Round (10000); + + ClearFingerprint (); + + } + +/******************************************************************************/ + +void dng_camera_profile::SetForwardMatrix2 (const dng_matrix &m) + { + + fForwardMatrix2 = m; + + fForwardMatrix2.Round (10000); + + ClearFingerprint (); + + } + +/*****************************************************************************/ + +void dng_camera_profile::SetReductionMatrix1 (const dng_matrix &m) + { + + fReductionMatrix1 = m; + + fReductionMatrix1.Round (10000); + + ClearFingerprint (); + + } + +/******************************************************************************/ + +void dng_camera_profile::SetReductionMatrix2 (const dng_matrix &m) + { + + fReductionMatrix2 = m; + + fReductionMatrix2.Round (10000); + + ClearFingerprint (); + + } + +/*****************************************************************************/ + +bool dng_camera_profile::HasColorMatrix1 () const + { + + return fColorMatrix1.Cols () == 3 && + fColorMatrix1.Rows () > 1; + + } + +/*****************************************************************************/ + +bool dng_camera_profile::HasColorMatrix2 () const + { + + return fColorMatrix2.Cols () == 3 && + fColorMatrix2.Rows () == fColorMatrix1.Rows (); + + } + +/*****************************************************************************/ + +void dng_camera_profile::SetHueSatDeltas1 (const dng_hue_sat_map &deltas1) + { + + fHueSatDeltas1 = deltas1; + + ClearFingerprint (); + + } + +/*****************************************************************************/ + +void dng_camera_profile::SetHueSatDeltas2 (const dng_hue_sat_map &deltas2) + { + + fHueSatDeltas2 = deltas2; + + ClearFingerprint (); + + } + +/*****************************************************************************/ + +void dng_camera_profile::SetLookTable (const dng_hue_sat_map &table) + { + + fLookTable = table; + + ClearFingerprint (); + + } + +/*****************************************************************************/ + +static void FingerprintMatrix (dng_md5_printer_stream &printer, + const dng_matrix &matrix) + { + + tag_matrix tag (0, matrix); + + // Tag's Put routine doesn't write the header, only the data + + tag.Put (printer); + + } + +/*****************************************************************************/ + +static void FingerprintHueSatMap (dng_md5_printer_stream &printer, + const dng_hue_sat_map &map) + { + + if (map.IsNull ()) + return; + + uint32 hues; + uint32 sats; + uint32 vals; + + map.GetDivisions (hues, sats, vals); + + printer.Put_uint32 (hues); + printer.Put_uint32 (sats); + printer.Put_uint32 (vals); + + for (uint32 val = 0; val < vals; val++) + for (uint32 hue = 0; hue < hues; hue++) + for (uint32 sat = 0; sat < sats; sat++) + { + + dng_hue_sat_map::HSBModify modify; + + map.GetDelta (hue, sat, val, modify); + + printer.Put_real32 (modify.fHueShift); + printer.Put_real32 (modify.fSatScale); + printer.Put_real32 (modify.fValScale); + + } + + } + +/*****************************************************************************/ + +void dng_camera_profile::CalculateFingerprint () const + { + + DNG_ASSERT (!fWasStubbed, "CalculateFingerprint on stubbed profile"); + + dng_md5_printer_stream printer; + + // MD5 hash is always calculated on little endian data. + + printer.SetLittleEndian (); + + // The data that we fingerprint closely matches that saved + // by the profile_tag_set class in dng_image_writer.cpp, with + // the exception of the fingerprint itself. + + if (HasColorMatrix1 ()) + { + + uint32 colorChannels = ColorMatrix1 ().Rows (); + + printer.Put_uint16 ((uint16) fCalibrationIlluminant1); + + FingerprintMatrix (printer, fColorMatrix1); + + if (fForwardMatrix1.Rows () == fColorMatrix1.Cols () && + fForwardMatrix1.Cols () == fColorMatrix1.Rows ()) + { + + FingerprintMatrix (printer, fForwardMatrix1); + + } + + if (colorChannels > 3 && fReductionMatrix1.Rows () * + fReductionMatrix1.Cols () == colorChannels * 3) + { + + FingerprintMatrix (printer, fReductionMatrix1); + + } + + if (HasColorMatrix2 ()) + { + + printer.Put_uint16 ((uint16) fCalibrationIlluminant2); + + FingerprintMatrix (printer, fColorMatrix2); + + if (fForwardMatrix2.Rows () == fColorMatrix2.Cols () && + fForwardMatrix2.Cols () == fColorMatrix2.Rows ()) + { + + FingerprintMatrix (printer, fForwardMatrix2); + + } + + if (colorChannels > 3 && fReductionMatrix2.Rows () * + fReductionMatrix2.Cols () == colorChannels * 3) + { + + FingerprintMatrix (printer, fReductionMatrix2); + + } + + } + + printer.Put (fName.Get (), + fName.Length ()); + + printer.Put (fProfileCalibrationSignature.Get (), + fProfileCalibrationSignature.Length ()); + + printer.Put_uint32 (fEmbedPolicy); + + printer.Put (fCopyright.Get (), + fCopyright.Length ()); + + bool haveHueSat1 = HueSatDeltas1 ().IsValid (); + + bool haveHueSat2 = HueSatDeltas2 ().IsValid () && + HasColorMatrix2 (); + + if (haveHueSat1) + { + + FingerprintHueSatMap (printer, fHueSatDeltas1); + + } + + if (haveHueSat2) + { + + FingerprintHueSatMap (printer, fHueSatDeltas2); + + } + + if (haveHueSat1 || haveHueSat2) + { + + if (fHueSatMapEncoding != 0) + { + + printer.Put_uint32 (fHueSatMapEncoding); + + } + + } + + if (fLookTable.IsValid ()) + { + + FingerprintHueSatMap (printer, fLookTable); + + if (fLookTableEncoding != 0) + { + + printer.Put_uint32 (fLookTableEncoding); + + } + + } + + if (fBaselineExposureOffset.IsValid ()) + { + + if (fBaselineExposureOffset.As_real64 () != 0.0) + { + + printer.Put_real64 (fBaselineExposureOffset.As_real64 ()); + + } + + } + + if (fDefaultBlackRender != 0) + { + + printer.Put_int32 (fDefaultBlackRender); + + } + + if (fToneCurve.IsValid ()) + { + + for (uint32 i = 0; i < fToneCurve.fCoord.size (); i++) + { + + printer.Put_real32 ((real32) fToneCurve.fCoord [i].h); + printer.Put_real32 ((real32) fToneCurve.fCoord [i].v); + + } + + } + + } + + fFingerprint = printer.Result (); + + } + +/******************************************************************************/ + +bool dng_camera_profile::ValidForwardMatrix (const dng_matrix &m) + { + + const real64 kThreshold = 0.01; + + if (m.NotEmpty ()) + { + + dng_vector cameraOne; + + cameraOne.SetIdentity (m.Cols ()); + + dng_vector xyz = m * cameraOne; + + dng_vector pcs = PCStoXYZ (); + + if (Abs_real64 (xyz [0] - pcs [0]) > kThreshold || + Abs_real64 (xyz [1] - pcs [1]) > kThreshold || + Abs_real64 (xyz [2] - pcs [2]) > kThreshold) + { + + return false; + + } + + } + + return true; + + } + +/******************************************************************************/ + +bool dng_camera_profile::IsValid (uint32 channels) const + { + + // For Monochrome images, we ignore the camera profile. + + if (channels == 1) + { + + return true; + + } + + // ColorMatrix1 is required for all color images. + + if (fColorMatrix1.Cols () != 3 || + fColorMatrix1.Rows () != channels) + { + + #if qDNGValidate + + ReportError ("ColorMatrix1 is wrong size"); + + #endif + + return false; + + } + + // ColorMatrix2 is optional, but it must be valid if present. + + if (fColorMatrix2.Cols () != 0 || + fColorMatrix2.Rows () != 0) + { + + if (fColorMatrix2.Cols () != 3 || + fColorMatrix2.Rows () != channels) + { + + #if qDNGValidate + + ReportError ("ColorMatrix2 is wrong size"); + + #endif + + return false; + + } + + } + + // ForwardMatrix1 is optional, but it must be valid if present. + + if (fForwardMatrix1.Cols () != 0 || + fForwardMatrix1.Rows () != 0) + { + + if (fForwardMatrix1.Rows () != 3 || + fForwardMatrix1.Cols () != channels) + { + + #if qDNGValidate + + ReportError ("ForwardMatrix1 is wrong size"); + + #endif + + return false; + + } + + // Make sure ForwardMatrix1 does a valid mapping. + + if (!ValidForwardMatrix (fForwardMatrix1)) + { + + #if qDNGValidate + + ReportError ("ForwardMatrix1 does not map equal camera values to XYZ D50"); + + #endif + + return false; + + } + + } + + // ForwardMatrix2 is optional, but it must be valid if present. + + if (fForwardMatrix2.Cols () != 0 || + fForwardMatrix2.Rows () != 0) + { + + if (fForwardMatrix2.Rows () != 3 || + fForwardMatrix2.Cols () != channels) + { + + #if qDNGValidate + + ReportError ("ForwardMatrix2 is wrong size"); + + #endif + + return false; + + } + + // Make sure ForwardMatrix2 does a valid mapping. + + if (!ValidForwardMatrix (fForwardMatrix2)) + { + + #if qDNGValidate + + ReportError ("ForwardMatrix2 does not map equal camera values to XYZ D50"); + + #endif + + return false; + + } + + } + + // ReductionMatrix1 is optional, but it must be valid if present. + + if (fReductionMatrix1.Cols () != 0 || + fReductionMatrix1.Rows () != 0) + { + + if (fReductionMatrix1.Cols () != channels || + fReductionMatrix1.Rows () != 3) + { + + #if qDNGValidate + + ReportError ("ReductionMatrix1 is wrong size"); + + #endif + + return false; + + } + + } + + // ReductionMatrix2 is optional, but it must be valid if present. + + if (fReductionMatrix2.Cols () != 0 || + fReductionMatrix2.Rows () != 0) + { + + if (fReductionMatrix2.Cols () != channels || + fReductionMatrix2.Rows () != 3) + { + + #if qDNGValidate + + ReportError ("ReductionMatrix2 is wrong size"); + + #endif + + return false; + + } + + } + + // Make sure ColorMatrix1 is invertable. + + try + { + + if (fReductionMatrix1.NotEmpty ()) + { + + (void) Invert (fColorMatrix1, + fReductionMatrix1); + + } + + else + { + + (void) Invert (fColorMatrix1); + + } + + } + + catch (...) + { + + #if qDNGValidate + + ReportError ("ColorMatrix1 is not invertable"); + + #endif + + return false; + + } + + // Make sure ColorMatrix2 is invertable. + + if (fColorMatrix2.NotEmpty ()) + { + + try + { + + if (fReductionMatrix2.NotEmpty ()) + { + + (void) Invert (fColorMatrix2, + fReductionMatrix2); + + } + + else + { + + (void) Invert (fColorMatrix2); + + } + + } + + catch (...) + { + + #if qDNGValidate + + ReportError ("ColorMatrix2 is not invertable"); + + #endif + + return false; + + } + + } + + return true; + + } + +/*****************************************************************************/ + +bool dng_camera_profile::EqualData (const dng_camera_profile &profile) const + { + + return fCalibrationIlluminant1 == profile.fCalibrationIlluminant1 && + fCalibrationIlluminant2 == profile.fCalibrationIlluminant2 && + fColorMatrix1 == profile.fColorMatrix1 && + fColorMatrix2 == profile.fColorMatrix2 && + fForwardMatrix1 == profile.fForwardMatrix1 && + fForwardMatrix2 == profile.fForwardMatrix2 && + fReductionMatrix1 == profile.fReductionMatrix1 && + fReductionMatrix2 == profile.fReductionMatrix2 && + fHueSatDeltas1 == profile.fHueSatDeltas1 && + fHueSatDeltas2 == profile.fHueSatDeltas2 && + fHueSatMapEncoding == profile.fHueSatMapEncoding && + fLookTable == profile.fLookTable && + fLookTableEncoding == profile.fLookTableEncoding && + fDefaultBlackRender == profile.fDefaultBlackRender && + fToneCurve == profile.fToneCurve && + fBaselineExposureOffset.As_real64 () == profile.fBaselineExposureOffset.As_real64 () && + fProfileCalibrationSignature == profile.fProfileCalibrationSignature; + + } + +/*****************************************************************************/ + +void dng_camera_profile::ReadHueSatMap (dng_stream &stream, + dng_hue_sat_map &hueSatMap, + uint32 hues, + uint32 sats, + uint32 vals, + bool skipSat0) + { + + hueSatMap.SetDivisions (hues, sats, vals); + + for (uint32 val = 0; val < vals; val++) + { + + for (uint32 hue = 0; hue < hues; hue++) + { + + for (uint32 sat = skipSat0 ? 1 : 0; sat < sats; sat++) + { + + dng_hue_sat_map::HSBModify modify; + + modify.fHueShift = stream.Get_real32 (); + modify.fSatScale = stream.Get_real32 (); + modify.fValScale = stream.Get_real32 (); + + hueSatMap.SetDelta (hue, sat, val, modify); + + } + + } + + } + + } + +/*****************************************************************************/ + +void dng_camera_profile::Parse (dng_stream &stream, + dng_camera_profile_info &profileInfo) + { + + SetUniqueCameraModelRestriction (profileInfo.fUniqueCameraModel.Get ()); + + if (profileInfo.fProfileName.NotEmpty ()) + { + + SetName (profileInfo.fProfileName.Get ()); + + } + + SetCopyright (profileInfo.fProfileCopyright.Get ()); + + SetEmbedPolicy (profileInfo.fEmbedPolicy); + + SetCalibrationIlluminant1 (profileInfo.fCalibrationIlluminant1); + + SetColorMatrix1 (profileInfo.fColorMatrix1); + + if (profileInfo.fForwardMatrix1.NotEmpty ()) + { + + SetForwardMatrix1 (profileInfo.fForwardMatrix1); + + } + + if (profileInfo.fReductionMatrix1.NotEmpty ()) + { + + SetReductionMatrix1 (profileInfo.fReductionMatrix1); + + } + + if (profileInfo.fColorMatrix2.NotEmpty ()) + { + + SetCalibrationIlluminant2 (profileInfo.fCalibrationIlluminant2); + + SetColorMatrix2 (profileInfo.fColorMatrix2); + + if (profileInfo.fForwardMatrix2.NotEmpty ()) + { + + SetForwardMatrix2 (profileInfo.fForwardMatrix2); + + } + + if (profileInfo.fReductionMatrix2.NotEmpty ()) + { + + SetReductionMatrix2 (profileInfo.fReductionMatrix2); + + } + + } + + SetProfileCalibrationSignature (profileInfo.fProfileCalibrationSignature.Get ()); + + if (profileInfo.fHueSatDeltas1Offset != 0 && + profileInfo.fHueSatDeltas1Count != 0) + { + + TempBigEndian setEndianness (stream, profileInfo.fBigEndian); + + stream.SetReadPosition (profileInfo.fHueSatDeltas1Offset); + + bool skipSat0 = (profileInfo.fHueSatDeltas1Count == profileInfo.fProfileHues * + (profileInfo.fProfileSats - 1) * + profileInfo.fProfileVals * 3); + + ReadHueSatMap (stream, + fHueSatDeltas1, + profileInfo.fProfileHues, + profileInfo.fProfileSats, + profileInfo.fProfileVals, + skipSat0); + + } + + if (profileInfo.fHueSatDeltas2Offset != 0 && + profileInfo.fHueSatDeltas2Count != 0) + { + + TempBigEndian setEndianness (stream, profileInfo.fBigEndian); + + stream.SetReadPosition (profileInfo.fHueSatDeltas2Offset); + + bool skipSat0 = (profileInfo.fHueSatDeltas2Count == profileInfo.fProfileHues * + (profileInfo.fProfileSats - 1) * + profileInfo.fProfileVals * 3); + + ReadHueSatMap (stream, + fHueSatDeltas2, + profileInfo.fProfileHues, + profileInfo.fProfileSats, + profileInfo.fProfileVals, + skipSat0); + + } + + if (profileInfo.fLookTableOffset != 0 && + profileInfo.fLookTableCount != 0) + { + + TempBigEndian setEndianness (stream, profileInfo.fBigEndian); + + stream.SetReadPosition (profileInfo.fLookTableOffset); + + bool skipSat0 = (profileInfo.fLookTableCount == profileInfo.fLookTableHues * + (profileInfo.fLookTableSats - 1) * + profileInfo.fLookTableVals * 3); + + ReadHueSatMap (stream, + fLookTable, + profileInfo.fLookTableHues, + profileInfo.fLookTableSats, + profileInfo.fLookTableVals, + skipSat0); + + } + + if ((profileInfo.fToneCurveCount & 1) == 0) + { + + TempBigEndian setEndianness (stream, profileInfo.fBigEndian); + + stream.SetReadPosition (profileInfo.fToneCurveOffset); + + uint32 points = profileInfo.fToneCurveCount / 2; + + fToneCurve.fCoord.resize (points); + + for (size_t i = 0; i < points; i++) + { + + dng_point_real64 point; + + point.h = stream.Get_real32 (); + point.v = stream.Get_real32 (); + + fToneCurve.fCoord [i] = point; + + } + + } + + SetHueSatMapEncoding (profileInfo.fHueSatMapEncoding); + + SetLookTableEncoding (profileInfo.fLookTableEncoding); + + SetBaselineExposureOffset (profileInfo.fBaselineExposureOffset.As_real64 ()); + + SetDefaultBlackRender (profileInfo.fDefaultBlackRender); + + } + +/*****************************************************************************/ + +bool dng_camera_profile::ParseExtended (dng_stream &stream) + { + + try + { + + dng_camera_profile_info profileInfo; + + if (!profileInfo.ParseExtended (stream)) + { + return false; + } + + Parse (stream, profileInfo); + + return true; + + } + + catch (...) + { + + // Eat parsing errors. + + } + + return false; + + } + +/*****************************************************************************/ + +void dng_camera_profile::SetFourColorBayer () + { + + uint32 j; + + if (!IsValid (3)) + { + ThrowProgramError (); + } + + if (fColorMatrix1.NotEmpty ()) + { + + dng_matrix m (4, 3); + + for (j = 0; j < 3; j++) + { + m [0] [j] = fColorMatrix1 [0] [j]; + m [1] [j] = fColorMatrix1 [1] [j]; + m [2] [j] = fColorMatrix1 [2] [j]; + m [3] [j] = fColorMatrix1 [1] [j]; + } + + fColorMatrix1 = m; + + } + + if (fColorMatrix2.NotEmpty ()) + { + + dng_matrix m (4, 3); + + for (j = 0; j < 3; j++) + { + m [0] [j] = fColorMatrix2 [0] [j]; + m [1] [j] = fColorMatrix2 [1] [j]; + m [2] [j] = fColorMatrix2 [2] [j]; + m [3] [j] = fColorMatrix2 [1] [j]; + } + + fColorMatrix2 = m; + + } + + fReductionMatrix1.Clear (); + fReductionMatrix2.Clear (); + + fForwardMatrix1.Clear (); + fForwardMatrix2.Clear (); + + } + +/*****************************************************************************/ + +dng_hue_sat_map * dng_camera_profile::HueSatMapForWhite (const dng_xy_coord &white) const + { + + if (fHueSatDeltas1.IsValid ()) + { + + // If we only have the first table, just use it for any color temperature. + + if (!fHueSatDeltas2.IsValid ()) + { + + return new dng_hue_sat_map (fHueSatDeltas1); + + } + + // Else we need to interpolate based on color temperature. + + real64 temperature1 = CalibrationTemperature1 (); + real64 temperature2 = CalibrationTemperature2 (); + + if (temperature1 <= 0.0 || + temperature2 <= 0.0 || + temperature1 == temperature2) + { + + return new dng_hue_sat_map (fHueSatDeltas1); + + } + + bool reverseOrder = temperature1 > temperature2; + + if (reverseOrder) + { + real64 temp = temperature1; + temperature1 = temperature2; + temperature2 = temp; + } + + // Convert to temperature/offset space. + + dng_temperature td (white); + + // Find fraction to weight the first calibration. + + real64 g; + + if (td.Temperature () <= temperature1) + g = 1.0; + + else if (td.Temperature () >= temperature2) + g = 0.0; + + else + { + + real64 invT = 1.0 / td.Temperature (); + + g = (invT - (1.0 / temperature2)) / + ((1.0 / temperature1) - (1.0 / temperature2)); + + } + + // Fix up if we swapped the order. + + if (reverseOrder) + { + g = 1.0 - g; + } + + // Do the interpolation. + + return dng_hue_sat_map::Interpolate (HueSatDeltas1 (), + HueSatDeltas2 (), + g); + + } + + return NULL; + + } + +/*****************************************************************************/ + +void dng_camera_profile::Stub () + { + + (void) Fingerprint (); + + dng_hue_sat_map nullTable; + + fHueSatDeltas1 = nullTable; + fHueSatDeltas2 = nullTable; + + fLookTable = nullTable; + + fToneCurve.SetInvalid (); + + fWasStubbed = true; + + } + +/*****************************************************************************/ + +void SplitCameraProfileName (const dng_string &name, + dng_string &baseName, + int32 &version) + { + + baseName = name; + + version = 0; + + uint32 len = baseName.Length (); + + if (len > 5 && baseName.EndsWith (" beta")) + { + + baseName.Truncate (len - 5); + + version += -10; + + } + + else if (len > 7) + { + + char lastChar = name.Get () [len - 1]; + + if (lastChar >= '0' && lastChar <= '9') + { + + dng_string temp = name; + + temp.Truncate (len - 1); + + if (temp.EndsWith (" beta ")) + { + + baseName.Truncate (len - 7); + + version += ((int32) (lastChar - '0')) - 10; + + } + + } + + } + + len = baseName.Length (); + + if (len > 3) + { + + char lastChar = name.Get () [len - 1]; + + if (lastChar >= '0' && lastChar <= '9') + { + + dng_string temp = name; + + temp.Truncate (len - 1); + + if (temp.EndsWith (" v")) + { + + baseName.Truncate (len - 3); + + version += ((int32) (lastChar - '0')) * 100; + + } + + } + + } + + } + +/*****************************************************************************/ + +void BuildHueSatMapEncodingTable (dng_memory_allocator &allocator, + uint32 encoding, + AutoPtr &encodeTable, + AutoPtr &decodeTable, + bool subSample) + { + + encodeTable.Reset (); + decodeTable.Reset (); + + switch (encoding) + { + + case encoding_Linear: + { + + break; + + } + + case encoding_sRGB: + { + + encodeTable.Reset (new dng_1d_table); + decodeTable.Reset (new dng_1d_table); + + const dng_1d_function & curve = dng_function_GammaEncode_sRGB::Get (); + + encodeTable->Initialize (allocator, + curve, + subSample); + + const dng_1d_inverse inverse (curve); + + decodeTable->Initialize (allocator, + inverse, + subSample); + + break; + + } + + default: + { + + DNG_REPORT ("Unsupported hue sat map / look table encoding."); + + break; + + } + + } + + } + +/*****************************************************************************/ -- cgit v1.2.3-70-g09d2