From 5611c1bea71ce7e67f24ba84ceb63e53054c4331 Mon Sep 17 00:00:00 2001 From: Vincent Maas Date: Thu, 28 Dec 2023 21:48:33 +0100 Subject: [PATCH] add Nvidia digital vibrance/hue control, add creation of custom color profile, add support for LG A2/A3 service menu unlocker --- ColorControl.sln | 20 + ColorControl/ColorControl.csproj | 12 +- ColorControl/Forms/InfoPanel.cs | 12 +- ColorControl/MainForm.Designer.cs | 35 + ColorControl/MainForm.cs | 20 +- ColorControl/MainForm.resx | 3 + ColorControl/Program.cs | 1 + .../Services/GameLauncher/GameService.cs | 9 +- ColorControl/Services/LG/LgPanel.cs | 2 +- .../Services/NVIDIA/NvPanel.Designer.cs | 28 +- ColorControl/Services/NVIDIA/NvPanel.cs | 95 +- ColorControl/Services/NVIDIA/NvPanel.resx | 2 +- ColorControl/Services/NVIDIA/NvPreset.cs | 32 +- ColorControl/Services/NVIDIA/NvService.cs | 46 +- ColorControl/XForms/ColorProfileViewModel.cs | 260 ++++ ColorControl/XForms/ColorProfileWindow.xaml | 104 ++ .../XForms/ColorProfileWindow.xaml.cs | 152 +++ LittleCms/CmsContext.cs | 64 + LittleCms/CmsDefinition.cs | 539 ++++++++ LittleCms/CmsError.cs | 84 ++ LittleCms/CmsExtension.cs | 34 + LittleCms/CmsGlobal.cs | 20 + LittleCms/CmsNative.cs | 958 ++++++++++++++ LittleCms/CmsObject.cs | 46 + LittleCms/CmsPixelFormat.cs | 145 +++ LittleCms/CmsTransform.cs | 52 + LittleCms/Data/BlittableDataTagSignature.cs | 20 + .../Data/ChromaticAdaptationTagSignature.cs | 31 + LittleCms/Data/ISafeTagSignature.cs | 16 + LittleCms/Data/IccDataTagSignature.cs | 32 + LittleCms/Data/MLU.cs | 111 ++ LittleCms/Data/MluTagSignature.cs | 24 + LittleCms/Data/RgbToneCurve.cs | 7 + LittleCms/Data/SafeTagSignature.cs | 41 + LittleCms/Data/TagNotFoundException.cs | 29 + LittleCms/Data/ToneCurve.cs | 65 + LittleCms/Data/ToneCurveTagSignature.cs | 24 + .../Data/VideoCardGammaTableTagSignature.cs | 34 + LittleCms/IccProfile.cs | 259 ++++ LittleCms/LittleCms.csproj | 16 + LittleCms/lcms2.dll | Bin 0 -> 736768 bytes MHC2Gen/CmsFunctions.cs | 96 ++ MHC2Gen/Extension.cs | 24 + MHC2Gen/GenerateProfileCommand.cs | 29 + MHC2Gen/IccContext.cs | 1134 +++++++++++++++++ MHC2Gen/MHC2Gen.csproj | 55 + MHC2Gen/MHC2Wrapper.cs | 26 + MHC2Gen/Primaries.cs | 52 + MHC2Gen/ST2084.cs | 38 + Shared/Common/Utils.cs | 5 + .../NVIDIA/NvColorEnhancementSettings.cs | 26 + Shared/Forms/FormUtils.cs | 10 + Shared/Native/CCD.cs | 295 +++-- Shared/Native/CmsFunctions.cs | 87 ++ Shared/Services/WinApiAdminService.cs | 13 + Shared/XForms/BaseViewModel.cs | 52 + novideo_srgb/Novideo.cs | 4 + 57 files changed, 5277 insertions(+), 153 deletions(-) create mode 100644 ColorControl/XForms/ColorProfileViewModel.cs create mode 100644 ColorControl/XForms/ColorProfileWindow.xaml create mode 100644 ColorControl/XForms/ColorProfileWindow.xaml.cs create mode 100644 LittleCms/CmsContext.cs create mode 100644 LittleCms/CmsDefinition.cs create mode 100644 LittleCms/CmsError.cs create mode 100644 LittleCms/CmsExtension.cs create mode 100644 LittleCms/CmsGlobal.cs create mode 100644 LittleCms/CmsNative.cs create mode 100644 LittleCms/CmsObject.cs create mode 100644 LittleCms/CmsPixelFormat.cs create mode 100644 LittleCms/CmsTransform.cs create mode 100644 LittleCms/Data/BlittableDataTagSignature.cs create mode 100644 LittleCms/Data/ChromaticAdaptationTagSignature.cs create mode 100644 LittleCms/Data/ISafeTagSignature.cs create mode 100644 LittleCms/Data/IccDataTagSignature.cs create mode 100644 LittleCms/Data/MLU.cs create mode 100644 LittleCms/Data/MluTagSignature.cs create mode 100644 LittleCms/Data/RgbToneCurve.cs create mode 100644 LittleCms/Data/SafeTagSignature.cs create mode 100644 LittleCms/Data/TagNotFoundException.cs create mode 100644 LittleCms/Data/ToneCurve.cs create mode 100644 LittleCms/Data/ToneCurveTagSignature.cs create mode 100644 LittleCms/Data/VideoCardGammaTableTagSignature.cs create mode 100644 LittleCms/IccProfile.cs create mode 100644 LittleCms/LittleCms.csproj create mode 100644 LittleCms/lcms2.dll create mode 100644 MHC2Gen/CmsFunctions.cs create mode 100644 MHC2Gen/Extension.cs create mode 100644 MHC2Gen/GenerateProfileCommand.cs create mode 100644 MHC2Gen/IccContext.cs create mode 100644 MHC2Gen/MHC2Gen.csproj create mode 100644 MHC2Gen/MHC2Wrapper.cs create mode 100644 MHC2Gen/Primaries.cs create mode 100644 MHC2Gen/ST2084.cs create mode 100644 Shared/Contracts/NVIDIA/NvColorEnhancementSettings.cs create mode 100644 Shared/Native/CmsFunctions.cs create mode 100644 Shared/XForms/BaseViewModel.cs diff --git a/ColorControl.sln b/ColorControl.sln index 1b8d8f4..6a445c8 100644 --- a/ColorControl.sln +++ b/ColorControl.sln @@ -15,6 +15,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NLogViewer", "NLogViewer\NL EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared", "Shared\Shared.csproj", "{8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LittleCms", "LittleCms\LittleCms.csproj", "{42D251AE-42AF-4C0D-B163-7C7A13C4A9A6}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MHC2Gen", "MHC2Gen\MHC2Gen.csproj", "{9FDF741F-0ECF-46DB-8671-AB11ACEB9F41}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -71,6 +75,22 @@ Global {8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Release|Any CPU.Build.0 = Release|Any CPU {8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Release|x64.ActiveCfg = Release|Any CPU {8F38D6B0-82DA-4DD1-89EB-918D8A18AEB1}.Release|x64.Build.0 = Release|Any CPU + {42D251AE-42AF-4C0D-B163-7C7A13C4A9A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42D251AE-42AF-4C0D-B163-7C7A13C4A9A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42D251AE-42AF-4C0D-B163-7C7A13C4A9A6}.Debug|x64.ActiveCfg = Debug|Any CPU + {42D251AE-42AF-4C0D-B163-7C7A13C4A9A6}.Debug|x64.Build.0 = Debug|Any CPU + {42D251AE-42AF-4C0D-B163-7C7A13C4A9A6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42D251AE-42AF-4C0D-B163-7C7A13C4A9A6}.Release|Any CPU.Build.0 = Release|Any CPU + {42D251AE-42AF-4C0D-B163-7C7A13C4A9A6}.Release|x64.ActiveCfg = Release|Any CPU + {42D251AE-42AF-4C0D-B163-7C7A13C4A9A6}.Release|x64.Build.0 = Release|Any CPU + {9FDF741F-0ECF-46DB-8671-AB11ACEB9F41}.Debug|Any CPU.ActiveCfg = Debug|x64 + {9FDF741F-0ECF-46DB-8671-AB11ACEB9F41}.Debug|Any CPU.Build.0 = Debug|x64 + {9FDF741F-0ECF-46DB-8671-AB11ACEB9F41}.Debug|x64.ActiveCfg = Debug|x64 + {9FDF741F-0ECF-46DB-8671-AB11ACEB9F41}.Debug|x64.Build.0 = Debug|x64 + {9FDF741F-0ECF-46DB-8671-AB11ACEB9F41}.Release|Any CPU.ActiveCfg = Release|x64 + {9FDF741F-0ECF-46DB-8671-AB11ACEB9F41}.Release|Any CPU.Build.0 = Release|x64 + {9FDF741F-0ECF-46DB-8671-AB11ACEB9F41}.Release|x64.ActiveCfg = Release|x64 + {9FDF741F-0ECF-46DB-8671-AB11ACEB9F41}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ColorControl/ColorControl.csproj b/ColorControl/ColorControl.csproj index 0aa2f21..d7ff0cd 100644 --- a/ColorControl/ColorControl.csproj +++ b/ColorControl/ColorControl.csproj @@ -18,8 +18,8 @@ Maassoft Maassoft 0 - 9.7.2.0 - 9.7.2.0 + 9.8.0.0 + 9.8.0.0 false true false @@ -29,7 +29,7 @@ true pngbarn.ico 10.0.20348.0 - 2020-2023 Maassoft + 2020-2024 Maassoft Maassoft CF0BC153EA664CD97AC6F234B91F45D34630958F ColorControl_1_TemporaryKey.pfx @@ -52,6 +52,7 @@ $(MSBuildThisFileDirectory)=.\ + @@ -113,11 +114,16 @@ + + Designer + MSBuild:Compile + MSBuild:Compile + diff --git a/ColorControl/Forms/InfoPanel.cs b/ColorControl/Forms/InfoPanel.cs index 9133f57..780116b 100644 --- a/ColorControl/Forms/InfoPanel.cs +++ b/ColorControl/Forms/InfoPanel.cs @@ -8,15 +8,12 @@ namespace ColorControl.Forms public partial class InfoPanel : UserControl { private readonly WinApiService _winApiService; - private bool _initialized; public InfoPanel(WinApiService winApiService) { _winApiService = winApiService; InitializeComponent(); - _initialized = true; - if (DarkModeUtils.UseDarkMode) { grpInfo.ForeColor = FormUtils.CurrentForeColor; @@ -29,14 +26,14 @@ namespace ColorControl.Forms { var currentVersionInfo = FileVersionInfo.GetVersionInfo(Application.ExecutablePath); - Text = Application.ProductName + " " + Application.ProductVersion; + var text = Application.ProductName + " " + Application.ProductVersion; if (_winApiService.IsAdministrator()) { - Text += " (administrator)"; + text += " (administrator)"; } - lblInfo.Text = Text + " - " + currentVersionInfo.LegalCopyright; + lblInfo.Text = text + " - " + currentVersionInfo.LegalCopyright; lbPlugins.Items.Add("lgtv.net by gr4b4z"); lbPlugins.Items.Add("Newtonsoft.Json by James Newton-King"); @@ -49,7 +46,8 @@ namespace ColorControl.Forms lbPlugins.Items.Add("Novideo sRGB by ledoge"); lbPlugins.Items.Add("NLogViewer by dojo90"); lbPlugins.Items.Add("WPFDarkTheme by AngryCarrot789"); - + lbPlugins.Items.Add("Little-CMS by mm2"); + lbPlugins.Items.Add("MHC2 by dantmnf"); } } diff --git a/ColorControl/MainForm.Designer.cs b/ColorControl/MainForm.Designer.cs index c627d91..3ce3d9a 100644 --- a/ColorControl/MainForm.Designer.cs +++ b/ColorControl/MainForm.Designer.cs @@ -28,6 +28,7 @@ /// private void InitializeComponent() { + components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); tcMain = new System.Windows.Forms.TabControl(); tabOptions = new System.Windows.Forms.TabPage(); @@ -35,6 +36,7 @@ label1 = new System.Windows.Forms.Label(); chkModules = new System.Windows.Forms.CheckedListBox(); grpMiscellaneousOptions = new System.Windows.Forms.GroupBox(); + btnOptionsColorProfiles = new System.Windows.Forms.Button(); btnSetShortcutScreenSaver = new System.Windows.Forms.Button(); label11 = new System.Windows.Forms.Label(); edtBlankScreenSaverShortcut = new System.Windows.Forms.TextBox(); @@ -60,11 +62,14 @@ chkStartAfterLogin = new System.Windows.Forms.CheckBox(); tabInfo = new System.Windows.Forms.TabPage(); btnUpdate = new System.Windows.Forms.Button(); + mnuColorProfiles = new System.Windows.Forms.ContextMenuStrip(components); + miCreateHDRColorProfile = new System.Windows.Forms.ToolStripMenuItem(); tcMain.SuspendLayout(); tabOptions.SuspendLayout(); grpOptionsModules.SuspendLayout(); grpMiscellaneousOptions.SuspendLayout(); grpGeneralOptions.SuspendLayout(); + mnuColorProfiles.SuspendLayout(); SuspendLayout(); // // tcMain @@ -130,6 +135,7 @@ // // grpMiscellaneousOptions // + grpMiscellaneousOptions.Controls.Add(btnOptionsColorProfiles); grpMiscellaneousOptions.Controls.Add(btnSetShortcutScreenSaver); grpMiscellaneousOptions.Controls.Add(label11); grpMiscellaneousOptions.Controls.Add(edtBlankScreenSaverShortcut); @@ -144,6 +150,17 @@ grpMiscellaneousOptions.TabStop = false; grpMiscellaneousOptions.Text = "Miscellaneous"; // + // btnOptionsColorProfiles + // + btnOptionsColorProfiles.Location = new System.Drawing.Point(538, 17); + btnOptionsColorProfiles.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + btnOptionsColorProfiles.Name = "btnOptionsColorProfiles"; + btnOptionsColorProfiles.Size = new System.Drawing.Size(112, 27); + btnOptionsColorProfiles.TabIndex = 12; + btnOptionsColorProfiles.Text = "Color Profiles..."; + btnOptionsColorProfiles.UseVisualStyleBackColor = true; + btnOptionsColorProfiles.Click += btnOptionsColorProfiles_Click; + // // btnSetShortcutScreenSaver // btnSetShortcutScreenSaver.Location = new System.Drawing.Point(181, 98); @@ -455,6 +472,20 @@ btnUpdate.Visible = false; btnUpdate.Click += btnUpdate_Click; // + // mnuColorProfiles + // + mnuColorProfiles.ImageScalingSize = new System.Drawing.Size(20, 20); + mnuColorProfiles.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miCreateHDRColorProfile }); + mnuColorProfiles.Name = "mnuLgButtons"; + mnuColorProfiles.Size = new System.Drawing.Size(214, 26); + // + // miCreateHDRColorProfile + // + miCreateHDRColorProfile.Name = "miCreateHDRColorProfile"; + miCreateHDRColorProfile.Size = new System.Drawing.Size(213, 22); + miCreateHDRColorProfile.Text = "Create HDR Color Profile..."; + miCreateHDRColorProfile.Click += miCreateHDRColorProfile_Click; + // // MainForm // AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); @@ -486,6 +517,7 @@ grpMiscellaneousOptions.PerformLayout(); grpGeneralOptions.ResumeLayout(false); grpGeneralOptions.PerformLayout(); + mnuColorProfiles.ResumeLayout(false); ResumeLayout(false); } @@ -522,6 +554,9 @@ private System.Windows.Forms.CheckBox chkOptionsUseDarkMode; private System.Windows.Forms.Button btnOptionsAdvanced; private System.Windows.Forms.Button btnOptionsLog; + private System.Windows.Forms.Button btnOptionsColorProfiles; + private System.Windows.Forms.ContextMenuStrip mnuColorProfiles; + private System.Windows.Forms.ToolStripMenuItem miCreateHDRColorProfile; } } diff --git a/ColorControl/MainForm.cs b/ColorControl/MainForm.cs index 8a04bdf..6d97155 100644 --- a/ColorControl/MainForm.cs +++ b/ColorControl/MainForm.cs @@ -66,7 +66,6 @@ namespace ColorControl private AmdPanel _amdPanel; private bool _skipResize; - private FileVersionInfo _currentVersionInfo; private bool _checkedForUpdates = false; private string _updateHtmlUrl; private string _downloadUrl; @@ -96,6 +95,15 @@ namespace ColorControl _dataDir = Program.DataDir; _config = Program.Config; + var currentVersionInfo = FileVersionInfo.GetVersionInfo(Application.ExecutablePath); + + Text = Application.ProductName + " " + Application.ProductVersion; + + if (_winApiService.IsAdministrator()) + { + Text += " (administrator)"; + } + LoadConfig(); KeyboardShortcutManager.SetUseRawInput(_config.UseRawInput); @@ -1423,5 +1431,15 @@ Currently ColorControl is {(_winApiService.IsAdministrator() ? "" : "not ")}runn var module = _config.Modules[index]; module.IsActive = e.NewValue == CheckState.Checked; } + + private void miCreateHDRColorProfile_Click(object sender, EventArgs e) + { + ColorProfileWindow.CreateAndShow(); + } + + private void btnOptionsColorProfiles_Click(object sender, EventArgs e) + { + mnuColorProfiles.ShowCustom(btnOptionsColorProfiles); + } } } \ No newline at end of file diff --git a/ColorControl/MainForm.resx b/ColorControl/MainForm.resx index 1de7ce7..74bd8a9 100644 --- a/ColorControl/MainForm.resx +++ b/ColorControl/MainForm.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 147, 17 + diff --git a/ColorControl/Program.cs b/ColorControl/Program.cs index 35fb9e2..6646ffa 100644 --- a/ColorControl/Program.cs +++ b/ColorControl/Program.cs @@ -256,6 +256,7 @@ namespace ColorControl services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddTransient(); services.AddSingleton(); services.AddSingleton(); }); diff --git a/ColorControl/Services/GameLauncher/GameService.cs b/ColorControl/Services/GameLauncher/GameService.cs index cf4db42..21ba132 100644 --- a/ColorControl/Services/GameLauncher/GameService.cs +++ b/ColorControl/Services/GameLauncher/GameService.cs @@ -77,7 +77,14 @@ namespace ColorControl.Services.GameLauncher if (_winApiService.IsAdministrator()) { - var fileName = process.MainModule.FileName; + var mainModule = process.MainModule; + + if (mainModule == null) + { + return false; + } + + var fileName = mainModule.FileName; preset = _presets.FirstOrDefault(p => fileName.Contains(Path.GetDirectoryName(p.Path), System.StringComparison.OrdinalIgnoreCase)); } diff --git a/ColorControl/Services/LG/LgPanel.cs b/ColorControl/Services/LG/LgPanel.cs index 82dd916..1e58a11 100644 --- a/ColorControl/Services/LG/LgPanel.cs +++ b/ColorControl/Services/LG/LgPanel.cs @@ -829,7 +829,7 @@ Do you want to continue?" mnuLgOLEDMotionPro.Visible = visible; miLgEnableMotionPro.Visible = enableVisible; - var svcMenuFlagVisible = new[] { "B2", "C2", "G2", "B3", "C3", "G3" }.Any(m => device?.ModelName?.Contains(m) == true); + var svcMenuFlagVisible = new[] { "A2", "B2", "C2", "G2", "A3", "B3", "C3", "G3" }.Any(m => device?.ModelName?.Contains(m) == true); mnuLgSetSvcMenuFlag.Visible = svcMenuFlagVisible; diff --git a/ColorControl/Services/NVIDIA/NvPanel.Designer.cs b/ColorControl/Services/NVIDIA/NvPanel.Designer.cs index 987376b..3fbd11d 100644 --- a/ColorControl/Services/NVIDIA/NvPanel.Designer.cs +++ b/ColorControl/Services/NVIDIA/NvPanel.Designer.cs @@ -57,6 +57,8 @@ namespace ColorControl.Services.NVIDIA miNvPrimaryDisplay = new System.Windows.Forms.ToolStripMenuItem(); mnuNvPresetsColorSettings = new System.Windows.Forms.ToolStripMenuItem(); miNvPresetColorSettings = new System.Windows.Forms.ToolStripMenuItem(); + mnuNvPresetsColorEnhancements = new System.Windows.Forms.ToolStripMenuItem(); + miNvPresetColorEnhancementsIncluded = new System.Windows.Forms.ToolStripMenuItem(); mnuRefreshRate = new System.Windows.Forms.ToolStripMenuItem(); miRefreshRateIncluded = new System.Windows.Forms.ToolStripMenuItem(); mnuNvResolution = new System.Windows.Forms.ToolStripMenuItem(); @@ -94,8 +96,8 @@ namespace ColorControl.Services.NVIDIA miNvNovideo = new System.Windows.Forms.ToolStripMenuItem(); miNvSettings = new System.Windows.Forms.ToolStripMenuItem(); miNvTestDithering = new System.Windows.Forms.ToolStripMenuItem(); - lvNvPresetsToolTip = new System.Windows.Forms.ToolTip(components); miNVIDIAInfo = new System.Windows.Forms.ToolStripMenuItem(); + lvNvPresetsToolTip = new System.Windows.Forms.ToolTip(components); mnuNvPresets.SuspendLayout(); mnuNvSettings.SuspendLayout(); SuspendLayout(); @@ -326,9 +328,9 @@ namespace ColorControl.Services.NVIDIA // mnuNvPresets // mnuNvPresets.ImageScalingSize = new System.Drawing.Size(20, 20); - mnuNvPresets.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvApply, miNvPresetApplyOnStartup, tssNvPresetMenu, mnuNvDisplay, mnuNvPresetsColorSettings, mnuRefreshRate, mnuNvResolution, miNvPresetDithering, miNvHDR, mnuNvDriverSettings, mnuNvOtherSettings, mnuNvHdmiSettings, mnuNvOverclocking, miNvCopyId }); + mnuNvPresets.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvApply, miNvPresetApplyOnStartup, tssNvPresetMenu, mnuNvDisplay, mnuNvPresetsColorSettings, mnuNvPresetsColorEnhancements, mnuRefreshRate, mnuNvResolution, miNvPresetDithering, miNvHDR, mnuNvDriverSettings, mnuNvOtherSettings, mnuNvHdmiSettings, mnuNvOverclocking, miNvCopyId }); mnuNvPresets.Name = "mnuNvPresets"; - mnuNvPresets.Size = new System.Drawing.Size(185, 296); + mnuNvPresets.Size = new System.Drawing.Size(185, 340); mnuNvPresets.Opening += mnuNvPresets_Opening; // // miNvApply @@ -375,10 +377,24 @@ namespace ColorControl.Services.NVIDIA // miNvPresetColorSettings // miNvPresetColorSettings.Name = "miNvPresetColorSettings"; - miNvPresetColorSettings.Size = new System.Drawing.Size(120, 22); + miNvPresetColorSettings.Size = new System.Drawing.Size(180, 22); miNvPresetColorSettings.Text = "Included"; miNvPresetColorSettings.Click += miNvPresetColorSettings_Click; // + // mnuNvPresetsColorEnhancements + // + mnuNvPresetsColorEnhancements.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvPresetColorEnhancementsIncluded }); + mnuNvPresetsColorEnhancements.Name = "mnuNvPresetsColorEnhancements"; + mnuNvPresetsColorEnhancements.Size = new System.Drawing.Size(184, 22); + mnuNvPresetsColorEnhancements.Text = "Color Enhancements"; + // + // miNvPresetColorEnhancementsIncluded + // + miNvPresetColorEnhancementsIncluded.Name = "miNvPresetColorEnhancementsIncluded"; + miNvPresetColorEnhancementsIncluded.Size = new System.Drawing.Size(180, 22); + miNvPresetColorEnhancementsIncluded.Text = "Included"; + miNvPresetColorEnhancementsIncluded.Click += miNvPresetColorEnhancementsIncluded_Click; + // // mnuRefreshRate // mnuRefreshRate.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miRefreshRateIncluded }); @@ -638,7 +654,7 @@ namespace ColorControl.Services.NVIDIA mnuNvSettings.ImageScalingSize = new System.Drawing.Size(20, 20); mnuNvSettings.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvProfileInspector, miNvNovideo, miNvSettings, miNvTestDithering, miNVIDIAInfo }); mnuNvSettings.Name = "mnuLgButtons"; - mnuNvSettings.Size = new System.Drawing.Size(202, 136); + mnuNvSettings.Size = new System.Drawing.Size(202, 114); // // miNvProfileInspector // @@ -778,5 +794,7 @@ namespace ColorControl.Services.NVIDIA private System.Windows.Forms.ToolStripMenuItem miNvHdmiIncluded; private System.Windows.Forms.ToolStripMenuItem miNvTestDithering; private System.Windows.Forms.ToolStripMenuItem miNVIDIAInfo; + private System.Windows.Forms.ToolStripMenuItem mnuNvPresetsColorEnhancements; + private System.Windows.Forms.ToolStripMenuItem miNvPresetColorEnhancementsIncluded; } } diff --git a/ColorControl/Services/NVIDIA/NvPanel.cs b/ColorControl/Services/NVIDIA/NvPanel.cs index 5793aca..b38472c 100644 --- a/ColorControl/Services/NVIDIA/NvPanel.cs +++ b/ColorControl/Services/NVIDIA/NvPanel.cs @@ -337,6 +337,8 @@ namespace ColorControl.Services.NVIDIA mnuNvDisplay.Visible = presetItemsVisible; miNvPresetColorSettings.Enabled = presetItemsVisible; mnuNvPresetsColorSettings.Enabled = preset != null; + miNvPresetColorEnhancementsIncluded.Enabled = presetItemsVisible; + mnuNvPresetsColorEnhancements.Enabled = preset != null; mnuRefreshRate.Enabled = preset != null; mnuNvResolution.Enabled = preset != null; miNvPresetDithering.Enabled = preset != null; @@ -363,6 +365,7 @@ namespace ColorControl.Services.NVIDIA miNvPresetApplyDithering.Visible = !isCurrentDisplay; miNvPresetColorSettings.Visible = !isCurrentDisplay; + miNvPresetColorEnhancementsIncluded.Visible = !isCurrentDisplay; miNvResolutionIncluded.Visible = !isCurrentDisplay; miRefreshRateIncluded.Visible = !isCurrentDisplay; miHDRIncluded.Visible = !isCurrentDisplay; @@ -422,8 +425,10 @@ namespace ColorControl.Services.NVIDIA miNvOtherIncluded.Checked = preset.applyOther; miNvHdmiIncluded.Checked = preset.applyHdmiSettings; miNvDriverSettingsIncluded.Checked = preset.applyDriverSettings; + miNvPresetColorEnhancementsIncluded.Checked = preset.ApplyColorEnhancements; mnuNvPresetsColorSettings.Font = _menuItemFonts[preset.applyColorData]; + mnuNvPresetsColorEnhancements.Font = _menuItemFonts[preset.ApplyColorEnhancements]; mnuRefreshRate.Font = _menuItemFonts[preset.applyRefreshRate]; mnuNvResolution.Font = _menuItemFonts[preset.applyResolution]; miNvPresetDithering.Font = _menuItemFonts[preset.applyDithering]; @@ -432,22 +437,19 @@ namespace ColorControl.Services.NVIDIA mnuNvOtherSettings.Font = _menuItemFonts[preset.applyOther]; mnuNvHdmiSettings.Font = _menuItemFonts[preset.applyHdmiSettings]; - var itemName = $"{mnuNvOtherSettings.Name}_SDRBrightness"; - var brightnessMenu = FormUtils.BuildMenuItem(mnuNvOtherSettings.DropDownItems, itemName, "SDR brightness"); + FormUtils.BuildMenuItemAndSub(mnuNvPresetsColorEnhancements, "Digital Vibrance", + $"{preset.ColorEnhancementSettings.DigitalVibranceLevel}% (click to change)", nvPresetDvcMenuItem_Click); + FormUtils.BuildMenuItemAndSub(mnuNvPresetsColorEnhancements, "Hue", + $"{preset.ColorEnhancementSettings.HueAngle}° (click to change)", nvPresetHueMenuItem_Click); - var subItemName = $"{itemName}_SubItem"; - var subItem = FormUtils.BuildMenuItem(brightnessMenu.DropDownItems, subItemName, "", onClick: nvPresetBrightnessMenuItem_Click); - subItem.Text = (preset.SDRBrightness.HasValue ? $"{preset.SDRBrightness.Value}%" : "Unset") + " (click to change)"; + FormUtils.BuildMenuItemAndSub(mnuNvOtherSettings, "SDR brightness", + (preset.SDRBrightness.HasValue ? $"{preset.SDRBrightness.Value}%" : "Unset") + " (click to change)", nvPresetBrightnessMenuItem_Click); FormUtils.BuildDropDownMenu(mnuNvOtherSettings, "Scaling", typeof(Scaling), preset, "scaling", nvPresetScalingMenuItem_Click, unchanged: true, skipValues: new object[] { Scaling.Customized }) .DropDownItems[0].Visible = !isCurrentDisplay; - var itemNameProfile = $"{mnuNvOtherSettings.Name}_Profile"; - var profileMenu = FormUtils.BuildMenuItem(mnuNvOtherSettings.DropDownItems, itemNameProfile, "Color Profile"); - - var subItemNameProfile = $"{itemNameProfile}_SubItem"; - var subItemProfile = FormUtils.BuildMenuItem(profileMenu.DropDownItems, subItemNameProfile, "", onClick: nvPresetColorProfileMenuItem_Click); - subItemProfile.Text = (!preset.ColorProfileSettings.ProfileName.IsNullOrWhiteSpace() ? $"{preset.ColorProfileSettings.ProfileName}" : "Unset") + " (click to change)"; + FormUtils.BuildMenuItemAndSub(mnuNvOtherSettings, "Color Profile", + (!preset.ColorProfileSettings.ProfileName.IsNullOrWhiteSpace() ? $"{preset.ColorProfileSettings.ProfileName}" : "Unset") + " (click to change)", nvPresetColorProfileMenuItem_Click); FormUtils.BuildDropDownMenu(mnuNvHdmiSettings, "Content type", typeof(InfoFrameVideoContentType), preset.HdmiInfoFrameSettings, "ContentType", nvPresetHdmiContentTypeMenuItem_Click, unchanged: true) .DropDownItems[0].Visible = !isCurrentDisplay; @@ -833,6 +835,68 @@ namespace ColorControl.Services.NVIDIA AddOrUpdateItem(); } + private void nvPresetDvcMenuItem_Click(object sender, EventArgs e) + { + var preset = GetSelectedNvPreset(true); + + var label = "Digital vibrance in % (clear to set to default)"; + + var display = _nvService.ResolveDisplay(preset); + var dvControl = display.DigitalVibranceControl; + + var value = SelectValue(dvControl.MinimumLevel, dvControl.MaximumLevel, preset.ColorEnhancementSettings.DigitalVibranceLevel, label); + + if (value == -1) + { + return; + } + + var intValue = value ?? dvControl.DefaultLevel; + + if (preset.IsDisplayPreset) + { + _nvService.SetDigitalVibranceLevel(preset.Display, intValue); + + UpdateDisplayInfoItems(); + return; + } + + preset.ColorEnhancementSettings.DigitalVibranceLevel = intValue; + + AddOrUpdateItem(); + } + + private void nvPresetHueMenuItem_Click(object sender, EventArgs e) + { + var preset = GetSelectedNvPreset(true); + + var label = "Hue angle in ° (clear to set to default)"; + + var display = _nvService.ResolveDisplay(preset); + var hueControl = display.HUEControl; + + var value = SelectValue(hueControl.DefaultAngle, 359, preset.ColorEnhancementSettings.HueAngle, label); + + if (value == -1) + { + return; + } + + var intValue = value ?? hueControl.DefaultAngle; + + if (preset.IsDisplayPreset) + { + _nvService.SetHueAngle(preset.Display, intValue); + + UpdateDisplayInfoItems(); + return; + } + + preset.ColorEnhancementSettings.HueAngle = intValue; + + AddOrUpdateItem(); + } + private void nvPresetScalingMenuItem_Click(object sender, EventArgs e) { var menuItem = (ToolStripMenuItem)sender; @@ -1931,5 +1995,14 @@ namespace ColorControl.Services.NVIDIA MessageForms.ShowControl(panel, "NVIDIA Info", height: 800); } + + private void miNvPresetColorEnhancementsIncluded_Click(object sender, EventArgs e) + { + var preset = GetSelectedNvPreset(); + + preset.ApplyColorEnhancements = !preset.ApplyColorEnhancements; + + AddOrUpdateItem(); + } } } diff --git a/ColorControl/Services/NVIDIA/NvPanel.resx b/ColorControl/Services/NVIDIA/NvPanel.resx index 86701cd..474820f 100644 --- a/ColorControl/Services/NVIDIA/NvPanel.resx +++ b/ColorControl/Services/NVIDIA/NvPanel.resx @@ -18,7 +18,7 @@ System.Resources.ResXResourceReader, System.Windows.Forms, ... System.Resources.ResXResourceWriter, System.Windows.Forms, ... this is my long stringthis is a comment - Blue + Blue [base64 mime encoded serialized .NET Framework object] diff --git a/ColorControl/Services/NVIDIA/NvPreset.cs b/ColorControl/Services/NVIDIA/NvPreset.cs index ad04060..4bb50c7 100644 --- a/ColorControl/Services/NVIDIA/NvPreset.cs +++ b/ColorControl/Services/NVIDIA/NvPreset.cs @@ -20,6 +20,8 @@ namespace ColorControl.Services.NVIDIA public bool applyColorData { get; set; } public ColorData colorData { get; set; } + public bool ApplyColorEnhancements { get; set; } + public NvColorEnhancementSettings ColorEnhancementSettings { get; set; } public bool applyHDR { get; set; } public bool HDREnabled { get; set; } public bool toggleHDR { get; set; } @@ -77,6 +79,7 @@ namespace ColorControl.Services.NVIDIA ocSettings = new List(); HdmiInfoFrameSettings = new NvHdmiInfoFrameSettings(); ColorProfileSettings = new NvColorProfileSettings(); + ColorEnhancementSettings = new NvColorEnhancementSettings(); } public NvPreset(ColorData colorData) : this() @@ -116,6 +119,9 @@ namespace ColorControl.Services.NVIDIA HdmiInfoFrameSettings = new NvHdmiInfoFrameSettings(preset.HdmiInfoFrameSettings); applyHdmiSettings = preset.applyHdmiSettings; + + ColorEnhancementSettings = new NvColorEnhancementSettings(preset.ColorEnhancementSettings); + ApplyColorEnhancements = preset.ApplyColorEnhancements; } public NvPreset Clone() @@ -127,7 +133,7 @@ namespace ColorControl.Services.NVIDIA public static string[] GetColumnNames() { - return new[] { "Name", "Display|140", "Color settings (BPC, format, dyn. range, color space)|260", "Refresh rate|100", "Resolution|120", "Dithering", "HDR", "Driver settings|300", "HDMI settings|200", "Other|200", "Overclocking|300", "Shortcut", "Apply on startup" }; + return new[] { "Name", "Display|140", "Color settings (BPC, format, dyn. range, color space)|260", "Color enhancements", "Refresh rate|100", "Resolution|120", "Dithering", "HDR", "Driver settings|300", "HDMI settings|200", "Other|200", "Overclocking|300", "Shortcut", "Apply on startup" }; } public override List GetDisplayValues(Config config = null) @@ -145,6 +151,9 @@ namespace ColorControl.Services.NVIDIA var colorSettings = FormatDisplaySetting(string.Format("{0}, {1}, {2}, {3}", colorData.ColorDepth, colorData.ColorFormat, colorData.DynamicRange, colorData.Colorimetry), isCurrent, applyColorData); values.Add(colorSettings); + + values.Add(FormatDisplaySetting(GetColorEnhancementsDescription(), isCurrent, ApplyColorEnhancements)); + values.Add(FormatDisplaySetting(string.Format("{0}Hz", refreshRate), isCurrent, applyRefreshRate)); if (applyResolution || resolutionWidth > 0) @@ -298,6 +307,27 @@ namespace ColorControl.Services.NVIDIA return string.Join(", ", values); } + public string GetColorEnhancementsDescription() + { + var values = new List(); + + if (ColorEnhancementSettings.DigitalVibranceLevel != 50) + { + values.Add($"Digital vibrance: {ColorEnhancementSettings.DigitalVibranceLevel}%"); + } + if (ColorEnhancementSettings.HueAngle != 0) + { + values.Add($"Hue: {ColorEnhancementSettings.HueAngle}°"); + } + + if (!values.Any()) + { + values.Add("None"); + } + + return string.Join(", ", values); + } + public static ColorData DefaultColorData => new ColorData(ColorDataFormat.Auto, dynamicRange: ColorDataDynamicRange.Auto, colorDepth: ColorDataDepth.Default, colorSelectionPolicy: ColorDataSelectionPolicy.BestQuality); public static List GetDefaultPresets() diff --git a/ColorControl/Services/NVIDIA/NvService.cs b/ColorControl/Services/NVIDIA/NvService.cs index 90c633c..ca17db5 100644 --- a/ColorControl/Services/NVIDIA/NvService.cs +++ b/ColorControl/Services/NVIDIA/NvService.cs @@ -398,6 +398,12 @@ namespace ColorControl.Services.NVIDIA } } + if (preset.ApplyColorEnhancements) + { + SetDigitalVibranceLevel(display, preset.ColorEnhancementSettings.DigitalVibranceLevel); + SetHueAngle(display, preset.ColorEnhancementSettings.HueAngle); + } + if (preset.applyDriverSettings) { SetDriverSettings(preset.driverSettings); @@ -609,6 +615,28 @@ namespace ColorControl.Services.NVIDIA return 0; } + public void SetDigitalVibranceLevel(Display display, int level) + { + var dvControl = display.DigitalVibranceControl; + + dvControl.CurrentLevel = level; + } + + public int GetDigitalVibranceLevel(Display display) + { + return display.DigitalVibranceControl.CurrentLevel; + } + + public void SetHueAngle(Display display, int angle) + { + display.HUEControl.CurrentAngle = angle; + } + + public int GetHueAngle(Display display) + { + return display.HUEControl.CurrentAngle; + } + public bool SetDithering(NvDitherState state, uint bits = 1, uint mode = 4, NvPreset preset = null, Display currentDisplay = null) { var result = true; @@ -1132,6 +1160,7 @@ namespace ColorControl.Services.NVIDIA preset.displayName = FormUtils.ExtendedDisplayName(display.Name); preset.colorData = GetCurrentColorData(display); + preset.ColorEnhancementSettings = GetCurrentColorEnhancements(display); preset.HdmiInfoFrameSettings = GetHdmiSettings(display); preset.SDRBrightness = GetSDRBrightness(display); preset.scaling = GetScaling(display); @@ -1199,6 +1228,15 @@ namespace ColorControl.Services.NVIDIA return preset; } + private NvColorEnhancementSettings GetCurrentColorEnhancements(Display display) + { + return new NvColorEnhancementSettings + { + DigitalVibranceLevel = GetDigitalVibranceLevel(display), + HueAngle = GetHueAngle(display) + }; + } + public List GetVisibleSettings() { return GetSettings().Where(s => _driverSettingIds.Contains(s.SettingId)).ToList(); @@ -1368,14 +1406,14 @@ namespace ColorControl.Services.NVIDIA Utils.WriteObject(_configFilename, Config); } - internal void ResolveDisplay(NvPreset preset) + internal Display ResolveDisplay(NvPreset preset) { - if (preset.Display != null) + if (preset.Display == null) { - return; + preset.Display = GetPresetDisplay(preset); } - preset.Display = GetPresetDisplay(preset); + return preset.Display; } } } diff --git a/ColorControl/XForms/ColorProfileViewModel.cs b/ColorControl/XForms/ColorProfileViewModel.cs new file mode 100644 index 0000000..4a63820 --- /dev/null +++ b/ColorControl/XForms/ColorProfileViewModel.cs @@ -0,0 +1,260 @@ +using ColorControl.Shared.Common; +using ColorControl.Shared.Forms; +using ColorControl.Shared.Native; +using ColorControl.Shared.XForms; +using MHC2Gen; +using novideo_srgb; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Windows.Forms; +using WindowsDisplayAPI; + +namespace ColorControl.XForms; + +public enum SaveOption +{ + Install, + [Description("Install and set as default")] + InstallAndSetAsDefault, + [Description("Save to file")] + SaveToFile +} + +public enum DisplayPrimariesSource +{ + Custom, + EDID, + Windows +} + +public class CustomDisplay +{ + public Display Display { get; set; } + + public string DisplayName => Display.DisplayName; + public string DevicePath => Display.DevicePath; + public bool IsHDRSupportedAndEnabled() + { + var advancedColor = CCD.GetAdvancedColorSupportedAndEnabled(DisplayName); + + return advancedColor.isSupported && advancedColor.isEnabled; + } + + public CustomDisplay(Display display) + { + Display = display; + } + + public override string ToString() + { + return $"{FormUtils.ExtendedDisplayName(Display.DisplayName)} on {Display.Adapter.DeviceName}"; + } +} + +public class ColorPointModel : BaseViewModel +{ + private double _x; + public double X { get => _x; set { _x = value; OnPropertyChanged(); } } + + private double _y; + public double Y { get => _y; set { _y = value; OnPropertyChanged(); } } + + public ColorPointModel() + { + + } + + public ColorPointModel(CIExy coord) + { + X = coord.x; + Y = coord.y; + } +} + +internal class ColorProfileViewModel : BaseViewModel +{ + [StringLength(30)] + public string Description { get; set; } + + public ColorPointModel RedPoint { get; set; } = new ColorPointModel(RgbPrimaries.sRGB.Red); + public ColorPointModel GreenPoint { get; set; } = new ColorPointModel(RgbPrimaries.sRGB.Green); + public ColorPointModel BluePoint { get; set; } = new ColorPointModel(RgbPrimaries.sRGB.Blue); + public ColorPointModel WhitePoint { get; set; } = new ColorPointModel(RgbPrimaries.sRGB.White); + public Dictionary PrimariesSources { get; } = Utils.EnumToDictionary(); + public DisplayPrimariesSource PrimariesSource { get; set; } = DisplayPrimariesSource.EDID; + public Dictionary ColorGamuts { get; } = Utils.EnumToDictionary(); + public ColorGamut ColorGamut { get; set; } = ColorGamut.Native; + public Dictionary SDRTransferFunctions { get; } = Utils.EnumToDictionary(); + public SDRTransferFunction SDRTransferFunction { get; set; } = SDRTransferFunction.PurePower; + [Range(0.1, 10)] + public double CustomGamma { get; set; } = 2.20; + [Range(0, 10)] + public double MinCLL { get; set; } = 0; + [Range(11, 10000)] + public double MaxCLL { get; set; } = 1000; + [Range(0, 10)] + public double BlackLuminance { get; set; } = 0; + [Range(11, 10000)] + public double WhiteLuminance { get; set; } = 1000; + [Range(0, 10)] + public double SDRMinBrightness { get; set; } = 0; + [Range(11, 1000)] + public double SDRMaxBrightness { get; set; } = 100; + [Range(-50, 50)] + public double SDRBrightnessBoost { get; set; } + + public CustomDisplay SelectedDisplay { get; set; } + public IEnumerable Displays { get; set; } + + public string SelectedDisplayName => SelectedDisplay?.DisplayName; + + public List ExistingProfiles { get; set; } + public string SelectedExistingProfile { get; set; } = CreateANewProfile; + public string NewProfileName { get; set; } + public string ProfileName => SelectedExistingProfile == CreateANewProfile ? NewProfileName : SelectedExistingProfile; + public bool IsHDR { get; set; } = true; + public Dictionary SaveOptions { get; } = Utils.EnumToDictionary(); + public SaveOption SaveOption { get; set; } = SaveOption.InstallAndSetAsDefault; + + + public override string this[string columnName] + { + get + { + var baseResult = base[columnName]; + + if (columnName == "SelectedDisplay" || columnName == "PrimariesSource") + { + UpdateDisplay(); + } + + return baseResult; + } + } + + public override bool PreValidate() + { + return base.PreValidate() && Displays.Any(); + } + + public const string CreateANewProfile = ""; + + public ColorProfileViewModel(bool isHDR = true) + { + IsHDR = isHDR; + + RefreshDisplays(); + + ExistingProfiles = new List { CreateANewProfile }; + NewProfileName = $"CC_{(isHDR ? "HDR" : "SDR")}_profile_{DateTime.Now:yyyyMMddHHmmss}.icm"; + Description = $"CC_{(isHDR ? "HDR" : "SDR")}"; + + if (Displays.Any()) + { + SelectedDisplay = Displays.First(); + + UpdateDisplay(); + } + } + + public void RefreshDisplays() + { + Displays = Display.GetDisplays().Select(d => new CustomDisplay(d)).ToList(); + + if (IsHDR) + { + Displays = Displays.Where(d => d.IsHDRSupportedAndEnabled()).ToList(); + } + } + + private void UpdateDisplay() + { + if (SelectedDisplay == null) + { + return; + } + + var colorParams = CCD.GetColorParams(SelectedDisplay.DisplayName); + + if (colorParams.MaxLuminance > 0) + { + if (PrimariesSource == DisplayPrimariesSource.Windows) + { + var divider = colorParams.RedPointX <= 1 << 10 ? 1 << 10 : 1 << 20; + + RedPoint.X = (double)colorParams.RedPointX / divider; + RedPoint.Y = (double)colorParams.RedPointY / divider; + GreenPoint.X = (double)colorParams.GreenPointX / divider; + GreenPoint.Y = (double)colorParams.GreenPointY / divider; + BluePoint.X = (double)colorParams.BluePointX / divider; + BluePoint.Y = (double)colorParams.BluePointY / divider; + WhitePoint.X = (double)colorParams.WhitePointX / divider; + WhitePoint.Y = (double)colorParams.WhitePointY / divider; + } + + WhiteLuminance = (double)colorParams.MaxLuminance / 10000; + OnPropertyChanged(nameof(WhiteLuminance)); + BlackLuminance = (double)colorParams.MinLuminance / 10000; + OnPropertyChanged(nameof(BlackLuminance)); + MinCLL = BlackLuminance; + OnPropertyChanged(nameof(MinCLL)); + MaxCLL = WhiteLuminance; + OnPropertyChanged(nameof(MaxCLL)); + } + + if (PrimariesSource == DisplayPrimariesSource.EDID) + { + GetEDID(); + } + + if (!CCD.GetUsePerUserDisplayProfiles(SelectedDisplay.DisplayName)) + { + if (MessageForms.QuestionYesNo("To be able to select/activate a color profile, user specific settings have to be enabled. Do you want to enable this?") == DialogResult.Yes) + { + CCD.SetUsePerUserDisplayProfiles(SelectedDisplay.DisplayName, true); + } + } + + ExistingProfiles = new List { CreateANewProfile }; + ExistingProfiles.AddRange(CCD.GetDisplayColorProfiles(SelectedDisplay.DisplayName)); + } + + private void GetEDID() + { + if (SelectedDisplay == null) + { + return; + } + + var path = SelectedDisplay.DevicePath; + + var edid = Novideo.GetEDID(path, null); + var primaries = edid?.DisplayParameters?.ChromaticityCoordinates; + + if (primaries == null) + { + return; + } + + RedPoint.X = primaries.RedX; + RedPoint.Y = primaries.RedY; + GreenPoint.X = primaries.GreenX; + GreenPoint.Y = primaries.GreenY; + BluePoint.X = primaries.BlueX; + BluePoint.Y = primaries.BlueY; + WhitePoint.X = primaries.WhiteX; + WhitePoint.Y = primaries.WhiteY; + } + + internal RgbPrimaries GetDevicePrimaries() + { + return new RgbPrimaries( + new CIExy { x = RedPoint.X, y = RedPoint.Y }, + new CIExy { x = GreenPoint.X, y = GreenPoint.Y }, + new CIExy { x = BluePoint.X, y = BluePoint.Y }, + new CIExy { x = WhitePoint.X, y = WhitePoint.Y }); + } +} diff --git a/ColorControl/XForms/ColorProfileWindow.xaml b/ColorControl/XForms/ColorProfileWindow.xaml new file mode 100644 index 0000000..7030df6 --- /dev/null +++ b/ColorControl/XForms/ColorProfileWindow.xaml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +