Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions src/components/SlideViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
selectedPresentationStateUID: this.props.selectedPresentationStateUID,
loadingFrames: new Set(),
isICCProfilesEnabled: true,
isPaletteDisplayGammaCorrectionEnabled:
volumeViewer.getPaletteDisplayGammaCorrectionEnabled(),
isSegmentationInterpolationEnabled: false,
isParametricMapInterpolationEnabled: true,
customizedSegmentColors: {},
Expand All @@ -317,6 +319,7 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
*/
private static readonly createSegmentPaletteColorLookupTable = (
segmentColor: number[],
applyDisplayGammaCorrection = true,
): dmv.color.PaletteColorLookupTable => {
/** Create a simple palette with the segment color
* For binary segments, we typically have 2 values: background (0) and segment (1) */
Expand All @@ -328,6 +331,7 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
return dmv.color.buildPaletteColorLookupTable({
data: paletteData,
firstValueMapped: 0,
applyDisplayGammaCorrection,
})
}

Expand Down Expand Up @@ -402,6 +406,9 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
})
this.volumeViewer = volumeViewer
this.labelViewer = labelViewer
this.volumeViewer.setPaletteDisplayGammaCorrectionEnabled(
this.state.isPaletteDisplayGammaCorrectionEnabled,
)

const activeOpticalPathIdentifiers: Set<string> = new Set()
const visibleOpticalPathIdentifiers: Set<string> = new Set()
Expand Down Expand Up @@ -3016,7 +3023,10 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
}
if (styleOptions.color !== undefined) {
stylePayload.paletteColorLookupTable =
SlideViewer.createSegmentPaletteColorLookupTable(styleOptions.color)
SlideViewer.createSegmentPaletteColorLookupTable(
styleOptions.color,
this.volumeViewer.getPaletteDisplayGammaCorrectionEnabled(),
)
}

this.volumeViewer.setSegmentStyle(segmentUID, stylePayload)
Expand Down Expand Up @@ -3578,6 +3588,15 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
this.volumeViewer.toggleICCProfiles()
}

/**
* Toggle display gamma compensation for palette-based rendering (optical paths,
* segment overlays, parametric maps).
*/
handlePaletteDisplayGammaCorrectionToggle = (checked: boolean): void => {
this.setState({ isPaletteDisplayGammaCorrectionEnabled: checked })
this.volumeViewer.setPaletteDisplayGammaCorrectionEnabled(checked)
}

/**
* Handler that will toggle the segmentation interpolation, i.e., either
* enable or disable it, depending on its current state.
Expand Down Expand Up @@ -4084,6 +4103,7 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
defaultSegmentStyles[segment.uid].color !== undefined
? SlideViewer.createSegmentPaletteColorLookupTable(
defaultSegmentStyles[segment.uid].color as number[],
this.volumeViewer.getPaletteDisplayGammaCorrectionEnabled(),
)
: undefined,
})
Expand Down Expand Up @@ -4565,6 +4585,26 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
)
}

private readonly getPaletteDisplayGammaCorrectionMenu =
(): React.ReactNode => {
return (
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginTop: '0.75rem',
}}
>
<span>Gamma correction</span>
<Switch
checked={this.state.isPaletteDisplayGammaCorrectionEnabled}
onChange={this.handlePaletteDisplayGammaCorrectionToggle}
/>
</div>
)
}

private readonly getSegmentationInterpolationMenu = (): React.ReactNode => {
const segments = this.volumeViewer.getAllSegments()
return (
Expand All @@ -4588,14 +4628,18 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {

private readonly getSettingsPanelContent = (menus: {
iccProfilesMenu: React.ReactNode
gammaCorrectionMenu: React.ReactNode
segmentationInterpolationMenu: React.ReactNode
}): React.ReactNode => {
const menuItems: React.ReactNode[] = []

menuItems.push(
<Menu.SubMenu key="display" title="Display">
<Menu.Item key="display-content" disabled style={{ cursor: 'default' }}>
<div className="slim-settings-content">{menus.iccProfilesMenu}</div>
<div className="slim-settings-content">
{menus.iccProfilesMenu}
{menus.gammaCorrectionMenu}
</div>
</Menu.Item>
</Menu.SubMenu>,
)
Expand Down Expand Up @@ -4734,13 +4778,15 @@ class SlideViewer extends React.Component<SlideViewerProps, SlideViewerState> {
const cursor = this.getCursor()
const selectedRoiInformation = this.getSelectedRoiInformation()
const iccProfilesMenu = this.getICCProfilesMenu()
const gammaCorrectionMenu = this.getPaletteDisplayGammaCorrectionMenu()
const segmentationInterpolationMenu =
this.getSegmentationInterpolationMenu()

const presentationStateMenu = this.getPresentationStateMenu()

const settingsPanelContent = this.getSettingsPanelContent({
iccProfilesMenu,
gammaCorrectionMenu,
segmentationInterpolationMenu,
})

Expand Down
1 change: 1 addition & 0 deletions src/components/SlideViewer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export interface SlideViewerState {
}
loadingFrames: Set<string>
isICCProfilesEnabled: boolean
isPaletteDisplayGammaCorrectionEnabled: boolean
isSegmentationInterpolationEnabled: boolean
isParametricMapInterpolationEnabled: boolean
customizedSegmentColors: { [segmentUID: string]: number[] }
Expand Down
7 changes: 7 additions & 0 deletions types/dicom-microscopy-viewer/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ declare module 'dicom-microscopy-viewer' {
controls: string[]
annotationOptions?: object
errorInterceptor?: (error: CustomError) => void
paletteDisplayGammaCorrection?: boolean
}

export interface ROIStyleOptions {
Expand Down Expand Up @@ -232,6 +233,8 @@ declare module 'dicom-microscopy-viewer' {
): metadata.MicroscopyBulkSimpleAnnotations
toggleICCProfiles (): void;
getICCProfiles (): any[];
setPaletteDisplayGammaCorrectionEnabled (enabled: boolean): void;
getPaletteDisplayGammaCorrectionEnabled (): boolean;
toggleSegmentationInterpolation (): void;
toggleParametricMapInterpolation (): void;
}
Expand Down Expand Up @@ -814,11 +817,13 @@ declare module 'dicom-microscopy-viewer' {
redSegmentedData?: Unit8Array|Unit16Array
greenSegmentedData?: Unit8Array|Unit16Array
blueSegmentedData?: Unit8Array|Unit16Array
applyDisplayGammaCorrection?: boolean
}

export interface BuildPaletteColorLookupTableOptions {
data: number[][]
firstValueMapped: number
applyDisplayGammaCorrection?: boolean
}

export function buildPaletteColorLookupTable (options: BuildPaletteColorLookupTableOptions): PaletteColorLookupTable
Expand All @@ -828,6 +833,8 @@ declare module 'dicom-microscopy-viewer' {
get uid (): string
get data (): number[][]
get firstValueMapped (): number
get applyDisplayGammaCorrection (): boolean
setApplyDisplayGammaCorrection (enabled: boolean): void
}
}

Expand Down
Loading