@cornerstonejs/core 0.36.2 → 0.36.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/loaders/volumeLoader.d.ts +1 -0
- package/dist/cjs/loaders/volumeLoader.js +5 -1
- package/dist/cjs/loaders/volumeLoader.js.map +1 -1
- package/dist/cjs/utilities/getSliceRange.js +3 -1
- package/dist/cjs/utilities/getSliceRange.js.map +1 -1
- package/dist/cjs/utilities/getTargetVolumeAndSpacingInNormalDir.js +7 -0
- package/dist/cjs/utilities/getTargetVolumeAndSpacingInNormalDir.js.map +1 -1
- package/dist/esm/loaders/volumeLoader.d.ts +1 -0
- package/dist/esm/loaders/volumeLoader.js +3 -0
- package/dist/esm/loaders/volumeLoader.js.map +1 -1
- package/dist/esm/utilities/getSliceRange.js +3 -1
- package/dist/esm/utilities/getSliceRange.js.map +1 -1
- package/dist/esm/utilities/getTargetVolumeAndSpacingInNormalDir.js +7 -0
- package/dist/esm/utilities/getTargetVolumeAndSpacingInNormalDir.js.map +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/index.js.map +1 -1
- package/package.json +4 -3
- package/src/RenderingEngine/BaseVolumeViewport.ts +847 -0
- package/src/RenderingEngine/RenderingEngine.ts +1364 -0
- package/src/RenderingEngine/StackViewport.ts +2690 -0
- package/src/RenderingEngine/Viewport.ts +1244 -0
- package/src/RenderingEngine/VolumeViewport.ts +420 -0
- package/src/RenderingEngine/VolumeViewport3D.ts +42 -0
- package/src/RenderingEngine/getRenderingEngine.ts +34 -0
- package/src/RenderingEngine/helpers/addVolumesToViewports.ts +52 -0
- package/src/RenderingEngine/helpers/cpuFallback/colors/colormap.ts +343 -0
- package/src/RenderingEngine/helpers/cpuFallback/colors/index.ts +4 -0
- package/src/RenderingEngine/helpers/cpuFallback/colors/lookupTable.ts +469 -0
- package/src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts +58 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.ts +136 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.ts +25 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.ts +47 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts +38 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/createViewport.ts +64 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.ts +36 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.ts +22 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.ts +60 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/generateLut.ts +83 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.ts +88 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.ts +52 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.ts +55 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/getLut.ts +53 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.ts +55 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/getTransform.ts +17 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.ts +74 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.ts +37 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.ts +21 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/now.ts +13 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.ts +22 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.ts +193 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.ts +166 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.ts +203 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.ts +32 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/resize.ts +109 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.ts +36 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.ts +17 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.ts +32 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.ts +58 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.ts +76 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataColorLUT.ts +60 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.ts +50 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.ts +66 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.ts +68 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.ts +81 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.ts +56 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/transform.ts +126 -0
- package/src/RenderingEngine/helpers/cpuFallback/rendering/validator.ts +31 -0
- package/src/RenderingEngine/helpers/createVolumeActor.ts +103 -0
- package/src/RenderingEngine/helpers/createVolumeMapper.ts +37 -0
- package/src/RenderingEngine/helpers/getOrCreateCanvas.ts +58 -0
- package/src/RenderingEngine/helpers/index.ts +15 -0
- package/src/RenderingEngine/helpers/isRgbaSourceRgbDest.ts +1 -0
- package/src/RenderingEngine/helpers/setDefaultVolumeVOI.ts +227 -0
- package/src/RenderingEngine/helpers/setVolumesForViewports.ts +52 -0
- package/src/RenderingEngine/helpers/viewportTypeToViewportClass.ts +14 -0
- package/src/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.ts +7 -0
- package/src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts +75 -0
- package/src/RenderingEngine/index.ts +23 -0
- package/src/RenderingEngine/renderingEngineCache.ts +43 -0
- package/src/RenderingEngine/vtkClasses/index.js +11 -0
- package/src/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.js +149 -0
- package/src/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.js +52 -0
- package/src/RenderingEngine/vtkClasses/vtkSlabCamera.d.ts +781 -0
- package/src/RenderingEngine/vtkClasses/vtkSlabCamera.js +155 -0
- package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.js +47 -0
- package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js +272 -0
- package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.js +159 -0
- package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js +319 -0
- package/src/Settings.ts +294 -0
- package/src/cache/cache.ts +854 -0
- package/src/cache/classes/Contour.ts +70 -0
- package/src/cache/classes/ContourSet.ts +151 -0
- package/src/cache/classes/ImageVolume.ts +155 -0
- package/src/cache/index.ts +5 -0
- package/src/constants/cpuColormaps.ts +1537 -0
- package/src/constants/epsilon.ts +3 -0
- package/src/constants/index.ts +13 -0
- package/src/constants/mprCameraValues.ts +20 -0
- package/src/constants/rendering.ts +8 -0
- package/src/constants/viewportPresets.ts +357 -0
- package/src/enums/BlendModes.ts +23 -0
- package/src/enums/ContourType.ts +6 -0
- package/src/enums/Events.ts +196 -0
- package/src/enums/GeometryType.ts +5 -0
- package/src/enums/InterpolationType.ts +13 -0
- package/src/enums/OrientationAxis.ts +8 -0
- package/src/enums/RequestType.ts +13 -0
- package/src/enums/SharedArrayBufferModes.ts +11 -0
- package/src/enums/VOILUTFunctionType.ts +10 -0
- package/src/enums/ViewportType.ts +21 -0
- package/src/enums/index.ts +23 -0
- package/src/eventTarget.ts +67 -0
- package/src/getEnabledElement.ts +105 -0
- package/src/global.ts +8 -0
- package/src/index.ts +123 -0
- package/src/init.ts +247 -0
- package/src/loaders/geometryLoader.ts +108 -0
- package/src/loaders/imageLoader.ts +298 -0
- package/src/loaders/volumeLoader.ts +477 -0
- package/src/metaData.ts +84 -0
- package/src/requestPool/imageLoadPoolManager.ts +43 -0
- package/src/requestPool/imageRetrievalPoolManager.ts +25 -0
- package/src/requestPool/requestPoolManager.ts +329 -0
- package/src/types/ActorSliceRange.ts +17 -0
- package/src/types/CPUFallbackColormap.ts +23 -0
- package/src/types/CPUFallbackColormapData.ts +12 -0
- package/src/types/CPUFallbackColormapsData.ts +7 -0
- package/src/types/CPUFallbackEnabledElement.ts +71 -0
- package/src/types/CPUFallbackLUT.ts +5 -0
- package/src/types/CPUFallbackLookupTable.ts +17 -0
- package/src/types/CPUFallbackRenderingTools.ts +25 -0
- package/src/types/CPUFallbackTransform.ts +16 -0
- package/src/types/CPUFallbackViewport.ts +29 -0
- package/src/types/CPUFallbackViewportDisplayedArea.ts +15 -0
- package/src/types/CPUIImageData.ts +47 -0
- package/src/types/ContourData.ts +19 -0
- package/src/types/Cornerstone3DConfig.ts +31 -0
- package/src/types/CustomEventType.ts +14 -0
- package/src/types/EventTypes.ts +403 -0
- package/src/types/FlipDirection.ts +9 -0
- package/src/types/IActor.ts +23 -0
- package/src/types/ICache.ts +28 -0
- package/src/types/ICachedGeometry.ts +13 -0
- package/src/types/ICachedImage.ts +13 -0
- package/src/types/ICachedVolume.ts +12 -0
- package/src/types/ICamera.ts +36 -0
- package/src/types/IContour.ts +18 -0
- package/src/types/IContourSet.ts +56 -0
- package/src/types/IDynamicImageVolume.ts +18 -0
- package/src/types/IEnabledElement.ts +21 -0
- package/src/types/IGeometry.ts +12 -0
- package/src/types/IImage.ts +113 -0
- package/src/types/IImageData.ts +45 -0
- package/src/types/IImageVolume.ts +78 -0
- package/src/types/ILoadObject.ts +36 -0
- package/src/types/IRegisterImageLoader.ts +10 -0
- package/src/types/IRenderingEngine.ts +28 -0
- package/src/types/IStackViewport.ts +138 -0
- package/src/types/IStreamingImageVolume.ts +13 -0
- package/src/types/IStreamingVolumeProperties.ts +14 -0
- package/src/types/IViewport.ts +149 -0
- package/src/types/IViewportId.ts +9 -0
- package/src/types/IVolume.ts +45 -0
- package/src/types/IVolumeInput.ts +36 -0
- package/src/types/IVolumeViewport.ts +141 -0
- package/src/types/ImageLoaderFn.ts +16 -0
- package/src/types/ImageSliceData.ts +6 -0
- package/src/types/Mat3.ts +16 -0
- package/src/types/Metadata.ts +39 -0
- package/src/types/OrientationVectors.ts +36 -0
- package/src/types/Plane.ts +6 -0
- package/src/types/Point2.ts +6 -0
- package/src/types/Point3.ts +6 -0
- package/src/types/Point4.ts +6 -0
- package/src/types/ScalingParameters.ts +27 -0
- package/src/types/StackViewportProperties.ts +25 -0
- package/src/types/TransformMatrix2D.ts +4 -0
- package/src/types/ViewportInputOptions.ts +21 -0
- package/src/types/ViewportPreset.ts +14 -0
- package/src/types/VolumeLoaderFn.ts +18 -0
- package/src/types/VolumeViewportProperties.ts +14 -0
- package/src/types/index.ts +157 -0
- package/src/types/voi.ts +15 -0
- package/src/utilities/actorCheck.ts +24 -0
- package/src/utilities/applyPreset.ts +132 -0
- package/src/utilities/calculateViewportsSpatialRegistration.ts +74 -0
- package/src/utilities/calibratedPixelSpacingMetadataProvider.ts +38 -0
- package/src/utilities/createFloat32SharedArray.ts +45 -0
- package/src/utilities/createInt16SharedArray.ts +43 -0
- package/src/utilities/createLinearRGBTransferFunction.ts +22 -0
- package/src/utilities/createSigmoidRGBTransferFunction.ts +63 -0
- package/src/utilities/createUInt16SharedArray.ts +43 -0
- package/src/utilities/createUint8SharedArray.ts +45 -0
- package/src/utilities/deepFreeze.ts +19 -0
- package/src/utilities/deepMerge.ts +81 -0
- package/src/utilities/getClosestImageId.ts +80 -0
- package/src/utilities/getClosestStackImageIndexForPoint.ts +116 -0
- package/src/utilities/getImageSliceDataForVolumeViewport.ts +61 -0
- package/src/utilities/getMinMax.ts +31 -0
- package/src/utilities/getRuntimeId.ts +54 -0
- package/src/utilities/getScalarDataType.ts +31 -0
- package/src/utilities/getScalingParameters.ts +35 -0
- package/src/utilities/getSliceRange.ts +86 -0
- package/src/utilities/getSpacingInNormalDirection.ts +44 -0
- package/src/utilities/getTargetVolumeAndSpacingInNormalDir.ts +126 -0
- package/src/utilities/getViewportImageCornersInWorld.ts +102 -0
- package/src/utilities/getViewportsWithImageURI.ts +46 -0
- package/src/utilities/getViewportsWithVolumeId.ts +38 -0
- package/src/utilities/getVoiFromSigmoidRGBTransferFunction.ts +23 -0
- package/src/utilities/getVolumeActorCorners.ts +24 -0
- package/src/utilities/getVolumeSliceRangeInfo.ts +52 -0
- package/src/utilities/getVolumeViewportScrollInfo.ts +32 -0
- package/src/utilities/getVolumeViewportsContainingSameVolumes.ts +58 -0
- package/src/utilities/hasNaNValues.ts +12 -0
- package/src/utilities/imageIdToURI.ts +10 -0
- package/src/utilities/imageToWorldCoords.ts +54 -0
- package/src/utilities/index.ts +100 -0
- package/src/utilities/indexWithinDimensions.ts +27 -0
- package/src/utilities/invertRgbTransferFunction.ts +36 -0
- package/src/utilities/isEqual.ts +27 -0
- package/src/utilities/isOpposite.ts +23 -0
- package/src/utilities/isTypedArray.ts +20 -0
- package/src/utilities/loadImageToCanvas.ts +80 -0
- package/src/utilities/planar.ts +91 -0
- package/src/utilities/renderToCanvas.ts +32 -0
- package/src/utilities/scaleRgbTransferFunction.ts +37 -0
- package/src/utilities/snapFocalPointToSlice.ts +78 -0
- package/src/utilities/spatialRegistrationMetadataProvider.ts +50 -0
- package/src/utilities/transformWorldToIndex.ts +16 -0
- package/src/utilities/triggerEvent.ts +38 -0
- package/src/utilities/uuidv4.ts +13 -0
- package/src/utilities/windowLevel.ts +39 -0
- package/src/utilities/worldToImageCoords.ts +64 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import setToPixelCoordinateSystem from './setToPixelCoordinateSystem';
|
|
2
|
+
import now from './now';
|
|
3
|
+
import initializeRenderCanvas from './initializeRenderCanvas';
|
|
4
|
+
import getLut from './getLut';
|
|
5
|
+
import saveLastRendered from './saveLastRendered';
|
|
6
|
+
import doesImageNeedToBeRendered from './doesImageNeedToBeRendered';
|
|
7
|
+
import storedPixelDataToCanvasImageDataPseudocolorLUT from './storedPixelDataToCanvasImageDataPseudocolorLUT';
|
|
8
|
+
import storedPixelDataToCanvasImageDataPseudocolorLUTPET from './storedPixelDataToCanvasImageDataPseudocolorLUTPET';
|
|
9
|
+
import * as colors from '../colors/index';
|
|
10
|
+
import type { IImage, CPUFallbackEnabledElement } from '../../../../types';
|
|
11
|
+
|
|
12
|
+
function clamp(value: number, min: number, max: number) {
|
|
13
|
+
return Math.max(min, Math.min(max, value));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate
|
|
18
|
+
* it is returned, otherwise adjustments are made. It also sets the color transfer functions.
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} enabledElement The cornerstone enabled element
|
|
21
|
+
* @param {Object} image The image to be rendered
|
|
22
|
+
* @param {Boolean} invalidated Is pixel data valid
|
|
23
|
+
* @returns {HTMLCanvasElement} An appropriate canvas for rendering the image
|
|
24
|
+
* @memberof rendering
|
|
25
|
+
*/
|
|
26
|
+
function getRenderCanvas(
|
|
27
|
+
enabledElement: CPUFallbackEnabledElement,
|
|
28
|
+
image: IImage,
|
|
29
|
+
invalidated: boolean
|
|
30
|
+
): HTMLCanvasElement {
|
|
31
|
+
if (!enabledElement.renderingTools.renderCanvas) {
|
|
32
|
+
enabledElement.renderingTools.renderCanvas =
|
|
33
|
+
document.createElement('canvas');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const renderCanvas = enabledElement.renderingTools.renderCanvas;
|
|
37
|
+
|
|
38
|
+
let colormap =
|
|
39
|
+
enabledElement.viewport.colormap || enabledElement.options.colormap;
|
|
40
|
+
|
|
41
|
+
if (enabledElement.options && enabledElement.options.colormap) {
|
|
42
|
+
console.warn(
|
|
43
|
+
'enabledElement.options.colormap is deprecated. Use enabledElement.viewport.colormap instead'
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
if (colormap && typeof colormap === 'string') {
|
|
47
|
+
colormap = colors.getColormap(colormap);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!colormap) {
|
|
51
|
+
throw new Error('renderPseudoColorImage: colormap not found.');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const colormapId = colormap.getId();
|
|
55
|
+
|
|
56
|
+
if (
|
|
57
|
+
doesImageNeedToBeRendered(enabledElement, image) === false &&
|
|
58
|
+
invalidated !== true &&
|
|
59
|
+
enabledElement.renderingTools.colormapId === colormapId
|
|
60
|
+
) {
|
|
61
|
+
return renderCanvas;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// If our render canvas does not match the size of this image reset it
|
|
65
|
+
// NOTE: This might be inefficient if we are updating multiple images of different
|
|
66
|
+
// Sizes frequently.
|
|
67
|
+
if (
|
|
68
|
+
renderCanvas.width !== image.width ||
|
|
69
|
+
renderCanvas.height !== image.height
|
|
70
|
+
) {
|
|
71
|
+
initializeRenderCanvas(enabledElement, image);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Get the lut to use
|
|
75
|
+
let start = now();
|
|
76
|
+
|
|
77
|
+
if (
|
|
78
|
+
!enabledElement.renderingTools.colorLUT ||
|
|
79
|
+
invalidated ||
|
|
80
|
+
enabledElement.renderingTools.colormapId !== colormapId
|
|
81
|
+
) {
|
|
82
|
+
colormap.setNumberOfColors(256);
|
|
83
|
+
enabledElement.renderingTools.colorLUT = colormap.createLookupTable();
|
|
84
|
+
enabledElement.renderingTools.colormapId = colormapId;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const renderCanvasData = enabledElement.renderingTools.renderCanvasData;
|
|
88
|
+
const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;
|
|
89
|
+
const { viewport } = enabledElement;
|
|
90
|
+
const colorLUT = enabledElement.renderingTools.colorLUT;
|
|
91
|
+
|
|
92
|
+
if (viewport.modality === 'PT') {
|
|
93
|
+
const { windowWidth, windowCenter } = viewport.voi;
|
|
94
|
+
const minimum = windowCenter - windowWidth / 2;
|
|
95
|
+
const maximum = windowCenter + windowWidth / 2;
|
|
96
|
+
const range = maximum - minimum;
|
|
97
|
+
const collectedMultiplierTerms = 255.0 / range;
|
|
98
|
+
|
|
99
|
+
let petVOILutFunction;
|
|
100
|
+
|
|
101
|
+
if (viewport.invert) {
|
|
102
|
+
petVOILutFunction = (value) => {
|
|
103
|
+
return clamp(
|
|
104
|
+
Math.floor(255 - (value - minimum) * collectedMultiplierTerms),
|
|
105
|
+
0,
|
|
106
|
+
255
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
} else {
|
|
110
|
+
petVOILutFunction = (value) => {
|
|
111
|
+
return clamp(
|
|
112
|
+
Math.floor((value - minimum) * collectedMultiplierTerms),
|
|
113
|
+
0,
|
|
114
|
+
255
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
storedPixelDataToCanvasImageDataPseudocolorLUTPET(
|
|
120
|
+
image,
|
|
121
|
+
petVOILutFunction,
|
|
122
|
+
colorLUT,
|
|
123
|
+
renderCanvasData.data
|
|
124
|
+
);
|
|
125
|
+
} else {
|
|
126
|
+
const lut = getLut(image, enabledElement.viewport, invalidated);
|
|
127
|
+
|
|
128
|
+
image.stats = image.stats || {};
|
|
129
|
+
image.stats.lastLutGenerateTime = now() - start;
|
|
130
|
+
|
|
131
|
+
storedPixelDataToCanvasImageDataPseudocolorLUT(
|
|
132
|
+
image,
|
|
133
|
+
lut,
|
|
134
|
+
colorLUT,
|
|
135
|
+
renderCanvasData.data
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
start = now();
|
|
140
|
+
renderCanvasContext.putImageData(renderCanvasData, 0, 0);
|
|
141
|
+
image.stats.lastPutImageDataTime = now() - start;
|
|
142
|
+
|
|
143
|
+
return renderCanvas;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* API function to draw a pseudo-color image to a given enabledElement
|
|
148
|
+
*
|
|
149
|
+
* @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw
|
|
150
|
+
* @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used
|
|
151
|
+
* @returns {void}
|
|
152
|
+
* @memberof rendering
|
|
153
|
+
*/
|
|
154
|
+
export function renderPseudoColorImage(
|
|
155
|
+
enabledElement: CPUFallbackEnabledElement,
|
|
156
|
+
invalidated: boolean
|
|
157
|
+
): void {
|
|
158
|
+
if (enabledElement === undefined) {
|
|
159
|
+
throw new Error(
|
|
160
|
+
'drawImage: enabledElement parameter must not be undefined'
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const image = enabledElement.image;
|
|
165
|
+
|
|
166
|
+
if (image === undefined) {
|
|
167
|
+
throw new Error('drawImage: image must be loaded before it can be drawn');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Get the canvas context and reset the transform
|
|
171
|
+
const context = enabledElement.canvas.getContext('2d');
|
|
172
|
+
|
|
173
|
+
context.setTransform(1, 0, 0, 1, 0, 0);
|
|
174
|
+
|
|
175
|
+
// Clear the canvas
|
|
176
|
+
context.fillStyle = 'black';
|
|
177
|
+
context.fillRect(
|
|
178
|
+
0,
|
|
179
|
+
0,
|
|
180
|
+
enabledElement.canvas.width,
|
|
181
|
+
enabledElement.canvas.height
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
// Turn off image smooth/interpolation if pixelReplication is set in the viewport
|
|
185
|
+
context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;
|
|
186
|
+
|
|
187
|
+
// Save the canvas context state and apply the viewport properties
|
|
188
|
+
setToPixelCoordinateSystem(enabledElement, context);
|
|
189
|
+
|
|
190
|
+
// If no options are set we will retrieve the renderCanvas through the
|
|
191
|
+
// Normal Canvas rendering path
|
|
192
|
+
// TODO: Add WebGL support for pseudocolor pipeline
|
|
193
|
+
const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);
|
|
194
|
+
|
|
195
|
+
const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;
|
|
196
|
+
const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;
|
|
197
|
+
const width = enabledElement.viewport.displayedArea.brhc.x - sx;
|
|
198
|
+
const height = enabledElement.viewport.displayedArea.brhc.y - sy;
|
|
199
|
+
|
|
200
|
+
context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);
|
|
201
|
+
|
|
202
|
+
enabledElement.renderingTools = saveLastRendered(enabledElement);
|
|
203
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import getImageFitScale from './getImageFitScale';
|
|
2
|
+
import { CPUFallbackEnabledElement } from '../../../../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Resets the camera to the default position. which would be the center of the image.
|
|
6
|
+
* with no translation, no flipping, no zoom and proper scale.
|
|
7
|
+
*/
|
|
8
|
+
export default function (
|
|
9
|
+
enabledElement: CPUFallbackEnabledElement,
|
|
10
|
+
resetPan = true,
|
|
11
|
+
resetZoom = true
|
|
12
|
+
): void {
|
|
13
|
+
const { canvas, image, viewport } = enabledElement;
|
|
14
|
+
const scale = getImageFitScale(canvas, image, 0).scaleFactor;
|
|
15
|
+
|
|
16
|
+
viewport.vflip = false;
|
|
17
|
+
viewport.hflip = false;
|
|
18
|
+
|
|
19
|
+
if (resetPan) {
|
|
20
|
+
viewport.translation.x = 0;
|
|
21
|
+
viewport.translation.y = 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (resetZoom) {
|
|
25
|
+
viewport.displayedArea.tlhc.x = 1;
|
|
26
|
+
viewport.displayedArea.tlhc.y = 1;
|
|
27
|
+
viewport.displayedArea.brhc.x = image.columns;
|
|
28
|
+
viewport.displayedArea.brhc.y = image.rows;
|
|
29
|
+
|
|
30
|
+
viewport.scale = scale;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import fitToWindow from './fitToWindow';
|
|
2
|
+
import getImageSize from './getImageSize';
|
|
3
|
+
import { CPUFallbackEnabledElement } from '../../../../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This module is responsible for enabling an element to display images with cornerstone
|
|
7
|
+
*
|
|
8
|
+
* @param {HTMLDivElement} element The DOM element enabled for Cornerstone
|
|
9
|
+
* @param {HTMLDivElement} canvas The Canvas DOM element within the DOM element enabled for Cornerstone
|
|
10
|
+
* @returns {void}
|
|
11
|
+
*/
|
|
12
|
+
function setCanvasSize(enabledElement: CPUFallbackEnabledElement) {
|
|
13
|
+
const { canvas } = enabledElement;
|
|
14
|
+
const { clientWidth, clientHeight } = canvas;
|
|
15
|
+
|
|
16
|
+
// Set the canvas to be same resolution as the client.
|
|
17
|
+
if (canvas.width !== clientWidth || canvas.height !== clientHeight) {
|
|
18
|
+
canvas.width = clientWidth;
|
|
19
|
+
canvas.height = clientHeight;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Checks if the image of a given enabled element fitted the window
|
|
25
|
+
* before the resize
|
|
26
|
+
*
|
|
27
|
+
* @param {EnabledElement} enabledElement The Cornerstone Enabled Element
|
|
28
|
+
* @param {number} oldCanvasWidth The width of the canvas before the resize
|
|
29
|
+
* @param {number} oldCanvasHeight The height of the canvas before the resize
|
|
30
|
+
* @return {Boolean} true if it fitted the windows, false otherwise
|
|
31
|
+
*/
|
|
32
|
+
function wasFitToWindow(
|
|
33
|
+
enabledElement: CPUFallbackEnabledElement,
|
|
34
|
+
oldCanvasWidth: number,
|
|
35
|
+
oldCanvasHeight: number
|
|
36
|
+
): boolean {
|
|
37
|
+
const scale = enabledElement.viewport.scale;
|
|
38
|
+
const imageSize = getImageSize(
|
|
39
|
+
enabledElement.image,
|
|
40
|
+
enabledElement.viewport.rotation
|
|
41
|
+
);
|
|
42
|
+
const imageWidth = Math.round(imageSize.width * scale);
|
|
43
|
+
const imageHeight = Math.round(imageSize.height * scale);
|
|
44
|
+
const x = enabledElement.viewport.translation.x;
|
|
45
|
+
const y = enabledElement.viewport.translation.y;
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
(imageWidth === oldCanvasWidth && imageHeight <= oldCanvasHeight) ||
|
|
49
|
+
(imageWidth <= oldCanvasWidth &&
|
|
50
|
+
imageHeight === oldCanvasHeight &&
|
|
51
|
+
x === 0 &&
|
|
52
|
+
y === 0)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Rescale the image relative to the changed size of the canvas
|
|
58
|
+
*
|
|
59
|
+
* @param {EnabledElement} enabledElement The Cornerstone Enabled Element
|
|
60
|
+
* @param {number} oldCanvasWidth The width of the canvas before the resize
|
|
61
|
+
* @param {number} oldCanvasHeight The height of the canvas before the resize
|
|
62
|
+
* @return {void}
|
|
63
|
+
*/
|
|
64
|
+
function relativeRescale(
|
|
65
|
+
enabledElement: CPUFallbackEnabledElement,
|
|
66
|
+
oldCanvasWidth: number,
|
|
67
|
+
oldCanvasHeight: number
|
|
68
|
+
): void {
|
|
69
|
+
const scale = enabledElement.viewport.scale;
|
|
70
|
+
const canvasWidth = enabledElement.canvas.width;
|
|
71
|
+
const canvasHeight = enabledElement.canvas.height;
|
|
72
|
+
const relWidthChange = canvasWidth / oldCanvasWidth;
|
|
73
|
+
const relHeightChange = canvasHeight / oldCanvasHeight;
|
|
74
|
+
const relChange = Math.sqrt(relWidthChange * relHeightChange);
|
|
75
|
+
|
|
76
|
+
enabledElement.viewport.scale = relChange * scale;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Resizes an enabled element and optionally fits the image to window
|
|
81
|
+
*
|
|
82
|
+
* @param {HTMLDivElement} element The DOM element enabled for Cornerstone
|
|
83
|
+
* @param {Boolean} forceFitToWindow true to to force a refit, false to rescale accordingly
|
|
84
|
+
* @returns {void}
|
|
85
|
+
*/
|
|
86
|
+
export default function (
|
|
87
|
+
enabledElement: CPUFallbackEnabledElement,
|
|
88
|
+
forceFitToWindow = false
|
|
89
|
+
): void {
|
|
90
|
+
const oldCanvasWidth = enabledElement.canvas.width;
|
|
91
|
+
const oldCanvasHeight = enabledElement.canvas.height;
|
|
92
|
+
|
|
93
|
+
setCanvasSize(enabledElement);
|
|
94
|
+
|
|
95
|
+
if (enabledElement.image === undefined) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (
|
|
100
|
+
forceFitToWindow ||
|
|
101
|
+
wasFitToWindow(enabledElement, oldCanvasWidth, oldCanvasHeight)
|
|
102
|
+
) {
|
|
103
|
+
// Fit the image to the window again if it fitted before the resize
|
|
104
|
+
fitToWindow(enabledElement);
|
|
105
|
+
} else {
|
|
106
|
+
// Adapt the scale of a zoomed or panned image relative to the size change
|
|
107
|
+
relativeRescale(enabledElement, oldCanvasWidth, oldCanvasHeight);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CPUFallbackEnabledElement,
|
|
3
|
+
CPUFallbackRenderingTools,
|
|
4
|
+
} from '../../../../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Saves the parameters of the last render into renderingTools, used later to decide if data can be reused.
|
|
8
|
+
*
|
|
9
|
+
* @param {Object} enabledElement Cornerstone EnabledElement
|
|
10
|
+
* @returns {Object} enabledElement.renderingTools
|
|
11
|
+
* @memberof rendering
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export default function (
|
|
15
|
+
enabledElement: CPUFallbackEnabledElement
|
|
16
|
+
): CPUFallbackRenderingTools {
|
|
17
|
+
const imageId = enabledElement.image.imageId;
|
|
18
|
+
const viewport = enabledElement.viewport;
|
|
19
|
+
const isColor = enabledElement.image.color;
|
|
20
|
+
|
|
21
|
+
enabledElement.renderingTools.lastRenderedImageId = imageId;
|
|
22
|
+
enabledElement.renderingTools.lastRenderedIsColor = isColor;
|
|
23
|
+
enabledElement.renderingTools.lastRenderedViewport = {
|
|
24
|
+
windowCenter: viewport.voi.windowCenter,
|
|
25
|
+
windowWidth: viewport.voi.windowWidth,
|
|
26
|
+
invert: viewport.invert,
|
|
27
|
+
rotation: viewport.rotation,
|
|
28
|
+
hflip: viewport.hflip,
|
|
29
|
+
vflip: viewport.vflip,
|
|
30
|
+
modalityLUT: viewport.modalityLUT,
|
|
31
|
+
voiLUT: viewport.voiLUT,
|
|
32
|
+
colormap: viewport.colormap,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return enabledElement.renderingTools;
|
|
36
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CPUFallbackViewport } from '../../../../types';
|
|
2
|
+
|
|
3
|
+
const state = {
|
|
4
|
+
viewport: {},
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Sets new default values for `getDefaultViewport`
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} viewport - Object that sets new default values for getDefaultViewport
|
|
11
|
+
* @returns {undefined}
|
|
12
|
+
*/
|
|
13
|
+
export default function (viewport: CPUFallbackViewport): void {
|
|
14
|
+
state.viewport = viewport || {};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { state };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import calculateTransform from './calculateTransform';
|
|
2
|
+
import { CPUFallbackEnabledElement } from '../../../../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Sets the canvas context transformation matrix to the pixel coordinate system. This allows
|
|
6
|
+
* geometry to be driven using the canvas context using coordinates in the pixel coordinate system
|
|
7
|
+
* @param {EnabledElement} enabledElement The
|
|
8
|
+
* @param {CanvasRenderingContext2D} context The CanvasRenderingContext2D for the enabledElement's Canvas
|
|
9
|
+
* @param {Number} [scale] Optional scale to apply
|
|
10
|
+
* @returns {void}
|
|
11
|
+
*/
|
|
12
|
+
export default function (
|
|
13
|
+
enabledElement: CPUFallbackEnabledElement,
|
|
14
|
+
context: CanvasRenderingContext2D,
|
|
15
|
+
scale?: number
|
|
16
|
+
): void {
|
|
17
|
+
if (enabledElement === undefined) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
'setToPixelCoordinateSystem: parameter enabledElement must not be undefined'
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (context === undefined) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
'setToPixelCoordinateSystem: parameter context must not be undefined'
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const transform = calculateTransform(enabledElement, scale);
|
|
29
|
+
const m = transform.getMatrix();
|
|
30
|
+
|
|
31
|
+
context.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
|
32
|
+
}
|
package/src/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import now from './now';
|
|
2
|
+
import { IImage } from '../../../../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Converts stored color pixel values to display pixel values using a LUT.
|
|
6
|
+
*
|
|
7
|
+
* Note: Skips alpha value for any input image pixel data.
|
|
8
|
+
*
|
|
9
|
+
* @param {Image} image A Cornerstone Image Object
|
|
10
|
+
* @param {Array} lut Lookup table array
|
|
11
|
+
* @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels
|
|
12
|
+
*
|
|
13
|
+
* @returns {void}
|
|
14
|
+
* @memberof Internal
|
|
15
|
+
*/
|
|
16
|
+
export default function (
|
|
17
|
+
image: IImage,
|
|
18
|
+
lut: Uint8ClampedArray,
|
|
19
|
+
canvasImageDataData: Uint8ClampedArray
|
|
20
|
+
): void {
|
|
21
|
+
let start = now();
|
|
22
|
+
const pixelData = image.getPixelData();
|
|
23
|
+
|
|
24
|
+
image.stats.lastGetPixelDataTime = now() - start;
|
|
25
|
+
|
|
26
|
+
const minPixelValue = image.minPixelValue;
|
|
27
|
+
let canvasImageDataIndex = 0;
|
|
28
|
+
let storedPixelDataIndex = 0;
|
|
29
|
+
const numPixels = pixelData.length;
|
|
30
|
+
|
|
31
|
+
// NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.
|
|
32
|
+
// We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement
|
|
33
|
+
start = now();
|
|
34
|
+
if (minPixelValue < 0) {
|
|
35
|
+
while (storedPixelDataIndex < numPixels) {
|
|
36
|
+
canvasImageDataData[canvasImageDataIndex++] =
|
|
37
|
+
lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Red
|
|
38
|
+
canvasImageDataData[canvasImageDataIndex++] =
|
|
39
|
+
lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Green
|
|
40
|
+
canvasImageDataData[canvasImageDataIndex] =
|
|
41
|
+
lut[pixelData[storedPixelDataIndex] + -minPixelValue]; // Blue
|
|
42
|
+
storedPixelDataIndex += 2;
|
|
43
|
+
canvasImageDataIndex += 2;
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
while (storedPixelDataIndex < numPixels) {
|
|
47
|
+
canvasImageDataData[canvasImageDataIndex++] =
|
|
48
|
+
lut[pixelData[storedPixelDataIndex++]]; // Red
|
|
49
|
+
canvasImageDataData[canvasImageDataIndex++] =
|
|
50
|
+
lut[pixelData[storedPixelDataIndex++]]; // Green
|
|
51
|
+
canvasImageDataData[canvasImageDataIndex] =
|
|
52
|
+
lut[pixelData[storedPixelDataIndex]]; // Blue
|
|
53
|
+
storedPixelDataIndex += 2;
|
|
54
|
+
canvasImageDataIndex += 2;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;
|
|
58
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import now from './now';
|
|
2
|
+
import { IImage } from '../../../../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This function transforms stored pixel values into a canvas image data buffer
|
|
6
|
+
* by using a LUT. This is the most performance sensitive code in cornerstone and
|
|
7
|
+
* we use a special trick to make this go as fast as possible. Specifically we
|
|
8
|
+
* use the alpha channel only to control the luminance rather than the red, green and
|
|
9
|
+
* blue channels which makes it over 3x faster. The canvasImageDataData buffer needs
|
|
10
|
+
* to be previously filled with white pixels.
|
|
11
|
+
*
|
|
12
|
+
* NOTE: Attribution would be appreciated if you use this technique!
|
|
13
|
+
*
|
|
14
|
+
* @param {Image} image A Cornerstone Image Object
|
|
15
|
+
* @param {Array} lut Lookup table array
|
|
16
|
+
* @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels
|
|
17
|
+
*
|
|
18
|
+
* @returns {void}
|
|
19
|
+
* @memberof Internal
|
|
20
|
+
*/
|
|
21
|
+
export default function (
|
|
22
|
+
image: IImage,
|
|
23
|
+
lut: Uint8ClampedArray,
|
|
24
|
+
canvasImageDataData: Uint8ClampedArray
|
|
25
|
+
): void {
|
|
26
|
+
let start = now();
|
|
27
|
+
const pixelData = image.getPixelData();
|
|
28
|
+
|
|
29
|
+
image.stats.lastGetPixelDataTime = now() - start;
|
|
30
|
+
|
|
31
|
+
const numPixels = pixelData.length;
|
|
32
|
+
const minPixelValue = image.minPixelValue;
|
|
33
|
+
let canvasImageDataIndex = 3;
|
|
34
|
+
let storedPixelDataIndex = 0;
|
|
35
|
+
|
|
36
|
+
// NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.
|
|
37
|
+
// We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement
|
|
38
|
+
|
|
39
|
+
// Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.
|
|
40
|
+
start = now();
|
|
41
|
+
if (pixelData instanceof Int16Array) {
|
|
42
|
+
if (minPixelValue < 0) {
|
|
43
|
+
while (storedPixelDataIndex < numPixels) {
|
|
44
|
+
canvasImageDataData[canvasImageDataIndex] =
|
|
45
|
+
lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha
|
|
46
|
+
canvasImageDataIndex += 4;
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
while (storedPixelDataIndex < numPixels) {
|
|
50
|
+
canvasImageDataData[canvasImageDataIndex] =
|
|
51
|
+
lut[pixelData[storedPixelDataIndex++]]; // Alpha
|
|
52
|
+
canvasImageDataIndex += 4;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} else if (pixelData instanceof Uint16Array) {
|
|
56
|
+
while (storedPixelDataIndex < numPixels) {
|
|
57
|
+
canvasImageDataData[canvasImageDataIndex] =
|
|
58
|
+
lut[pixelData[storedPixelDataIndex++]]; // Alpha
|
|
59
|
+
canvasImageDataIndex += 4;
|
|
60
|
+
}
|
|
61
|
+
} else if (minPixelValue < 0) {
|
|
62
|
+
while (storedPixelDataIndex < numPixels) {
|
|
63
|
+
canvasImageDataData[canvasImageDataIndex] =
|
|
64
|
+
lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha
|
|
65
|
+
canvasImageDataIndex += 4;
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
while (storedPixelDataIndex < numPixels) {
|
|
69
|
+
canvasImageDataData[canvasImageDataIndex] =
|
|
70
|
+
lut[pixelData[storedPixelDataIndex++]]; // Alpha
|
|
71
|
+
canvasImageDataIndex += 4;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;
|
|
76
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as colors from '../colors';
|
|
2
|
+
import now from './now';
|
|
3
|
+
import type { IImage, CPUFallbackLookupTable } from '../../../../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {Image} image A Cornerstone Image Object
|
|
8
|
+
* @param {LookupTable|Array} colorLUT Lookup table array
|
|
9
|
+
* @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels
|
|
10
|
+
*
|
|
11
|
+
* @returns {void}
|
|
12
|
+
* @memberof Internal
|
|
13
|
+
*/
|
|
14
|
+
function storedPixelDataToCanvasImageDataColorLUT(
|
|
15
|
+
image: IImage,
|
|
16
|
+
colorLUT: CPUFallbackLookupTable,
|
|
17
|
+
canvasImageDataData: Uint8ClampedArray
|
|
18
|
+
): void {
|
|
19
|
+
let start = now();
|
|
20
|
+
const pixelData = image.getPixelData();
|
|
21
|
+
|
|
22
|
+
image.stats.lastGetPixelDataTime = now() - start;
|
|
23
|
+
|
|
24
|
+
const numPixels = pixelData.length;
|
|
25
|
+
const minPixelValue = image.minPixelValue;
|
|
26
|
+
let canvasImageDataIndex = 0;
|
|
27
|
+
let storedPixelDataIndex = 0;
|
|
28
|
+
let rgba;
|
|
29
|
+
let clut;
|
|
30
|
+
|
|
31
|
+
start = now();
|
|
32
|
+
|
|
33
|
+
if (colorLUT instanceof colors.LookupTable) {
|
|
34
|
+
clut = colorLUT.Table;
|
|
35
|
+
} else {
|
|
36
|
+
clut = colorLUT;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (minPixelValue < 0) {
|
|
40
|
+
while (storedPixelDataIndex < numPixels) {
|
|
41
|
+
rgba = clut[pixelData[storedPixelDataIndex++] + -minPixelValue];
|
|
42
|
+
canvasImageDataData[canvasImageDataIndex++] = rgba[0];
|
|
43
|
+
canvasImageDataData[canvasImageDataIndex++] = rgba[1];
|
|
44
|
+
canvasImageDataData[canvasImageDataIndex++] = rgba[2];
|
|
45
|
+
canvasImageDataData[canvasImageDataIndex++] = rgba[3];
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
while (storedPixelDataIndex < numPixels) {
|
|
49
|
+
rgba = clut[pixelData[storedPixelDataIndex++]];
|
|
50
|
+
canvasImageDataData[canvasImageDataIndex++] = rgba[0];
|
|
51
|
+
canvasImageDataData[canvasImageDataIndex++] = rgba[1];
|
|
52
|
+
canvasImageDataData[canvasImageDataIndex++] = rgba[2];
|
|
53
|
+
canvasImageDataData[canvasImageDataIndex++] = rgba[3];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export default storedPixelDataToCanvasImageDataColorLUT;
|
package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import now from './now';
|
|
2
|
+
import { IImage } from '../../../../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This function transforms stored pixel values into a canvas image data buffer
|
|
6
|
+
* by using a LUT. This is the most performance sensitive code in cornerstone and
|
|
7
|
+
* we use a special trick to make this go as fast as possible. Specifically we
|
|
8
|
+
* use the alpha channel only to control the luminance rather than the red, green and
|
|
9
|
+
* blue channels which makes it over 3x faster. The canvasImageDataData buffer needs
|
|
10
|
+
* to be previously filled with white pixels.
|
|
11
|
+
*
|
|
12
|
+
* NOTE: Attribution would be appreciated if you use this technique!
|
|
13
|
+
*
|
|
14
|
+
* @param {Image} image A Cornerstone Image Object
|
|
15
|
+
* @param {Array} lut Lookup table array
|
|
16
|
+
* @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels
|
|
17
|
+
*
|
|
18
|
+
* @returns {void}
|
|
19
|
+
* @memberof Internal
|
|
20
|
+
*/
|
|
21
|
+
export default function (
|
|
22
|
+
image: IImage,
|
|
23
|
+
lutFunction: (value: number) => number,
|
|
24
|
+
canvasImageDataData: Uint8ClampedArray
|
|
25
|
+
): void {
|
|
26
|
+
let start = now();
|
|
27
|
+
const pixelData = image.getPixelData();
|
|
28
|
+
|
|
29
|
+
image.stats.lastGetPixelDataTime = now() - start;
|
|
30
|
+
|
|
31
|
+
const numPixels = pixelData.length;
|
|
32
|
+
// const minPixelValue = image.minPixelValue;
|
|
33
|
+
let canvasImageDataIndex = 3;
|
|
34
|
+
let storedPixelDataIndex = 0;
|
|
35
|
+
|
|
36
|
+
// NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.
|
|
37
|
+
// We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement
|
|
38
|
+
|
|
39
|
+
// Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.
|
|
40
|
+
start = now();
|
|
41
|
+
|
|
42
|
+
while (storedPixelDataIndex < numPixels) {
|
|
43
|
+
canvasImageDataData[canvasImageDataIndex] = lutFunction(
|
|
44
|
+
pixelData[storedPixelDataIndex++]
|
|
45
|
+
); // Alpha
|
|
46
|
+
canvasImageDataIndex += 4;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;
|
|
50
|
+
}
|