@cornerstonejs/tools 0.56.2 → 0.56.3

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.
Files changed (352) hide show
  1. package/package.json +5 -4
  2. package/src/constants/COLOR_LUT.ts +262 -0
  3. package/src/constants/index.ts +3 -0
  4. package/src/cursors/ImageMouseCursor.ts +39 -0
  5. package/src/cursors/MouseCursor.ts +114 -0
  6. package/src/cursors/SVGCursorDescriptor.ts +462 -0
  7. package/src/cursors/SVGMouseCursor.ts +145 -0
  8. package/src/cursors/elementCursor.ts +69 -0
  9. package/src/cursors/index.ts +24 -0
  10. package/src/cursors/setCursorForElement.ts +33 -0
  11. package/src/drawingSvg/_getHash.ts +9 -0
  12. package/src/drawingSvg/_setAttributesIfNecessary.ts +13 -0
  13. package/src/drawingSvg/_setNewAttributesIfValid.ts +10 -0
  14. package/src/drawingSvg/clearByToolType.ts +26 -0
  15. package/src/drawingSvg/draw.ts +16 -0
  16. package/src/drawingSvg/drawArrow.ts +82 -0
  17. package/src/drawingSvg/drawCircle.ts +62 -0
  18. package/src/drawingSvg/drawEllipse.ts +71 -0
  19. package/src/drawingSvg/drawHandles.ts +87 -0
  20. package/src/drawingSvg/drawLine.ts +70 -0
  21. package/src/drawingSvg/drawLink.ts +76 -0
  22. package/src/drawingSvg/drawLinkedTextBox.ts +64 -0
  23. package/src/drawingSvg/drawPolyline.ts +80 -0
  24. package/src/drawingSvg/drawRect.ts +70 -0
  25. package/src/drawingSvg/drawTextBox.ts +213 -0
  26. package/src/drawingSvg/getSvgDrawingHelper.ts +98 -0
  27. package/src/drawingSvg/index.ts +23 -0
  28. package/src/enums/AnnotationStyleStates.ts +22 -0
  29. package/src/enums/Events.ts +242 -0
  30. package/src/enums/SegmentationRepresentations.ts +12 -0
  31. package/src/enums/ToolBindings.ts +37 -0
  32. package/src/enums/ToolModes.ts +31 -0
  33. package/src/enums/Touch.ts +8 -0
  34. package/src/enums/index.js +16 -0
  35. package/src/eventDispatchers/annotationModifiedEventDispatcher.ts +41 -0
  36. package/src/eventDispatchers/cameraModifiedEventDispatcher.ts +41 -0
  37. package/src/eventDispatchers/imageRenderedEventDispatcher.ts +37 -0
  38. package/src/eventDispatchers/imageSpacingCalibratedEventDispatcher.ts +50 -0
  39. package/src/eventDispatchers/index.js +15 -0
  40. package/src/eventDispatchers/keyboardEventHandlers/index.js +4 -0
  41. package/src/eventDispatchers/keyboardEventHandlers/keyDown.ts +29 -0
  42. package/src/eventDispatchers/keyboardEventHandlers/keyUp.ts +33 -0
  43. package/src/eventDispatchers/keyboardToolEventDispatcher.ts +28 -0
  44. package/src/eventDispatchers/mouseEventHandlers/index.js +19 -0
  45. package/src/eventDispatchers/mouseEventHandlers/mouseClick.ts +13 -0
  46. package/src/eventDispatchers/mouseEventHandlers/mouseDoubleClick.ts +13 -0
  47. package/src/eventDispatchers/mouseEventHandlers/mouseDown.ts +196 -0
  48. package/src/eventDispatchers/mouseEventHandlers/mouseDownActivate.ts +35 -0
  49. package/src/eventDispatchers/mouseEventHandlers/mouseDrag.ts +25 -0
  50. package/src/eventDispatchers/mouseEventHandlers/mouseMove.ts +70 -0
  51. package/src/eventDispatchers/mouseEventHandlers/mouseUp.ts +9 -0
  52. package/src/eventDispatchers/mouseEventHandlers/mouseWheel.ts +13 -0
  53. package/src/eventDispatchers/mouseToolEventDispatcher.ts +64 -0
  54. package/src/eventDispatchers/shared/customCallbackHandler.ts +73 -0
  55. package/src/eventDispatchers/shared/getActiveToolForKeyboardEvent.ts +58 -0
  56. package/src/eventDispatchers/shared/getActiveToolForMouseEvent.ts +61 -0
  57. package/src/eventDispatchers/shared/getActiveToolForTouchEvent.ts +64 -0
  58. package/src/eventDispatchers/shared/getMouseModifier.ts +30 -0
  59. package/src/eventDispatchers/shared/getToolsWithModesForMouseEvent.ts +56 -0
  60. package/src/eventDispatchers/shared/getToolsWithModesForTouchEvent.ts +54 -0
  61. package/src/eventDispatchers/touchEventHandlers/index.js +15 -0
  62. package/src/eventDispatchers/touchEventHandlers/touchDrag.ts +23 -0
  63. package/src/eventDispatchers/touchEventHandlers/touchEnd.ts +9 -0
  64. package/src/eventDispatchers/touchEventHandlers/touchPress.ts +13 -0
  65. package/src/eventDispatchers/touchEventHandlers/touchStart.ts +174 -0
  66. package/src/eventDispatchers/touchEventHandlers/touchStartActivate.ts +36 -0
  67. package/src/eventDispatchers/touchEventHandlers/touchTap.ts +9 -0
  68. package/src/eventDispatchers/touchToolEventDispatcher.ts +51 -0
  69. package/src/eventListeners/annotations/annotationModifiedListener.ts +22 -0
  70. package/src/eventListeners/annotations/annotationSelectionListener.ts +29 -0
  71. package/src/eventListeners/annotations/index.ts +4 -0
  72. package/src/eventListeners/index.ts +28 -0
  73. package/src/eventListeners/keyboard/index.ts +16 -0
  74. package/src/eventListeners/keyboard/keyDownListener.ts +99 -0
  75. package/src/eventListeners/mouse/getMouseEventPoints.ts +66 -0
  76. package/src/eventListeners/mouse/index.ts +55 -0
  77. package/src/eventListeners/mouse/mouseDoubleClickListener.ts +55 -0
  78. package/src/eventListeners/mouse/mouseDownListener.ts +519 -0
  79. package/src/eventListeners/mouse/mouseMoveListener.ts +33 -0
  80. package/src/eventListeners/segmentation/index.ts +11 -0
  81. package/src/eventListeners/segmentation/segmentationDataModifiedEventListener.ts +61 -0
  82. package/src/eventListeners/segmentation/segmentationModifiedEventListener.ts +32 -0
  83. package/src/eventListeners/segmentation/segmentationRepresentationModifiedEventListener.ts +15 -0
  84. package/src/eventListeners/segmentation/segmentationRepresentationRemovedEventListener.ts +16 -0
  85. package/src/eventListeners/touch/getTouchEventPoints.ts +75 -0
  86. package/src/eventListeners/touch/index.ts +37 -0
  87. package/src/eventListeners/touch/preventGhostClick.js +72 -0
  88. package/src/eventListeners/touch/touchStartListener.ts +499 -0
  89. package/src/eventListeners/wheel/index.ts +27 -0
  90. package/src/eventListeners/wheel/normalizeWheel.ts +69 -0
  91. package/src/eventListeners/wheel/wheelListener.ts +51 -0
  92. package/src/index.ts +133 -0
  93. package/src/init.ts +187 -0
  94. package/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts +399 -0
  95. package/src/stateManagement/annotation/annotationLocking.ts +178 -0
  96. package/src/stateManagement/annotation/annotationSelection.ts +163 -0
  97. package/src/stateManagement/annotation/annotationState.ts +180 -0
  98. package/src/stateManagement/annotation/annotationVisibility.ts +156 -0
  99. package/src/stateManagement/annotation/config/ToolStyle.ts +265 -0
  100. package/src/stateManagement/annotation/config/getFont.ts +36 -0
  101. package/src/stateManagement/annotation/config/getState.ts +26 -0
  102. package/src/stateManagement/annotation/config/helpers.ts +55 -0
  103. package/src/stateManagement/annotation/config/index.ts +5 -0
  104. package/src/stateManagement/annotation/helpers/state.ts +83 -0
  105. package/src/stateManagement/annotation/index.ts +15 -0
  106. package/src/stateManagement/index.js +40 -0
  107. package/src/stateManagement/segmentation/SegmentationStateManager.ts +491 -0
  108. package/src/stateManagement/segmentation/activeSegmentation.ts +60 -0
  109. package/src/stateManagement/segmentation/addSegmentationRepresentations.ts +77 -0
  110. package/src/stateManagement/segmentation/addSegmentations.ts +27 -0
  111. package/src/stateManagement/segmentation/config/index.ts +29 -0
  112. package/src/stateManagement/segmentation/config/segmentationColor.ts +132 -0
  113. package/src/stateManagement/segmentation/config/segmentationConfig.ts +195 -0
  114. package/src/stateManagement/segmentation/config/segmentationVisibility.ts +171 -0
  115. package/src/stateManagement/segmentation/helpers/index.ts +3 -0
  116. package/src/stateManagement/segmentation/helpers/normalizeSegmentationInput.ts +35 -0
  117. package/src/stateManagement/segmentation/helpers/validateSegmentationInput.ts +41 -0
  118. package/src/stateManagement/segmentation/index.ts +22 -0
  119. package/src/stateManagement/segmentation/removeSegmentationsFromToolGroup.ts +85 -0
  120. package/src/stateManagement/segmentation/segmentIndex.ts +38 -0
  121. package/src/stateManagement/segmentation/segmentLocking.ts +72 -0
  122. package/src/stateManagement/segmentation/segmentationState.ts +429 -0
  123. package/src/stateManagement/segmentation/triggerSegmentationEvents.ts +157 -0
  124. package/src/store/SynchronizerManager/Synchronizer.ts +344 -0
  125. package/src/store/SynchronizerManager/createSynchronizer.ts +41 -0
  126. package/src/store/SynchronizerManager/destroy.ts +14 -0
  127. package/src/store/SynchronizerManager/destroySynchronizer.ts +25 -0
  128. package/src/store/SynchronizerManager/getAllSynchronizers.ts +12 -0
  129. package/src/store/SynchronizerManager/getSynchronizer.ts +13 -0
  130. package/src/store/SynchronizerManager/getSynchronizersForViewport.ts +44 -0
  131. package/src/store/SynchronizerManager/index.js +15 -0
  132. package/src/store/ToolGroupManager/ToolGroup.ts +679 -0
  133. package/src/store/ToolGroupManager/createToolGroup.ts +33 -0
  134. package/src/store/ToolGroupManager/destroy.ts +24 -0
  135. package/src/store/ToolGroupManager/destroyToolGroup.ts +26 -0
  136. package/src/store/ToolGroupManager/getAllToolGroups.ts +12 -0
  137. package/src/store/ToolGroupManager/getToolGroup.ts +14 -0
  138. package/src/store/ToolGroupManager/getToolGroupForViewport.ts +44 -0
  139. package/src/store/ToolGroupManager/getToolGroupsWithToolName.ts +33 -0
  140. package/src/store/ToolGroupManager/index.ts +17 -0
  141. package/src/store/addEnabledElement.ts +137 -0
  142. package/src/store/addTool.ts +56 -0
  143. package/src/store/cancelActiveManipulations.ts +30 -0
  144. package/src/store/filterMoveableAnnotationTools.ts +61 -0
  145. package/src/store/filterToolsWithAnnotationsForElement.ts +51 -0
  146. package/src/store/filterToolsWithMoveableHandles.ts +51 -0
  147. package/src/store/index.ts +29 -0
  148. package/src/store/removeEnabledElement.ts +132 -0
  149. package/src/store/state.ts +57 -0
  150. package/src/store/svgNodeCache.ts +7 -0
  151. package/src/synchronizers/callbacks/areViewportsCoplanar .ts +12 -0
  152. package/src/synchronizers/callbacks/cameraSyncCallback.ts +33 -0
  153. package/src/synchronizers/callbacks/stackImageSyncCallback.ts +157 -0
  154. package/src/synchronizers/callbacks/voiSyncCallback.ts +51 -0
  155. package/src/synchronizers/callbacks/zoomPanSyncCallback.ts +43 -0
  156. package/src/synchronizers/index.ts +11 -0
  157. package/src/synchronizers/synchronizers/createCameraPositionSynchronizer.ts +25 -0
  158. package/src/synchronizers/synchronizers/createStackImageSynchronizer.ts +25 -0
  159. package/src/synchronizers/synchronizers/createVOISynchronizer.ts +24 -0
  160. package/src/synchronizers/synchronizers/createZoomPanSynchronizer.ts +25 -0
  161. package/src/synchronizers/synchronizers/index.ts +11 -0
  162. package/src/tools/CrosshairsTool.ts +2693 -0
  163. package/src/tools/MIPJumpToClickTool.ts +99 -0
  164. package/src/tools/MagnifyTool.ts +319 -0
  165. package/src/tools/PanTool.ts +58 -0
  166. package/src/tools/PlanarRotateTool.ts +77 -0
  167. package/src/tools/ReferenceCursors.ts +466 -0
  168. package/src/tools/ReferenceLinesTool.ts +279 -0
  169. package/src/tools/ScaleOverlayTool.ts +685 -0
  170. package/src/tools/StackScrollTool.ts +97 -0
  171. package/src/tools/StackScrollToolMouseWheelTool.ts +58 -0
  172. package/src/tools/TrackballRotateTool.ts +141 -0
  173. package/src/tools/VolumeRotateMouseWheelTool.ts +86 -0
  174. package/src/tools/WindowLevelTool.ts +260 -0
  175. package/src/tools/ZoomTool.ts +293 -0
  176. package/src/tools/annotation/AngleTool.ts +835 -0
  177. package/src/tools/annotation/ArrowAnnotateTool.ts +820 -0
  178. package/src/tools/annotation/BidirectionalTool.ts +1350 -0
  179. package/src/tools/annotation/CircleROITool.ts +1070 -0
  180. package/src/tools/annotation/CobbAngleTool.ts +815 -0
  181. package/src/tools/annotation/DragProbeTool.ts +213 -0
  182. package/src/tools/annotation/EllipticalROITool.ts +1223 -0
  183. package/src/tools/annotation/LengthTool.ts +861 -0
  184. package/src/tools/annotation/PlanarFreehandROITool.ts +636 -0
  185. package/src/tools/annotation/ProbeTool.ts +681 -0
  186. package/src/tools/annotation/RectangleROITool.ts +1028 -0
  187. package/src/tools/annotation/planarFreehandROITool/closedContourEditLoop.ts +488 -0
  188. package/src/tools/annotation/planarFreehandROITool/drawLoop.ts +462 -0
  189. package/src/tools/annotation/planarFreehandROITool/editLoopCommon.ts +331 -0
  190. package/src/tools/annotation/planarFreehandROITool/findOpenUShapedContourVectorToPeak.ts +74 -0
  191. package/src/tools/annotation/planarFreehandROITool/openContourEditLoop.ts +612 -0
  192. package/src/tools/annotation/planarFreehandROITool/openContourEndEditLoop.ts +74 -0
  193. package/src/tools/annotation/planarFreehandROITool/renderMethods.ts +407 -0
  194. package/src/tools/base/AnnotationDisplayTool.ts +228 -0
  195. package/src/tools/base/AnnotationTool.ts +307 -0
  196. package/src/tools/base/BaseTool.ts +215 -0
  197. package/src/tools/base/index.ts +4 -0
  198. package/src/tools/displayTools/Contour/addContourToElement.ts +135 -0
  199. package/src/tools/displayTools/Contour/contourDisplay.ts +252 -0
  200. package/src/tools/displayTools/Contour/index.ts +3 -0
  201. package/src/tools/displayTools/Contour/removeContourFromElement.ts +35 -0
  202. package/src/tools/displayTools/Labelmap/addLabelmapToElement.ts +57 -0
  203. package/src/tools/displayTools/Labelmap/index.ts +4 -0
  204. package/src/tools/displayTools/Labelmap/labelmapConfig.ts +37 -0
  205. package/src/tools/displayTools/Labelmap/labelmapDisplay.ts +461 -0
  206. package/src/tools/displayTools/Labelmap/removeLabelmapFromElement.ts +27 -0
  207. package/src/tools/displayTools/Labelmap/validateRepresentationData.ts +30 -0
  208. package/src/tools/displayTools/SegmentationDisplayTool.ts +198 -0
  209. package/src/tools/index.ts +84 -0
  210. package/src/tools/segmentation/BrushTool.ts +474 -0
  211. package/src/tools/segmentation/CircleScissorsTool.ts +365 -0
  212. package/src/tools/segmentation/PaintFillTool.ts +370 -0
  213. package/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts +471 -0
  214. package/src/tools/segmentation/RectangleROIThresholdTool.ts +281 -0
  215. package/src/tools/segmentation/RectangleScissorsTool.ts +382 -0
  216. package/src/tools/segmentation/SphereScissorsTool.ts +368 -0
  217. package/src/tools/segmentation/strategies/eraseCircle.ts +30 -0
  218. package/src/tools/segmentation/strategies/eraseRectangle.ts +81 -0
  219. package/src/tools/segmentation/strategies/eraseSphere.ts +27 -0
  220. package/src/tools/segmentation/strategies/fillCircle.ts +185 -0
  221. package/src/tools/segmentation/strategies/fillRectangle.ts +110 -0
  222. package/src/tools/segmentation/strategies/fillSphere.ts +88 -0
  223. package/src/tools/segmentation/strategies/index.ts +9 -0
  224. package/src/types/AnnotationGroupSelector.ts +7 -0
  225. package/src/types/AnnotationStyle.ts +42 -0
  226. package/src/types/AnnotationTypes.ts +109 -0
  227. package/src/types/BoundsIJK.ts +5 -0
  228. package/src/types/CINETypes.ts +32 -0
  229. package/src/types/ContourTypes.ts +26 -0
  230. package/src/types/CursorTypes.ts +12 -0
  231. package/src/types/EventTypes.ts +657 -0
  232. package/src/types/FloodFillTypes.ts +19 -0
  233. package/src/types/IAnnotationManager.ts +89 -0
  234. package/src/types/IDistance.ts +16 -0
  235. package/src/types/IPoints.ts +18 -0
  236. package/src/types/ISetToolModeOptions.ts +29 -0
  237. package/src/types/ISynchronizerEventHandler.ts +11 -0
  238. package/src/types/IToolClassReference.ts +5 -0
  239. package/src/types/IToolGroup.ts +72 -0
  240. package/src/types/ITouchPoints.ts +14 -0
  241. package/src/types/InteractionTypes.ts +6 -0
  242. package/src/types/InternalToolTypes.ts +19 -0
  243. package/src/types/JumpToSliceOptions.ts +7 -0
  244. package/src/types/LabelmapTypes.ts +41 -0
  245. package/src/types/PlanarBoundingBox.ts +8 -0
  246. package/src/types/SVGDrawingHelper.ts +10 -0
  247. package/src/types/ScrollOptions.ts +9 -0
  248. package/src/types/SegmentationStateTypes.ts +248 -0
  249. package/src/types/ToolHandle.ts +26 -0
  250. package/src/types/ToolProps.ts +16 -0
  251. package/src/types/ToolSpecificAnnotationTypes.ts +311 -0
  252. package/src/types/index.ts +115 -0
  253. package/src/utilities/boundingBox/extend2DBoundingBoxInViewAxis.ts +29 -0
  254. package/src/utilities/boundingBox/getBoundingBoxAroundShape.ts +57 -0
  255. package/src/utilities/boundingBox/index.ts +4 -0
  256. package/src/utilities/calibrateImageSpacing.ts +46 -0
  257. package/src/utilities/cine/events.ts +9 -0
  258. package/src/utilities/cine/index.ts +5 -0
  259. package/src/utilities/cine/playClip.ts +435 -0
  260. package/src/utilities/cine/state.ts +18 -0
  261. package/src/utilities/clip.js +30 -0
  262. package/src/utilities/debounce.js +217 -0
  263. package/src/utilities/drawing/getTextBoxCoordsCanvas.ts +45 -0
  264. package/src/utilities/drawing/index.ts +3 -0
  265. package/src/utilities/dynamicVolume/getDataInTime.ts +110 -0
  266. package/src/utilities/dynamicVolume/index.ts +2 -0
  267. package/src/utilities/getAnnotationNearPoint.ts +130 -0
  268. package/src/utilities/getModalityUnit.ts +11 -0
  269. package/src/utilities/getToolsWithModesForElement.ts +52 -0
  270. package/src/utilities/index.ts +68 -0
  271. package/src/utilities/isObject.js +29 -0
  272. package/src/utilities/math/angle/angleBetweenLines.ts +29 -0
  273. package/src/utilities/math/circle/_types.ts +6 -0
  274. package/src/utilities/math/circle/getCanvasCircleCorners.ts +23 -0
  275. package/src/utilities/math/circle/getCanvasCircleRadius.ts +16 -0
  276. package/src/utilities/math/circle/index.ts +4 -0
  277. package/src/utilities/math/ellipse/getCanvasEllipseCorners.ts +26 -0
  278. package/src/utilities/math/ellipse/index.ts +4 -0
  279. package/src/utilities/math/ellipse/pointInEllipse.ts +38 -0
  280. package/src/utilities/math/ellipse/pointInEllipsoidWithConstraint.ts +35 -0
  281. package/src/utilities/math/index.ts +8 -0
  282. package/src/utilities/math/line/distanceToPoint.ts +24 -0
  283. package/src/utilities/math/line/distanceToPointSquared.ts +44 -0
  284. package/src/utilities/math/line/index.ts +5 -0
  285. package/src/utilities/math/line/intersectLine.ts +92 -0
  286. package/src/utilities/math/midPoint.ts +24 -0
  287. package/src/utilities/math/point/distanceToPoint.ts +22 -0
  288. package/src/utilities/math/point/index.ts +3 -0
  289. package/src/utilities/math/polyline/addCanvasPointsToArray.ts +62 -0
  290. package/src/utilities/math/polyline/calculateAreaOfPoints.ts +23 -0
  291. package/src/utilities/math/polyline/getIntersectionWithPolyline.ts +182 -0
  292. package/src/utilities/math/polyline/getSubPixelSpacingAndXYDirections.ts +99 -0
  293. package/src/utilities/math/polyline/index.ts +19 -0
  294. package/src/utilities/math/polyline/planarFreehandROIInternalTypes.ts +36 -0
  295. package/src/utilities/math/polyline/pointCanProjectOnLine.ts +57 -0
  296. package/src/utilities/math/polyline/pointsAreWithinCloseContourProximity.ts +15 -0
  297. package/src/utilities/math/rectangle/distanceToPoint.ts +82 -0
  298. package/src/utilities/math/rectangle/index.ts +3 -0
  299. package/src/utilities/math/sphere/index.ts +3 -0
  300. package/src/utilities/math/sphere/pointInSphere.ts +31 -0
  301. package/src/utilities/math/vec2/findClosestPoint.ts +40 -0
  302. package/src/utilities/math/vec2/index.ts +4 -0
  303. package/src/utilities/math/vec2/liangBarksyClip.ts +84 -0
  304. package/src/utilities/orientation/getOrientationStringLPS.ts +52 -0
  305. package/src/utilities/orientation/index.ts +4 -0
  306. package/src/utilities/orientation/invertOrientationStringLPS.ts +21 -0
  307. package/src/utilities/planar/filterAnnotationsForDisplay.ts +68 -0
  308. package/src/utilities/planar/filterAnnotationsWithinSlice.ts +85 -0
  309. package/src/utilities/planar/getPointInLineOfSightWithCriteria.ts +104 -0
  310. package/src/utilities/planar/getWorldWidthAndHeightFromCorners.ts +51 -0
  311. package/src/utilities/planar/getWorldWidthAndHeightFromTwoPoints.ts +51 -0
  312. package/src/utilities/planar/index.ts +18 -0
  313. package/src/utilities/planarFreehandROITool/index.ts +7 -0
  314. package/src/utilities/planarFreehandROITool/interpolateAnnotation.ts +87 -0
  315. package/src/utilities/planarFreehandROITool/interpolatePoints.ts +214 -0
  316. package/src/utilities/planarFreehandROITool/interpolation/algorithms/bspline.ts +55 -0
  317. package/src/utilities/planarFreehandROITool/interpolation/interpolateSegmentPoints.ts +90 -0
  318. package/src/utilities/pointInShapeCallback.ts +138 -0
  319. package/src/utilities/pointInSurroundingSphereCallback.ts +188 -0
  320. package/src/utilities/rectangleROITool/getBoundsIJKFromRectangleAnnotations.ts +76 -0
  321. package/src/utilities/rectangleROITool/index.ts +3 -0
  322. package/src/utilities/scroll.ts +62 -0
  323. package/src/utilities/segmentation/brushSizeForToolGroup.ts +72 -0
  324. package/src/utilities/segmentation/brushThresholdForToolGroup.ts +65 -0
  325. package/src/utilities/segmentation/createLabelmapVolumeForViewport.ts +74 -0
  326. package/src/utilities/segmentation/createMergedLabelmapForIndex.ts +65 -0
  327. package/src/utilities/segmentation/floodFill.ts +194 -0
  328. package/src/utilities/segmentation/getDefaultRepresentationConfig.ts +20 -0
  329. package/src/utilities/segmentation/index.ts +33 -0
  330. package/src/utilities/segmentation/isValidRepresentationConfig.ts +22 -0
  331. package/src/utilities/segmentation/rectangleROIThresholdVolumeByRange.ts +91 -0
  332. package/src/utilities/segmentation/thresholdSegmentationByRange.ts +129 -0
  333. package/src/utilities/segmentation/thresholdVolumeByRange.ts +150 -0
  334. package/src/utilities/segmentation/triggerSegmentationRender.ts +206 -0
  335. package/src/utilities/segmentation/utilities.ts +116 -0
  336. package/src/utilities/stackPrefetch/index.ts +8 -0
  337. package/src/utilities/stackPrefetch/stackPrefetch.ts +405 -0
  338. package/src/utilities/stackPrefetch/state.ts +17 -0
  339. package/src/utilities/throttle.js +69 -0
  340. package/src/utilities/touch/index.ts +246 -0
  341. package/src/utilities/triggerAnnotationRender.ts +237 -0
  342. package/src/utilities/triggerAnnotationRenderForViewportIds.ts +18 -0
  343. package/src/utilities/viewport/index.ts +5 -0
  344. package/src/utilities/viewport/isViewportPreScaled.ts +24 -0
  345. package/src/utilities/viewport/jumpToSlice.ts +73 -0
  346. package/src/utilities/viewport/jumpToWorld.ts +58 -0
  347. package/src/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.ts +28 -0
  348. package/src/utilities/viewportFilters/filterViewportsWithParallelNormals.ts +26 -0
  349. package/src/utilities/viewportFilters/filterViewportsWithSameOrientation.ts +15 -0
  350. package/src/utilities/viewportFilters/filterViewportsWithToolEnabled.ts +72 -0
  351. package/src/utilities/viewportFilters/getViewportIdsWithToolToRender.ts +45 -0
  352. package/src/utilities/viewportFilters/index.ts +11 -0
@@ -0,0 +1,97 @@
1
+ import {
2
+ getEnabledElementByIds,
3
+ VolumeViewport,
4
+ StackViewport,
5
+ utilities as csUtils,
6
+ } from '@cornerstonejs/core';
7
+ import { BaseTool } from './base';
8
+ import { scroll } from '../utilities';
9
+ import { PublicToolProps, ToolProps, EventTypes } from '../types';
10
+
11
+ /**
12
+ * The StackScrollTool is a tool that allows the user to scroll through a
13
+ * stack of images by pressing the mouse click and dragging
14
+ */
15
+ class StackScrollTool extends BaseTool {
16
+ static toolName;
17
+ deltaY: number;
18
+ constructor(
19
+ toolProps: PublicToolProps = {},
20
+ defaultToolProps: ToolProps = {
21
+ supportedInteractionTypes: ['Mouse', 'Touch'],
22
+ configuration: {
23
+ invert: false,
24
+ debounceIfNotLoaded: true,
25
+ loop: false
26
+ },
27
+ }
28
+ ) {
29
+ super(toolProps, defaultToolProps);
30
+ this.deltaY = 1;
31
+ }
32
+
33
+ mouseDragCallback(evt: EventTypes.InteractionEventType) {
34
+ this._dragCallback(evt);
35
+ }
36
+ touchDragCallback(evt: EventTypes.InteractionEventType) {
37
+ this._dragCallback(evt);
38
+ }
39
+
40
+ _dragCallback(evt: EventTypes.InteractionEventType) {
41
+ const { deltaPoints, viewportId, renderingEngineId } = evt.detail;
42
+ const { viewport } = getEnabledElementByIds(viewportId, renderingEngineId);
43
+
44
+ const targetId = this.getTargetId(viewport);
45
+ const { debounceIfNotLoaded, invert, loop } = this.configuration;
46
+
47
+ const deltaPointY = deltaPoints.canvas[1];
48
+
49
+ let volumeId;
50
+ if (viewport instanceof VolumeViewport) {
51
+ volumeId = targetId.split('volumeId:')[1];
52
+ }
53
+
54
+ const pixelsPerImage = this._getPixelPerImage(viewport);
55
+ const deltaY = deltaPointY + this.deltaY;
56
+
57
+ if (!pixelsPerImage) {
58
+ return;
59
+ }
60
+
61
+ if (Math.abs(deltaY) >= pixelsPerImage) {
62
+ const imageIdIndexOffset = Math.round(deltaY / pixelsPerImage);
63
+
64
+ scroll(viewport, {
65
+ delta: invert ? -imageIdIndexOffset : imageIdIndexOffset,
66
+ volumeId,
67
+ debounceLoading: debounceIfNotLoaded,
68
+ loop: loop
69
+ });
70
+
71
+ this.deltaY = deltaY % pixelsPerImage;
72
+ } else {
73
+ this.deltaY = deltaY;
74
+ }
75
+ }
76
+
77
+ _getPixelPerImage(viewport) {
78
+ const { element } = viewport;
79
+ const numberOfSlices = this._getNumberOfSlices(viewport);
80
+
81
+ // The Math.max here makes it easier to mouseDrag-scroll small or really large image stacks
82
+ return Math.max(2, element.offsetHeight / Math.max(numberOfSlices, 8));
83
+ }
84
+
85
+ _getNumberOfSlices(viewport) {
86
+ if (viewport instanceof VolumeViewport) {
87
+ const { numberOfSlices } =
88
+ csUtils.getImageSliceDataForVolumeViewport(viewport);
89
+ return numberOfSlices;
90
+ } else if (viewport instanceof StackViewport) {
91
+ return viewport.getImageIds().length;
92
+ }
93
+ }
94
+ }
95
+
96
+ StackScrollTool.toolName = 'StackScroll';
97
+ export default StackScrollTool;
@@ -0,0 +1,58 @@
1
+ import {
2
+ getEnabledElement,
3
+ VolumeViewport,
4
+ StackViewport,
5
+ } from '@cornerstonejs/core';
6
+ import { BaseTool } from './base';
7
+ import { MouseWheelEventType } from '../types/EventTypes';
8
+ import { scrollVolume } from '../utilities/scroll';
9
+
10
+ /**
11
+ * The StackScrollMouseWheelTool is a tool that allows the user to scroll through a
12
+ * stack of images using the mouse wheel
13
+ */
14
+ class StackScrollMouseWheelTool extends BaseTool {
15
+ static toolName;
16
+
17
+ _configuration: any;
18
+
19
+ constructor(
20
+ toolProps = {},
21
+ defaultToolProps = {
22
+ supportedInteractionTypes: ['Mouse', 'Touch'],
23
+ configuration: {
24
+ invert: false,
25
+ debounceIfNotLoaded: true,
26
+ loop: false,
27
+ },
28
+ }
29
+ ) {
30
+ super(toolProps, defaultToolProps);
31
+ }
32
+
33
+ mouseWheelCallback(evt: MouseWheelEventType): void {
34
+ const { wheel, element } = evt.detail;
35
+ const { direction } = wheel;
36
+ const { invert } = this.configuration;
37
+ const { viewport } = getEnabledElement(element);
38
+ const delta = direction * (invert ? -1 : 1);
39
+
40
+ if (viewport instanceof StackViewport) {
41
+ viewport.scroll(
42
+ delta,
43
+ this.configuration.debounceIfNotLoaded,
44
+ this.configuration.loop
45
+ );
46
+ } else if (viewport instanceof VolumeViewport) {
47
+ const targetId = this.getTargetId(viewport);
48
+ const volumeId = targetId.split('volumeId:')[1];
49
+ // TODO: add loop implemention for scroll volume.
50
+ scrollVolume(viewport, volumeId, delta);
51
+ } else {
52
+ throw new Error('StackScrollMouseWheelTool: Unsupported viewport type');
53
+ }
54
+ }
55
+ }
56
+
57
+ StackScrollMouseWheelTool.toolName = 'StackScrollMouseWheel';
58
+ export default StackScrollMouseWheelTool;
@@ -0,0 +1,141 @@
1
+ import vtkMath from '@kitware/vtk.js/Common/Core/Math';
2
+
3
+ import { getEnabledElement } from '@cornerstonejs/core';
4
+ import type { Types } from '@cornerstonejs/core';
5
+ import { mat4, vec3 } from 'gl-matrix';
6
+ import { EventTypes, PublicToolProps, ToolProps } from '../types';
7
+ import { BaseTool } from './base';
8
+
9
+ /**
10
+ * Tool that rotates the camera in the plane defined by the viewPlaneNormal and the viewUp.
11
+ */
12
+ class TrackballRotateTool extends BaseTool {
13
+ static toolName;
14
+ touchDragCallback: (evt: EventTypes.InteractionEventType) => void;
15
+ mouseDragCallback: (evt: EventTypes.InteractionEventType) => void;
16
+
17
+ constructor(
18
+ toolProps: PublicToolProps = {},
19
+ defaultToolProps: ToolProps = {
20
+ supportedInteractionTypes: ['Mouse', 'Touch'],
21
+ configuration: {
22
+ rotateIncrementDegrees: 2,
23
+ },
24
+ }
25
+ ) {
26
+ super(toolProps, defaultToolProps);
27
+
28
+ this.touchDragCallback = this._dragCallback.bind(this);
29
+ this.mouseDragCallback = this._dragCallback.bind(this);
30
+ }
31
+
32
+ rotateCamera = (viewport, centerWorld, axis, angle) => {
33
+ const vtkCamera = viewport.getVtkActiveCamera();
34
+ const viewUp = vtkCamera.getViewUp();
35
+ const focalPoint = vtkCamera.getFocalPoint();
36
+ const position = vtkCamera.getPosition();
37
+
38
+ const newPosition: Types.Point3 = [0, 0, 0];
39
+ const newFocalPoint: Types.Point3 = [0, 0, 0];
40
+ const newViewUp: Types.Point3 = [0, 0, 0];
41
+
42
+ const transform = mat4.identity(new Float32Array(16));
43
+ mat4.translate(transform, transform, centerWorld);
44
+ mat4.rotate(transform, transform, angle, axis);
45
+ mat4.translate(transform, transform, [
46
+ -centerWorld[0],
47
+ -centerWorld[1],
48
+ -centerWorld[2],
49
+ ]);
50
+ vec3.transformMat4(newPosition, position, transform);
51
+ vec3.transformMat4(newFocalPoint, focalPoint, transform);
52
+
53
+ mat4.identity(transform);
54
+ mat4.rotate(transform, transform, angle, axis);
55
+ vec3.transformMat4(newViewUp, viewUp, transform);
56
+
57
+ viewport.setCamera({
58
+ position: newPosition,
59
+ viewUp: newViewUp,
60
+ focalPoint: newFocalPoint,
61
+ });
62
+ };
63
+
64
+ // pseudocode inspired from
65
+ // https://github.com/kitware/vtk-js/blob/HEAD/Sources/Interaction/Manipulators/MouseCameraUnicamRotateManipulator/index.js
66
+ _dragCallback(evt: EventTypes.InteractionEventType): void {
67
+ const { element, currentPoints, lastPoints } = evt.detail;
68
+ const currentPointsCanvas = currentPoints.canvas;
69
+ const lastPointsCanvas = lastPoints.canvas;
70
+ const { rotateIncrementDegrees } = this.configuration;
71
+ const enabledElement = getEnabledElement(element);
72
+ const { viewport } = enabledElement;
73
+ const camera = viewport.getCamera();
74
+ const width = element.clientWidth;
75
+ const height = element.clientHeight;
76
+
77
+ const normalizedPosition = [
78
+ currentPointsCanvas[0] / width,
79
+ currentPointsCanvas[1] / height,
80
+ ];
81
+
82
+ const normalizedPreviousPosition = [
83
+ lastPointsCanvas[0] / width,
84
+ lastPointsCanvas[1] / height,
85
+ ];
86
+
87
+ const center: Types.Point2 = [width * 0.5, height * 0.5];
88
+ // NOTE: centerWorld corresponds to the focal point in cornerstone3D
89
+ const centerWorld = viewport.canvasToWorld(center);
90
+ const normalizedCenter = [0.5, 0.5];
91
+
92
+ const radsq = (1.0 + Math.abs(normalizedCenter[0])) ** 2.0;
93
+ const op = [normalizedPreviousPosition[0], 0, 0];
94
+ const oe = [normalizedPosition[0], 0, 0];
95
+
96
+ const opsq = op[0] ** 2;
97
+ const oesq = oe[0] ** 2;
98
+
99
+ const lop = opsq > radsq ? 0 : Math.sqrt(radsq - opsq);
100
+ const loe = oesq > radsq ? 0 : Math.sqrt(radsq - oesq);
101
+
102
+ const nop: Types.Point3 = [op[0], 0, lop];
103
+ vtkMath.normalize(nop);
104
+ const noe: Types.Point3 = [oe[0], 0, loe];
105
+ vtkMath.normalize(noe);
106
+
107
+ const dot = vtkMath.dot(nop, noe);
108
+ if (Math.abs(dot) > 0.0001) {
109
+ const angleX =
110
+ -2 *
111
+ Math.acos(vtkMath.clampValue(dot, -1.0, 1.0)) *
112
+ Math.sign(normalizedPosition[0] - normalizedPreviousPosition[0]) *
113
+ rotateIncrementDegrees;
114
+
115
+ const upVec = camera.viewUp;
116
+ const atV = camera.viewPlaneNormal;
117
+ const rightV: Types.Point3 = [0, 0, 0];
118
+ const forwardV: Types.Point3 = [0, 0, 0];
119
+
120
+ vtkMath.cross(upVec, atV, rightV);
121
+ vtkMath.normalize(rightV);
122
+
123
+ vtkMath.cross(atV, rightV, forwardV);
124
+ vtkMath.normalize(forwardV);
125
+ vtkMath.normalize(upVec);
126
+
127
+ this.rotateCamera(viewport, centerWorld, forwardV, angleX);
128
+
129
+ const angleY =
130
+ (normalizedPreviousPosition[1] - normalizedPosition[1]) *
131
+ rotateIncrementDegrees;
132
+
133
+ this.rotateCamera(viewport, centerWorld, rightV, angleY);
134
+
135
+ viewport.render();
136
+ }
137
+ }
138
+ }
139
+
140
+ TrackballRotateTool.toolName = 'TrackballRotate';
141
+ export default TrackballRotateTool;
@@ -0,0 +1,86 @@
1
+ import { BaseTool } from './base';
2
+ import { getEnabledElement } from '@cornerstonejs/core';
3
+ import type { Types } from '@cornerstonejs/core';
4
+
5
+ import { mat4, vec3 } from 'gl-matrix';
6
+ import { PublicToolProps, ToolProps } from '../types';
7
+ import { MouseWheelEventType } from '../types/EventTypes';
8
+
9
+ const DIRECTIONS = {
10
+ X: [1, 0, 0],
11
+ Y: [0, 1, 0],
12
+ Z: [0, 0, 1],
13
+ CUSTOM: [],
14
+ };
15
+
16
+ /**
17
+ * Tool that rotates the camera on mouse wheel.
18
+ * It rotates the camera around the focal point, and around a defined axis. Default
19
+ * axis is set to be Z axis, but it can be configured to any custom normalized axis.
20
+ *
21
+ */
22
+ class VolumeRotateMouseWheelTool extends BaseTool {
23
+ static toolName;
24
+ _configuration: any;
25
+
26
+ constructor(
27
+ toolProps: PublicToolProps = {},
28
+ defaultToolProps: ToolProps = {
29
+ supportedInteractionTypes: ['Mouse', 'Touch'],
30
+ configuration: {
31
+ direction: DIRECTIONS.Z,
32
+ rotateIncrementDegrees: 0.5,
33
+ },
34
+ }
35
+ ) {
36
+ super(toolProps, defaultToolProps);
37
+ }
38
+
39
+ mouseWheelCallback(evt: MouseWheelEventType) {
40
+ // https://github.com/kitware/vtk-js/blob/HEAD/Sources/Interaction/Manipulators/MouseCameraUnicamRotateManipulator/index.js#L73
41
+ const { element, wheel } = evt.detail;
42
+ const enabledElement = getEnabledElement(element);
43
+ const { viewport } = enabledElement;
44
+ const { direction, rotateIncrementDegrees } = this.configuration;
45
+
46
+ const camera = viewport.getCamera();
47
+ const { viewUp, position, focalPoint } = camera;
48
+
49
+ const { direction: deltaY } = wheel;
50
+
51
+ const [cx, cy, cz] = focalPoint;
52
+ const [ax, ay, az] = direction;
53
+
54
+ const angle = deltaY * rotateIncrementDegrees;
55
+
56
+ // position[3] = 1.0
57
+ // focalPoint[3] = 1.0
58
+ // viewUp[3] = 0.0
59
+
60
+ const newPosition: Types.Point3 = [0, 0, 0];
61
+ const newFocalPoint: Types.Point3 = [0, 0, 0];
62
+ const newViewUp: Types.Point3 = [0, 0, 0];
63
+
64
+ const transform = mat4.identity(new Float32Array(16));
65
+ mat4.translate(transform, transform, [cx, cy, cz]);
66
+ mat4.rotate(transform, transform, angle, [ax, ay, az]);
67
+ mat4.translate(transform, transform, [-cx, -cy, -cz]);
68
+ vec3.transformMat4(newPosition, position, transform);
69
+ vec3.transformMat4(newFocalPoint, focalPoint, transform);
70
+
71
+ mat4.identity(transform);
72
+ mat4.rotate(transform, transform, angle, [ax, ay, az]);
73
+ vec3.transformMat4(<Types.Point3>newViewUp, viewUp, transform);
74
+
75
+ viewport.setCamera({
76
+ position: newPosition,
77
+ viewUp: newViewUp,
78
+ focalPoint: newFocalPoint,
79
+ });
80
+
81
+ viewport.render();
82
+ }
83
+ }
84
+
85
+ VolumeRotateMouseWheelTool.toolName = 'VolumeRotateMouseWheel';
86
+ export default VolumeRotateMouseWheelTool;
@@ -0,0 +1,260 @@
1
+ import { BaseTool } from './base';
2
+ import {
3
+ getEnabledElement,
4
+ VolumeViewport,
5
+ StackViewport,
6
+ utilities,
7
+ cache,
8
+ Types,
9
+ } from '@cornerstonejs/core';
10
+ import { EventTypes } from '../types';
11
+
12
+ // Todo: should move to configuration
13
+ const DEFAULT_MULTIPLIER = 4;
14
+ const DEFAULT_IMAGE_DYNAMIC_RANGE = 1024;
15
+ const PT = 'PT';
16
+
17
+ /**
18
+ * WindowLevel tool manipulates the windowLevel applied to a viewport. It
19
+ * provides a way to set the windowCenter and windowWidth of a viewport
20
+ * by dragging mouse over the image.
21
+ *
22
+ */
23
+ class WindowLevelTool extends BaseTool {
24
+ static toolName;
25
+ constructor(
26
+ toolProps = {},
27
+ defaultToolProps = {
28
+ supportedInteractionTypes: ['Mouse', 'Touch'],
29
+ }
30
+ ) {
31
+ super(toolProps, defaultToolProps);
32
+ }
33
+
34
+ touchDragCallback(evt: EventTypes.InteractionEventType) {
35
+ this.mouseDragCallback(evt);
36
+ }
37
+
38
+ mouseDragCallback(evt: EventTypes.InteractionEventType) {
39
+ const { element, deltaPoints } = evt.detail;
40
+ const enabledElement = getEnabledElement(element);
41
+ const { renderingEngine, viewport } = enabledElement;
42
+
43
+ let volumeId,
44
+ lower,
45
+ upper,
46
+ modality,
47
+ newRange,
48
+ viewportsContainingVolumeUID;
49
+ let isPreScaled = false;
50
+
51
+ if (viewport instanceof VolumeViewport) {
52
+ const targetId = this.getTargetId(viewport as Types.IVolumeViewport);
53
+ volumeId = targetId.split('volumeId:')[1];
54
+ viewportsContainingVolumeUID = utilities.getViewportsWithVolumeId(
55
+ volumeId,
56
+ renderingEngine.id
57
+ );
58
+ const properties = viewport.getProperties();
59
+ ({ lower, upper } = properties.voiRange);
60
+ const volume = cache.getVolume(volumeId);
61
+ modality = volume.metadata.Modality;
62
+ isPreScaled = volume.scaling && Object.keys(volume.scaling).length > 0;
63
+ } else if (viewport instanceof StackViewport) {
64
+ const properties = viewport.getProperties();
65
+ modality = viewport.modality;
66
+ ({ lower, upper } = properties.voiRange);
67
+ const { preScale } = viewport.getImageData();
68
+ isPreScaled = preScale.scaled;
69
+ } else {
70
+ throw new Error('Viewport is not a valid type');
71
+ }
72
+
73
+ // If modality is PT, treat it special to not include the canvas delta in
74
+ // the x direction. For other modalities, use the canvas delta in both
75
+ // directions, and if the viewport is a volumeViewport, the multiplier
76
+ // is calculate using the volume min and max.
77
+ if (modality === PT && isPreScaled) {
78
+ newRange = this.getPTNewRange({
79
+ deltaPointsCanvas: deltaPoints.canvas,
80
+ lower,
81
+ upper,
82
+ clientHeight: element.clientHeight,
83
+ });
84
+ } else {
85
+ newRange = this.getNewRange({
86
+ viewport,
87
+ deltaPointsCanvas: deltaPoints.canvas,
88
+ volumeId,
89
+ lower,
90
+ upper,
91
+ });
92
+ }
93
+
94
+ if (viewport instanceof StackViewport) {
95
+ viewport.setProperties({
96
+ voiRange: newRange,
97
+ });
98
+
99
+ viewport.render();
100
+ return;
101
+ }
102
+
103
+ if (viewport instanceof VolumeViewport) {
104
+ viewport.setProperties({
105
+ voiRange: newRange,
106
+ });
107
+
108
+ viewportsContainingVolumeUID.forEach((vp) => {
109
+ vp.render();
110
+ });
111
+ return;
112
+ }
113
+ }
114
+
115
+ getPTNewRange({ deltaPointsCanvas, lower, upper, clientHeight }) {
116
+ const deltaY = deltaPointsCanvas[1];
117
+ const multiplier = 5 / clientHeight;
118
+ const wcDelta = deltaY * multiplier;
119
+
120
+ upper -= wcDelta;
121
+ upper = Math.max(upper, 0.1);
122
+
123
+ return { lower, upper };
124
+ }
125
+
126
+ getNewRange({ viewport, deltaPointsCanvas, volumeId, lower, upper }) {
127
+ const multiplier =
128
+ this._getMultiplierFromDynamicRange(viewport, volumeId) ||
129
+ DEFAULT_MULTIPLIER;
130
+
131
+ const wwDelta = deltaPointsCanvas[0] * multiplier;
132
+ const wcDelta = deltaPointsCanvas[1] * multiplier;
133
+
134
+ let { windowWidth, windowCenter } = utilities.windowLevel.toWindowLevel(
135
+ lower,
136
+ upper
137
+ );
138
+
139
+ windowWidth += wwDelta;
140
+ windowCenter += wcDelta;
141
+
142
+ windowWidth = Math.max(windowWidth, 1);
143
+
144
+ // Convert back to range
145
+ return utilities.windowLevel.toLowHighRange(windowWidth, windowCenter);
146
+ }
147
+
148
+ _getMultiplierFromDynamicRange(viewport, volumeId) {
149
+ let imageDynamicRange;
150
+
151
+ if (volumeId) {
152
+ const imageVolume = cache.getVolume(volumeId);
153
+ const { dimensions } = imageVolume;
154
+ const scalarData = imageVolume.getScalarData();
155
+ const calculatedDynamicRange = this._getImageDynamicRangeFromMiddleSlice(
156
+ scalarData,
157
+ dimensions
158
+ );
159
+ const BitsStored = imageVolume?.metadata?.BitsStored;
160
+ const metadataDynamicRange = BitsStored ? 2 ** BitsStored : Infinity;
161
+ // Burned in Pixels often use pixel values above the BitsStored.
162
+ // This results in a multiplier which is way higher than what you would
163
+ // want in practice. Thus we take the min between the metadata dynamic
164
+ // range and actual middel slice dynamic range.
165
+ imageDynamicRange = Math.min(
166
+ calculatedDynamicRange,
167
+ metadataDynamicRange
168
+ );
169
+ } else {
170
+ imageDynamicRange = this._getImageDynamicRangeFromViewport(viewport);
171
+ }
172
+
173
+ const ratio = imageDynamicRange / DEFAULT_IMAGE_DYNAMIC_RANGE;
174
+
175
+ let multiplier = DEFAULT_MULTIPLIER;
176
+
177
+ if (ratio > 1) {
178
+ multiplier = Math.round(ratio);
179
+ }
180
+ return multiplier;
181
+ }
182
+
183
+ _getImageDynamicRangeFromViewport(viewport) {
184
+ const { imageData } = viewport.getImageData();
185
+ const dimensions = imageData.getDimensions();
186
+
187
+ let scalarData;
188
+ // if getScalarData is a method on imageData
189
+ if (imageData.getScalarData) {
190
+ scalarData = imageData.getScalarData();
191
+ } else {
192
+ scalarData = imageData.getPointData().getScalars();
193
+ }
194
+
195
+ if (dimensions[2] !== 1) {
196
+ return this._getImageDynamicRangeFromMiddleSlice(scalarData, dimensions);
197
+ }
198
+
199
+ let range;
200
+ if (scalarData.getRange) {
201
+ range = scalarData.getRange();
202
+ } else {
203
+ const { min, max } = this._getMinMax(scalarData, scalarData.length);
204
+ range = [min, max];
205
+ }
206
+
207
+ return range[1] - range[0];
208
+ }
209
+
210
+ _getImageDynamicRangeFromMiddleSlice = (scalarData, dimensions) => {
211
+ const middleSliceIndex = Math.floor(dimensions[2] / 2);
212
+
213
+ const frameLength = dimensions[0] * dimensions[1];
214
+ let bytesPerVoxel;
215
+ let TypedArrayConstructor;
216
+
217
+ if (scalarData instanceof Float32Array) {
218
+ bytesPerVoxel = 4;
219
+ TypedArrayConstructor = Float32Array;
220
+ } else if (scalarData instanceof Uint8Array) {
221
+ bytesPerVoxel = 1;
222
+ TypedArrayConstructor = Uint8Array;
223
+ } else if (scalarData instanceof Uint16Array) {
224
+ bytesPerVoxel = 2;
225
+ TypedArrayConstructor = Uint16Array;
226
+ } else if (scalarData instanceof Int16Array) {
227
+ bytesPerVoxel = 2;
228
+ TypedArrayConstructor = Int16Array;
229
+ }
230
+
231
+ const buffer = scalarData.buffer;
232
+ const byteOffset = middleSliceIndex * frameLength * bytesPerVoxel;
233
+ const frame = new TypedArrayConstructor(buffer, byteOffset, frameLength);
234
+
235
+ const { max, min } = this._getMinMax(frame, frameLength);
236
+
237
+ return max - min;
238
+ };
239
+
240
+ private _getMinMax(frame: Uint8Array | Float32Array, frameLength: number) {
241
+ let min = Infinity;
242
+ let max = -Infinity;
243
+
244
+ for (let i = 0; i < frameLength; i++) {
245
+ const voxel = frame[i];
246
+
247
+ if (voxel < min) {
248
+ min = voxel;
249
+ }
250
+
251
+ if (voxel > max) {
252
+ max = voxel;
253
+ }
254
+ }
255
+ return { max, min };
256
+ }
257
+ }
258
+
259
+ WindowLevelTool.toolName = 'WindowLevel';
260
+ export default WindowLevelTool;