Skip to content

Commit

Permalink
feat: added support for 16 bit textures.
Browse files Browse the repository at this point in the history
Adds 16 bit texture support to cornerstone3D
  - CSWIL will decide on array type to match native storage format. In the case native format is unsigned int, if the scaling params are negative, prescale = true will return back a signed int.
  - Streaming Volume does require the array buffer type to be predetermined (targetBuffer must be specified). This is because all incoming slices need to adhere to one data type.
  - Block Height is set to 1 in the case norm16 is used due to this chromium bug: https://bugs.chromium.org/p/chromium/issues/detail?id=1408247. In the case preferSizeOverAccuracy is used block height for texture transfers can be calculated as usual.

TODO:
  - CSWIL needs to implement scaling logic. When a buffer type is not provided native is used (using signed versions of array buffers in the case scale is negative). When a buffer type is provided scaling will occur with possible over/underflows.

Co-authored-by: sedghi <[email protected]>
  • Loading branch information
Ouwen and sedghi committed Mar 13, 2023
1 parent 32da347 commit 0833bf6
Show file tree
Hide file tree
Showing 37 changed files with 620 additions and 159 deletions.
45 changes: 41 additions & 4 deletions common/reviews/api/core.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,16 @@ enum ContourType {
OPEN_PLANAR = "OPEN_PLANAR"
}

// @public (undocumented)
type Cornerstone3DConfig = {
detectGPU: any;
rendering: {
preferSizeOverAccuracy: boolean;
useNorm16Texture: boolean;
useCPURendering: boolean;
};
};

// @public (undocumented)
interface CPUFallbackColormap {
// (undocumented)
Expand Down Expand Up @@ -464,6 +474,9 @@ function createAndCacheVolume(volumeId: string, options: VolumeLoaderOptions): P
// @public (undocumented)
function createFloat32SharedArray(length: number): Float32Array;

// @public (undocumented)
function createInt16SharedArray(length: number): Int16Array;

// @public (undocumented)
function createLinearRGBTransferFunction(voiRange: VOIRange): vtkColorTransferFunction;

Expand All @@ -473,6 +486,9 @@ function createLocalVolume(options: LocalVolumeOptions, volumeId: string, preven
// @public (undocumented)
function createSigmoidRGBTransferFunction(voiRange: VOIRange, approximationNodes?: number): vtkColorTransferFunction;

// @public (undocumented)
function createUint16SharedArray(length: number): Uint16Array;

// @public (undocumented)
function createUint8SharedArray(length: number): Uint8Array;

Expand All @@ -490,6 +506,9 @@ interface CustomEvent_2<T = any> extends Event {
initCustomEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, detailArg: T): void;
}

// @public (undocumented)
const deepMerge: (target?: {}, source?: {}, optionsArgument?: any) => any;

// @public (undocumented)
type ElementDisabledEvent = CustomEvent_2<ElementDisabledEventDetail>;

Expand Down Expand Up @@ -660,6 +679,9 @@ function getClosestImageId(imageVolume: IImageVolume, worldPos: Point3, viewPlan
// @public (undocumented)
function getClosestStackImageIndexForPoint(point: Point3, viewport: IStackViewport): number | null;

// @public (undocumented)
export function getConfiguration(): Cornerstone3DConfig;

// @public (undocumented)
export function getEnabledElement(element: HTMLDivElement | undefined): IEnabledElement | undefined;

Expand Down Expand Up @@ -693,6 +715,12 @@ export function getRenderingEngines(): IRenderingEngine[] | undefined;
// @public (undocumented)
function getRuntimeId(context?: unknown, separator?: string, max?: number): string;

// @public (undocumented)
function getScalarDataType(scalingParameters: ScalingParameters, scalarData?: any): string;

// @public (undocumented)
function getScalingParameters(imageId: string): ScalingParameters;

// @public (undocumented)
export function getShouldUseCPURendering(): boolean;

Expand Down Expand Up @@ -1054,7 +1082,7 @@ interface IImageData {
};
};
// (undocumented)
scalarData: Float32Array;
scalarData: Float32Array | Uint16Array | Uint8Array | Int16Array;
// (undocumented)
scaling?: Scaling;
// (undocumented)
Expand Down Expand Up @@ -1324,7 +1352,7 @@ type ImageVolumeModifiedEventDetail = {
function indexWithinDimensions(index: Point3, dimensions: Point3): boolean;

// @public (undocumented)
export function init(defaultConfiguration?: {}): Promise<boolean>;
export function init(configuration?: {}): Promise<boolean>;

// @public (undocumented)
enum InterpolationType {
Expand Down Expand Up @@ -1937,6 +1965,9 @@ type ScalingParameters = {
suvbsa?: number;
};

// @public (undocumented)
export function setConfiguration(c: Cornerstone3DConfig): void;

// @public (undocumented)
export class Settings {
constructor(base?: Settings);
Expand Down Expand Up @@ -2150,6 +2181,7 @@ export function triggerEvent(el: EventTarget, type: string, detail?: unknown): b

declare namespace Types {
export {
Cornerstone3DConfig,
ICamera,
IStackViewport,
IVolumeViewport,
Expand Down Expand Up @@ -2246,6 +2278,8 @@ declare namespace utilities {
isOpposite,
createFloat32SharedArray,
createUint8SharedArray,
createUint16SharedArray,
createInt16SharedArray,
windowLevel,
getClosestImageId,
getSpacingInNormalDirection,
Expand All @@ -2270,7 +2304,10 @@ declare namespace utilities {
spatialRegistrationMetadataProvider,
getViewportImageCornersInWorld,
hasNaNValues,
applyPreset
applyPreset,
deepMerge,
getScalingParameters,
getScalarDataType
}
}
export { utilities }
Expand Down Expand Up @@ -2558,7 +2595,7 @@ type VolumeNewImageEventDetail = {
};

// @public (undocumented)
type VolumeScalarData = Float32Array | Uint8Array;
type VolumeScalarData = Float32Array | Uint8Array | Uint16Array | Int16Array;

// @public (undocumented)
export class VolumeViewport extends BaseVolumeViewport {
Expand Down
35 changes: 33 additions & 2 deletions common/reviews/api/streaming-image-volume-loader.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,37 @@ enum ContourType {
OPEN_PLANAR = 'OPEN_PLANAR',
}

// @public (undocumented)
type Cornerstone3DConfig = {
detectGPU: any;
rendering: {
// vtk.js supports 8bit integer textures and 32bit float textures.
// However, if the client has norm16 textures (it can be seen by visiting
// the webGl report at https://webglreport.com/?v=2), vtk will be default
// to use it to improve memory usage. However, if the client don't have
// it still another level of optimization can happen by setting the
// preferSizeOverAccuracy since it will reduce the size of the texture to half
// float at the cost of accuracy in rendering. This is a tradeoff that the
// client can decide.
//
// Read more in the following Pull Request:
// 1. HalfFloat: https://github.com/Kitware/vtk-js/pull/2046
// 2. Norm16: https://github.com/Kitware/vtk-js/pull/2058
preferSizeOverAccuracy: boolean;
// Whether the EXT_texture_norm16 extension is supported by the browser.
// WebGL 2 report (link: https://webglreport.com/?v=2) can be used to check
// if the browser supports this extension.
// In case the browser supports this extension, instead of using 32bit float
// textures, 16bit float textures will be used to reduce the memory usage where
// possible.
// Norm16 may not work currently due to the two active bugs in chrome + safari
// https://bugs.chromium.org/p/chromium/issues/detail?id=1408247
// https://bugs.webkit.org/show_bug.cgi?id=252039
useNorm16Texture: boolean;
useCPURendering: boolean;
};
};

// @public (undocumented)
export function cornerstoneStreamingDynamicImageVolumeLoader(volumeId: string, options: {
imageIds: string[];
Expand Down Expand Up @@ -744,7 +775,7 @@ interface IImageData {
suvbw?: number;
};
};
scalarData: Float32Array;
scalarData: Float32Array | Uint16Array | Uint8Array | Int16Array;
scaling?: Scaling;
spacing: Point3;
}
Expand Down Expand Up @@ -1525,7 +1556,7 @@ type VolumeNewImageEventDetail = {
};

// @public (undocumented)
type VolumeScalarData = Float32Array | Uint8Array;
type VolumeScalarData = Float32Array | Uint8Array | Uint16Array | Int16Array;

// @public
type VolumeViewportProperties = {
Expand Down
43 changes: 35 additions & 8 deletions common/reviews/api/tools.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,37 @@ function copyPoints(points: ITouchPoints): ITouchPoints;
// @public (undocumented)
function copyPointsList(points: ITouchPoints[]): ITouchPoints[];

// @public (undocumented)
type Cornerstone3DConfig = {
detectGPU: any;
rendering: {
// vtk.js supports 8bit integer textures and 32bit float textures.
// However, if the client has norm16 textures (it can be seen by visiting
// the webGl report at https://webglreport.com/?v=2), vtk will be default
// to use it to improve memory usage. However, if the client don't have
// it still another level of optimization can happen by setting the
// preferSizeOverAccuracy since it will reduce the size of the texture to half
// float at the cost of accuracy in rendering. This is a tradeoff that the
// client can decide.
//
// Read more in the following Pull Request:
// 1. HalfFloat: https://github.com/Kitware/vtk-js/pull/2046
// 2. Norm16: https://github.com/Kitware/vtk-js/pull/2058
preferSizeOverAccuracy: boolean;
// Whether the EXT_texture_norm16 extension is supported by the browser.
// WebGL 2 report (link: https://webglreport.com/?v=2) can be used to check
// if the browser supports this extension.
// In case the browser supports this extension, instead of using 32bit float
// textures, 16bit float textures will be used to reduce the memory usage where
// possible.
// Norm16 may not work currently due to the two active bugs in chrome + safari
// https://bugs.chromium.org/p/chromium/issues/detail?id=1408247
// https://bugs.webkit.org/show_bug.cgi?id=252039
useNorm16Texture: boolean;
useCPURendering: boolean;
};
};

// @public (undocumented)
const CORNERSTONE_COLOR_LUT: number[][];

Expand Down Expand Up @@ -1080,9 +1111,9 @@ function createLabelmapVolumeForViewport(input: {
segmentationId?: string;
options?: {
volumeId?: string;
scalarData?: Float32Array | Uint8Array;
scalarData?: Float32Array | Uint8Array | Uint16Array | Int16Array;
targetBuffer?: {
type: 'Float32Array' | 'Uint8Array';
type: 'Float32Array' | 'Uint8Array' | 'Uint16Array' | 'Int8Array';
};
metadata?: any;
dimensions?: Types_2.Point3;
Expand Down Expand Up @@ -1289,9 +1320,6 @@ function debounce(func: Function, wait?: number, options?: {
trailing?: boolean;
}): Function;

// @public (undocumented)
function deepmerge(target?: {}, source?: {}, optionsArgument?: any): any;

// @public (undocumented)
const _default: {
filterAnnotationsWithinSlice: typeof filterAnnotationsWithinSlice;
Expand Down Expand Up @@ -2353,7 +2381,7 @@ interface IImageData {
suvbw?: number;
};
};
scalarData: Float32Array;
scalarData: Float32Array | Uint16Array | Uint8Array | Int16Array;
scaling?: Scaling;
spacing: Point3;
}
Expand Down Expand Up @@ -5077,7 +5105,6 @@ declare namespace utilities {
viewportFilters,
drawing_2 as drawing,
debounce,
deepmerge as deepMerge,
dynamicVolume,
throttle,
orientation_2 as orientation,
Expand Down Expand Up @@ -5278,7 +5305,7 @@ export class VolumeRotateMouseWheelTool extends BaseTool {
}

// @public (undocumented)
type VolumeScalarData = Float32Array | Uint8Array;
type VolumeScalarData = Float32Array | Uint8Array | Uint16Array | Int16Array;

// @public
type VolumeViewportProperties = {
Expand Down
Loading

0 comments on commit 0833bf6

Please sign in to comment.