Navigation Menu

Skip to content

Commit

Permalink
Color management: add blackpoint compensation preference
Browse files Browse the repository at this point in the history
  • Loading branch information
tannerhelland committed May 4, 2018
1 parent dae2e03 commit 9518509
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 177 deletions.
12 changes: 6 additions & 6 deletions Controls/pdRadioButton.ctl
Expand Up @@ -232,7 +232,7 @@ End Sub
Private Sub UpdateOtherButtons()

'If the option button is set to TRUE, turn off all other option buttons on a form
If m_Value Then
If m_Value And PDMain.IsProgramRunning() Then

'Enumerate through each control on the form; if it's another option button whose value is TRUE, set it to FALSE
Dim eControl As Object
Expand Down Expand Up @@ -339,7 +339,7 @@ Private Sub UserControl_Initialize()
Set m_Colors = New pdThemeColors
Dim colorCount As PDRADIOBUTTON_COLOR_LIST: colorCount = [_Count]
m_Colors.InitializeColorList "PDRadioButton", colorCount
If Not pdMain.IsProgramRunning() Then UpdateColorList
If Not PDMain.IsProgramRunning() Then UpdateColorList

End Sub

Expand All @@ -364,7 +364,7 @@ Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
End Sub

Private Sub UserControl_Resize()
If Not pdMain.IsProgramRunning() Then If Not pdMain.IsProgramRunning() Then ucSupport.NotifyIDEResize UserControl.Width, UserControl.Height
If Not PDMain.IsProgramRunning() Then If Not PDMain.IsProgramRunning() Then ucSupport.NotifyIDEResize UserControl.Width, UserControl.Height
End Sub

Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
Expand Down Expand Up @@ -466,7 +466,7 @@ Private Sub RedrawBackBuffer()
bWidth = ucSupport.GetBackBufferWidth
bHeight = ucSupport.GetBackBufferHeight

If pdMain.IsProgramRunning() Then
If PDMain.IsProgramRunning() Then

'Populate colors from the master theme object
Dim radioColorBorder As Long, radioColorFill As Long, txtColor As Long
Expand Down Expand Up @@ -528,8 +528,8 @@ End Sub
Public Sub UpdateAgainstCurrentTheme(Optional ByVal hostFormhWnd As Long = 0)
If ucSupport.ThemeUpdateRequired Then
UpdateColorList
If pdMain.IsProgramRunning() Then NavKey.NotifyControlLoad Me, hostFormhWnd
If pdMain.IsProgramRunning() Then ucSupport.UpdateAgainstThemeAndLanguage
If PDMain.IsProgramRunning() Then NavKey.NotifyControlLoad Me, hostFormhWnd
If PDMain.IsProgramRunning() Then ucSupport.UpdateAgainstThemeAndLanguage
End If
End Sub

Expand Down
22 changes: 18 additions & 4 deletions Forms/Tools_Options.frm
Expand Up @@ -405,6 +405,17 @@ Begin VB.Form FormOptions
Width = 8295
_ExtentX = 14631
_ExtentY = 11853
Begin PhotoDemon.pdCheckBox chkColorManagement
Height = 315
Index = 0
Left = 240
TabIndex = 45
Top = 4080
Width = 7935
_ExtentX = 13996
_ExtentY = 556
Caption = "use black point compensation"
End
Begin PhotoDemon.pdDropDown cboDisplayRenderIntent
Height = 735
Left = 180
Expand Down Expand Up @@ -1153,6 +1164,7 @@ Private Sub cmdBarMini_OKClick()
ColorManagement.SetDisplayColorManagementPreference DCM_CustomProfile
End If

ColorManagement.SetDisplayBPC CBool(chkColorManagement(0).Value)
ColorManagement.SetDisplayRenderingIntentPref cboDisplayRenderIntent.ListIndex

'Changes to color preferences require us to re-cache any working-space-to-screen transform data.
Expand Down Expand Up @@ -1500,13 +1512,14 @@ Private Sub LoadAllPreferences()

'Set the various buttons and dropdown according to the user's current display profile preference
optColorManagement(ColorManagement.GetDisplayColorManagementPreference()).Value = True
If ColorManagement.GetDisplayBPC() Then chkColorManagement(0).Value = vbChecked Else chkColorManagement(0).Value = vbUnchecked
Interface.PopulateRenderingIntentDropDown cboDisplayRenderIntent, ColorManagement.GetDisplayRenderingIntentPref()

'Load a list of all available monitors
cboMonitors.Clear

Dim PrimaryMonitor As String, secondaryMonitor As String
PrimaryMonitor = g_Language.TranslateMessage("Primary monitor") & ": "
Dim mainMonitor As String, secondaryMonitor As String
mainMonitor = g_Language.TranslateMessage("Primary monitor") & ": "
secondaryMonitor = g_Language.TranslateMessage("Secondary monitor") & ": "

Dim primaryIndex As Long, monitorEntry As String
Expand All @@ -1519,7 +1532,7 @@ Private Sub LoadAllPreferences()

'Explicitly label the primary monitor
If g_Displays.Displays(i).IsPrimary Then
monitorEntry = PrimaryMonitor
monitorEntry = mainMonitor
primaryIndex = i
Else
monitorEntry = secondaryMonitor
Expand Down Expand Up @@ -1557,6 +1570,7 @@ Private Sub LoadAllPreferences()
cmdColorProfilePath.AssignTooltip "Click this button to bring up a ""browse for color profile"" dialog."

cboDisplayRenderIntent.AssignTooltip "If you do not know what this setting controls, set it to ""Perceptual"". Perceptual rendering intent is the best choice for most users."
chkColorManagement(0).AssignTooltip "BPC is primarily relevant in colorimetric rendering intents, where it helps preserve detail in dark (shadow) regions of images. For most workflows, BPC should be turned ON."

'END Color and Transparency preferences

Expand Down Expand Up @@ -1709,7 +1723,7 @@ Private Sub Form_Load()
Dim i As Long

'Populate all controls with the corresponding values from the preferences file
If pdMain.IsProgramRunning() Then LoadAllPreferences
If PDMain.IsProgramRunning() Then LoadAllPreferences

'Prep the category button strip
With btsvCategory
Expand Down
28 changes: 20 additions & 8 deletions Modules/ColorManagement_ICM.bas
Expand Up @@ -61,9 +61,9 @@ End Enum
' and Windows doesn't return a valid profile, we will automatically switch to unmanaged mode.)
Private m_DisplayCMMPolicy As DISPLAY_COLOR_MANAGEMENT

'Current display render intent. As of 7.0, the user can change this from Perceptual (although it's really not
' recommended unless soft-proofing is active).
Private m_DisplayRenderIntent As LCMS_RENDERING_INTENT
'Current display render intent and BPC. As of 7.0, the user can change these settings (although it doesn't make a
' lot of sense to do so, unless you're trying to do a poor-man's soft-proofing).
Private m_DisplayRenderIntent As LCMS_RENDERING_INTENT, m_DisplayBPC As Boolean

'When a pdImage object is created, we note the image's current color-management state. Because the user can change
' the default PD color-management approach mid-session, different pdImage objects may be managed using different
Expand Down Expand Up @@ -150,6 +150,14 @@ Private m_PreAlphaManagementRequired As Boolean
'To improve cache access, we generate unique hashes for each loaded profile.
Private m_Hasher As pdCrypto

Public Function GetDisplayBPC() As Boolean
GetDisplayBPC = UserPrefs.GetPref_Boolean("ColorManagement", "DisplayBPC", True)
End Function

Public Sub SetDisplayBPC(ByVal newValue As Boolean)
UserPrefs.SetPref_Boolean "ColorManagement", "DisplayBPC", newValue
End Sub

Public Function GetDisplayColorManagementPreference() As DISPLAY_COLOR_MANAGEMENT
GetDisplayColorManagementPreference = UserPrefs.GetPref_Long("ColorManagement", "DisplayCMMode", DCM_NoManagement)

Expand Down Expand Up @@ -226,8 +234,9 @@ Public Sub CacheDisplayCMMData()
'Next, load one or more display profiles based on the user's current color management settings.
' (In some cases, we'll retrieve profile paths from Windows itself, while in others, we'll retrieve them
' from internal PD settings the user has configured.)
m_DisplayCMMPolicy = GetDisplayColorManagementPreference()
m_DisplayRenderIntent = GetDisplayRenderingIntentPref()
m_DisplayCMMPolicy = ColorManagement.GetDisplayColorManagementPreference()
m_DisplayRenderIntent = ColorManagement.GetDisplayRenderingIntentPref()
m_DisplayBPC = ColorManagement.GetDisplayBPC()
m_SystemProfileIndex = m_sRGBIndex

'Start with the case where the user just wants us to use the default Windows system ICC profile.
Expand Down Expand Up @@ -740,7 +749,7 @@ Public Sub ApplyDisplayColorManagement_SingleColor(ByVal srcColor As Long, ByRef
dstColor = srcColor

'Note that this function does nothing if the display is not currently color managed
If (m_DisplayCMMPolicy <> DCM_NoManagement) And pdMain.IsProgramRunning() Then
If (m_DisplayCMMPolicy <> DCM_NoManagement) And PDMain.IsProgramRunning() Then

ValidateWorkingSpaceDisplayTransform srcWorkingSpaceIndex, Nothing

Expand Down Expand Up @@ -811,20 +820,23 @@ Private Sub ValidateWorkingSpaceDisplayTransform(ByRef srcWorkingSpaceIndex As L
use32bppPath = (srcDIB.GetDIBColorDepth = 32)
End If

Dim trnsFlags As LCMS_TRANSFORM_FLAGS
If m_DisplayBPC Then trnsFlags = cmsFLAGS_BLACKPOINTCOMPENSATION

'Verify the 32-bpp conversion handle
If use32bppPath Then

If (.ThisWSToDisplayTransform32 = 0) Or (.IndexOfDisplayTransform <> m_CurrentDisplayIndex) Then
If (.ThisWSToDisplayTransform32 <> 0) Then LittleCMS.LCMS_DeleteTransform .ThisWSToDisplayTransform32
.ThisWSToDisplayTransform32 = LittleCMS.LCMS_CreateTwoProfileTransform(.LcmsProfileHandle, m_ProfileCache(m_CurrentDisplayIndex).LcmsProfileHandle, TYPE_BGRA_8, TYPE_BGRA_8, m_DisplayRenderIntent, cmsFLAGS_COPY_ALPHA)
.ThisWSToDisplayTransform32 = LittleCMS.LCMS_CreateTwoProfileTransform(.LcmsProfileHandle, m_ProfileCache(m_CurrentDisplayIndex).LcmsProfileHandle, TYPE_BGRA_8, TYPE_BGRA_8, m_DisplayRenderIntent, trnsFlags Or cmsFLAGS_COPY_ALPHA)
.IndexOfDisplayTransform = m_CurrentDisplayIndex
End If

'Verify the 24-bpp conversion handle
Else
If (.ThisWSToDisplayTransform24 = 0) Or (.IndexOfDisplayTransform <> m_CurrentDisplayIndex) Then
If (.ThisWSToDisplayTransform24 <> 0) Then LittleCMS.LCMS_DeleteTransform .ThisWSToDisplayTransform24
.ThisWSToDisplayTransform24 = LittleCMS.LCMS_CreateTwoProfileTransform(.LcmsProfileHandle, m_ProfileCache(m_CurrentDisplayIndex).LcmsProfileHandle, TYPE_BGR_8, TYPE_BGR_8, m_DisplayRenderIntent, 0&)
.ThisWSToDisplayTransform24 = LittleCMS.LCMS_CreateTwoProfileTransform(.LcmsProfileHandle, m_ProfileCache(m_CurrentDisplayIndex).LcmsProfileHandle, TYPE_BGR_8, TYPE_BGR_8, m_DisplayRenderIntent, trnsFlags)
.IndexOfDisplayTransform = m_CurrentDisplayIndex
End If
End If
Expand Down

0 comments on commit 9518509

Please sign in to comment.