@cornerstonejs/core 1.29.0 → 1.30.0

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 (77) hide show
  1. package/dist/cjs/RenderingEngine/StackViewport.d.ts +1 -0
  2. package/dist/cjs/RenderingEngine/StackViewport.js +3 -0
  3. package/dist/cjs/RenderingEngine/StackViewport.js.map +1 -1
  4. package/dist/cjs/RenderingEngine/VideoViewport.d.ts +42 -3
  5. package/dist/cjs/RenderingEngine/VideoViewport.js +192 -13
  6. package/dist/cjs/RenderingEngine/VideoViewport.js.map +1 -1
  7. package/dist/cjs/RenderingEngine/Viewport.d.ts +1 -0
  8. package/dist/cjs/RenderingEngine/Viewport.js.map +1 -1
  9. package/dist/cjs/RenderingEngine/VolumeViewport.d.ts +1 -0
  10. package/dist/cjs/RenderingEngine/VolumeViewport.js +5 -0
  11. package/dist/cjs/RenderingEngine/VolumeViewport.js.map +1 -1
  12. package/dist/cjs/enums/MetadataModules.d.ts +11 -0
  13. package/dist/cjs/enums/MetadataModules.js +15 -0
  14. package/dist/cjs/enums/MetadataModules.js.map +1 -0
  15. package/dist/cjs/enums/index.d.ts +2 -1
  16. package/dist/cjs/enums/index.js +3 -1
  17. package/dist/cjs/enums/index.js.map +1 -1
  18. package/dist/cjs/types/IVideoViewport.d.ts +1 -0
  19. package/dist/cjs/types/IViewport.d.ts +1 -0
  20. package/dist/cjs/types/VideoViewportProperties.d.ts +1 -1
  21. package/dist/cjs/utilities/index.d.ts +2 -1
  22. package/dist/cjs/utilities/index.js +3 -1
  23. package/dist/cjs/utilities/index.js.map +1 -1
  24. package/dist/cjs/utilities/isVideoTransferSyntax.d.ts +2 -0
  25. package/dist/cjs/utilities/isVideoTransferSyntax.js +30 -0
  26. package/dist/cjs/utilities/isVideoTransferSyntax.js.map +1 -0
  27. package/dist/esm/RenderingEngine/StackViewport.js +3 -0
  28. package/dist/esm/RenderingEngine/StackViewport.js.map +1 -1
  29. package/dist/esm/RenderingEngine/VideoViewport.js +170 -14
  30. package/dist/esm/RenderingEngine/VideoViewport.js.map +1 -1
  31. package/dist/esm/RenderingEngine/Viewport.js.map +1 -1
  32. package/dist/esm/RenderingEngine/VolumeViewport.js +5 -0
  33. package/dist/esm/RenderingEngine/VolumeViewport.js.map +1 -1
  34. package/dist/esm/enums/MetadataModules.js +13 -0
  35. package/dist/esm/enums/MetadataModules.js.map +1 -0
  36. package/dist/esm/enums/index.js +2 -1
  37. package/dist/esm/enums/index.js.map +1 -1
  38. package/dist/esm/utilities/index.js +2 -1
  39. package/dist/esm/utilities/index.js.map +1 -1
  40. package/dist/esm/utilities/isVideoTransferSyntax.js +26 -0
  41. package/dist/esm/utilities/isVideoTransferSyntax.js.map +1 -0
  42. package/dist/types/RenderingEngine/StackViewport.d.ts +1 -0
  43. package/dist/types/RenderingEngine/StackViewport.d.ts.map +1 -1
  44. package/dist/types/RenderingEngine/VideoViewport.d.ts +42 -3
  45. package/dist/types/RenderingEngine/VideoViewport.d.ts.map +1 -1
  46. package/dist/types/RenderingEngine/Viewport.d.ts +1 -0
  47. package/dist/types/RenderingEngine/Viewport.d.ts.map +1 -1
  48. package/dist/types/RenderingEngine/VolumeViewport.d.ts +1 -0
  49. package/dist/types/RenderingEngine/VolumeViewport.d.ts.map +1 -1
  50. package/dist/types/enums/MetadataModules.d.ts +12 -0
  51. package/dist/types/enums/MetadataModules.d.ts.map +1 -0
  52. package/dist/types/enums/index.d.ts +2 -1
  53. package/dist/types/enums/index.d.ts.map +1 -1
  54. package/dist/types/types/IVideoViewport.d.ts +1 -0
  55. package/dist/types/types/IVideoViewport.d.ts.map +1 -1
  56. package/dist/types/types/IViewport.d.ts +1 -0
  57. package/dist/types/types/IViewport.d.ts.map +1 -1
  58. package/dist/types/types/VideoViewportProperties.d.ts +1 -1
  59. package/dist/types/types/VideoViewportProperties.d.ts.map +1 -1
  60. package/dist/types/utilities/index.d.ts +2 -1
  61. package/dist/types/utilities/index.d.ts.map +1 -1
  62. package/dist/types/utilities/isVideoTransferSyntax.d.ts +3 -0
  63. package/dist/types/utilities/isVideoTransferSyntax.d.ts.map +1 -0
  64. package/dist/umd/index.js +1 -1
  65. package/dist/umd/index.js.map +1 -1
  66. package/package.json +2 -2
  67. package/src/RenderingEngine/StackViewport.ts +5 -0
  68. package/src/RenderingEngine/VideoViewport.ts +255 -16
  69. package/src/RenderingEngine/Viewport.ts +1 -0
  70. package/src/RenderingEngine/VolumeViewport.ts +7 -0
  71. package/src/enums/MetadataModules.ts +20 -0
  72. package/src/enums/index.ts +2 -0
  73. package/src/types/IVideoViewport.ts +7 -0
  74. package/src/types/IViewport.ts +2 -0
  75. package/src/types/VideoViewportProperties.ts +1 -3
  76. package/src/utilities/index.ts +2 -0
  77. package/src/utilities/isVideoTransferSyntax.ts +26 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/core",
3
- "version": "1.29.0",
3
+ "version": "1.30.0",
4
4
  "description": "",
5
5
  "main": "src/index.ts",
6
6
  "types": "dist/types/index.d.ts",
@@ -46,5 +46,5 @@
46
46
  "type": "individual",
47
47
  "url": "https://ohif.org/donate"
48
48
  },
49
- "gitHead": "7e7c3eb2156c26f594af9e664405f64d9e269f4d"
49
+ "gitHead": "9098e604b0099ed3e779d85faa6a1d0e2a4cc4c7"
50
50
  }
@@ -554,6 +554,11 @@ class StackViewport extends Viewport implements IStackViewport, IImagesLoader {
554
554
  return actor;
555
555
  };
556
556
 
557
+ /** Gets the number of slices */
558
+ public getNumberOfSlices = (): number => {
559
+ return this.imageIds.length;
560
+ };
561
+
557
562
  /**
558
563
  * Retrieves the metadata from the metadata provider, and optionally adds the
559
564
  * scaling to the viewport if modality is PET and scaling metadata is provided.
@@ -1,4 +1,9 @@
1
- import { Events as EVENTS, VideoViewport as VideoViewportEnum } from '../enums';
1
+ import { vec3 } from 'gl-matrix';
2
+ import {
3
+ Events as EVENTS,
4
+ VideoViewport as VideoViewportEnum,
5
+ MetadataModules,
6
+ } from '../enums';
2
7
  import {
3
8
  IVideoViewport,
4
9
  VideoViewportProperties,
@@ -7,7 +12,9 @@ import {
7
12
  ICamera,
8
13
  InternalVideoCamera,
9
14
  VideoViewportInput,
15
+ VOIRange,
10
16
  } from '../types';
17
+ import * as metaData from '../metaData';
11
18
  import { Transform } from './helpers/cpuFallback/rendering/transform';
12
19
  import { triggerEvent } from '../utilities';
13
20
  import Viewport from './Viewport';
@@ -18,7 +25,9 @@ import { getOrCreateCanvas } from './helpers';
18
25
  * looking into an internal scene, and an associated target output `canvas`.
19
26
  */
20
27
  class VideoViewport extends Viewport implements IVideoViewport {
28
+ public modality;
21
29
  // Viewport Data
30
+ protected imageId: string;
22
31
  readonly uid;
23
32
  readonly renderingEngineId: string;
24
33
  readonly canvasContext: CanvasRenderingContext2D;
@@ -30,12 +39,43 @@ class VideoViewport extends Viewport implements IVideoViewport {
30
39
  private mute = true;
31
40
  private isPlaying = false;
32
41
  private scrollSpeed = 1;
33
- private fps = 30; // TODO We need to find a good solution for this.
42
+ private playbackRate = 1;
43
+
44
+ protected metadata;
45
+
46
+ /**
47
+ * The fps, frames per second is used to calculate time/frame mapping values.
48
+ * It is provided by the CINE Module in the metadata, defaulting to 30 if not
49
+ * provided.
50
+ */
51
+ private fps = 30;
52
+
34
53
  private videoCamera: InternalVideoCamera = {
35
54
  panWorld: [0, 0],
36
55
  parallelScale: 1,
37
56
  };
38
57
 
58
+ /**
59
+ * feFilter is an inline string value for the CSS filter on the video
60
+ * CSS filters can reference SVG filters, so for the typical use case here
61
+ * the CSS filter is actually an link link to a SVG filter.
62
+ */
63
+ private feFilter: string;
64
+
65
+ /**
66
+ * An average white point value, used to color balance the image so that
67
+ * the given white is mapped to [255,255,255] via multiplication per channel.
68
+ */
69
+ private averageWhite: [number, number, number];
70
+
71
+ /**
72
+ * The VOI Range is used to apply contrast/brightness adjustments to the image.
73
+ */
74
+ private voiRange: VOIRange = {
75
+ lower: 0,
76
+ upper: 255,
77
+ };
78
+
39
79
  constructor(props: VideoViewportInput) {
40
80
  super({
41
81
  ...props,
@@ -82,6 +122,86 @@ class VideoViewport extends Viewport implements IVideoViewport {
82
122
  this.videoElement.remove();
83
123
  }
84
124
 
125
+ private _getImageDataMetadata() {
126
+ const imagePlaneModule = metaData.get(
127
+ MetadataModules.IMAGE_PLANE,
128
+ this.imageId
129
+ );
130
+
131
+ let rowCosines = <Point3>imagePlaneModule.rowCosines;
132
+ let columnCosines = <Point3>imagePlaneModule.columnCosines;
133
+
134
+ // if null or undefined
135
+ if (rowCosines == null || columnCosines == null) {
136
+ rowCosines = <Point3>[1, 0, 0];
137
+ columnCosines = <Point3>[0, 1, 0];
138
+ }
139
+
140
+ const rowCosineVec = vec3.fromValues(
141
+ rowCosines[0],
142
+ rowCosines[1],
143
+ rowCosines[2]
144
+ );
145
+ const colCosineVec = vec3.fromValues(
146
+ columnCosines[0],
147
+ columnCosines[1],
148
+ columnCosines[2]
149
+ );
150
+ const scanAxisNormal = vec3.create();
151
+ vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);
152
+
153
+ let origin = imagePlaneModule.imagePositionPatient;
154
+ // if null or undefined
155
+ if (origin == null) {
156
+ origin = [0, 0, 0];
157
+ }
158
+
159
+ const xSpacing = imagePlaneModule.columnPixelSpacing;
160
+ const ySpacing = imagePlaneModule.rowPixelSpacing;
161
+ const xVoxels = imagePlaneModule.columns;
162
+ const yVoxels = imagePlaneModule.rows;
163
+
164
+ const zSpacing = 1;
165
+ const zVoxels = 1;
166
+
167
+ return {
168
+ bitsAllocated: 8,
169
+ numComps: 3,
170
+ origin,
171
+ direction: [...rowCosineVec, ...colCosineVec, ...scanAxisNormal],
172
+ dimensions: [xVoxels, yVoxels, zVoxels],
173
+ spacing: [xSpacing, ySpacing, zSpacing],
174
+ numVoxels: xVoxels * yVoxels * zVoxels,
175
+ imagePlaneModule,
176
+ };
177
+ }
178
+
179
+ /**
180
+ * Sets the video image id to show and hte frame number.
181
+ * Requirements are to have the imageUrlModule in the metadata
182
+ * with the rendered endpoint being the raw video in video/mp4 format.
183
+ */
184
+ public setVideo(
185
+ imageIds: string | string[],
186
+ frameNumber?: number
187
+ ): Promise<unknown> {
188
+ this.imageId = Array.isArray(imageIds) ? imageIds[0] : imageIds;
189
+ const { imageId } = this;
190
+ const { rendered } = metaData.get(MetadataModules.IMAGE_URL, imageId);
191
+ const generalSeries = metaData.get(MetadataModules.GENERAL_SERIES, imageId);
192
+ this.modality = generalSeries?.Modality;
193
+ this.metadata = this._getImageDataMetadata();
194
+
195
+ return this.setVideoURL(rendered).then(() => {
196
+ const { cineRate = 30 } = metaData.get(MetadataModules.CINE, imageId);
197
+ this.fps = cineRate;
198
+ if (frameNumber !== undefined) {
199
+ this.pause();
200
+ this.setFrame(frameNumber);
201
+ }
202
+ });
203
+ }
204
+
85
205
  public async setVideoURL(videoURL: string) {
86
206
  return new Promise((resolve) => {
87
207
  this.videoElement.src = videoURL;
@@ -126,10 +246,8 @@ class VideoViewport extends Viewport implements IVideoViewport {
126
246
  }
127
247
 
128
248
  public async pause() {
129
- if (this.isPlaying) {
130
- await this.videoElement.pause();
131
- this.isPlaying = false;
132
- }
249
+ await this.videoElement.pause();
250
+ this.isPlaying = false;
133
251
  }
134
252
 
135
253
  public async scroll(delta = 1) {
@@ -162,8 +280,6 @@ class VideoViewport extends Viewport implements IVideoViewport {
162
280
  if (videoElement.paused) {
163
281
  // Need to wait for seek update
164
282
  const seekEventListener = (evt) => {
165
- console.log('seeked');
166
-
167
283
  renderFrame();
168
284
 
169
285
  videoElement.removeEventListener('seeked', seekEventListener);
@@ -214,21 +330,30 @@ class VideoViewport extends Viewport implements IVideoViewport {
214
330
  this.setTime((frame - 1) / this.fps);
215
331
  }
216
332
 
217
- public setProperties(videoInterface: VideoViewportProperties) {
218
- if (videoInterface.loop !== undefined) {
219
- this.videoElement.loop = videoInterface.loop;
333
+ public setProperties(props: VideoViewportProperties) {
334
+ if (props.loop !== undefined) {
335
+ this.videoElement.loop = props.loop;
220
336
  }
221
337
 
222
- if (videoInterface.muted !== undefined) {
223
- this.videoElement.muted = videoInterface.muted;
338
+ if (props.muted !== undefined) {
339
+ this.videoElement.muted = props.muted;
224
340
  }
225
341
 
226
- if (videoInterface.playbackRate !== undefined) {
227
- this.setPlaybackRate(videoInterface.playbackRate);
342
+ if (props.playbackRate !== undefined) {
343
+ this.setPlaybackRate(props.playbackRate);
344
+ }
345
+
346
+ if (props.scrollSpeed !== undefined) {
347
+ this.setScrollSpeed(props.scrollSpeed);
348
+ }
349
+
350
+ if (props.voiRange) {
351
+ this.setVOI(props.voiRange);
228
352
  }
229
353
  }
230
354
 
231
355
  public setPlaybackRate(rate = 1) {
356
+ this.playbackRate = rate;
232
357
  // Minimum playback speed in chrome is 0.0625 compared to normal
233
358
  if (rate < 0.0625) {
234
359
  this.pause();
@@ -255,6 +380,9 @@ class VideoViewport extends Viewport implements IVideoViewport {
255
380
  return {
256
381
  loop: this.videoElement.loop,
257
382
  muted: this.videoElement.muted,
383
+ playbackRate: this.playbackRate,
384
+ scrollSpeed: this.scrollSpeed,
385
+ voiRange: { ...this.voiRange },
258
386
  };
259
387
  };
260
388
 
@@ -265,8 +393,101 @@ class VideoViewport extends Viewport implements IVideoViewport {
265
393
  });
266
394
  }
267
395
 
396
+ protected getScalarData() {
397
+ const canvas = document.createElement('canvas');
398
+ canvas.width = this.videoWidth;
399
+ canvas.height = this.videoHeight;
400
+ const context = canvas.getContext('2d');
401
+ context.drawImage(this.videoElement, 0, 0);
402
+ const canvasData = context.getImageData(
403
+ 0,
404
+ 0,
405
+ this.videoWidth,
406
+ this.videoHeight
407
+ );
408
+ const { data: scalarData } = canvasData;
409
+ (scalarData as any).getRange = () => [0, 255];
410
+ return scalarData;
411
+ }
412
+
268
413
  public getImageData() {
269
- return null;
414
+ const { metadata } = this;
415
+
416
+ const spacing = metadata.spacing;
417
+
418
+ return {
419
+ dimensions: metadata.dimensions,
420
+ spacing,
421
+ origin: metadata.origin,
422
+ direction: metadata.direction,
423
+ metadata: { Modality: this.modality },
424
+ imageData: {
425
+ getDirection: () => metadata.direction,
426
+ getDimensions: () => metadata.dimensions,
427
+ getRange: () => [0, 255],
428
+ getScalarData: () => this.getScalarData(),
429
+ getSpacing: () => metadata.spacing,
430
+ worldToIndex: (point: Point3) => {
431
+ const canvasPoint = this.worldToCanvas(point);
432
+ const pixelCoord = this.canvasToIndex(canvasPoint);
433
+ return [pixelCoord[0], pixelCoord[1], 0];
434
+ },
435
+ indexToWorld: (point: Point3) => {
436
+ const canvasPoint = this.indexToCanvas([point[0], point[1]]);
437
+ return this.canvasToWorld(canvasPoint);
438
+ },
439
+ },
440
+ hasPixelSpacing: this.hasPixelSpacing,
441
+ calibration: this.calibration,
442
+ preScale: {
443
+ scaled: false,
444
+ },
445
+ };
446
+ }
447
+
448
+ public setVOI(voiRange: VOIRange): void {
449
+ this.voiRange = voiRange;
450
+ this.setColorTransform();
451
+ }
452
+
453
+ public setWindowLevel(windowWidth = 256, windowCenter = 128) {
454
+ const lower = windowCenter - windowWidth / 2;
455
+ const upper = windowCenter + windowWidth / 2 - 1;
456
+ this.setVOI({ lower, upper });
457
+ this.setColorTransform();
458
+ }
459
+
460
+ public setAverageWhite(averageWhite: [number, number, number]) {
461
+ this.averageWhite = averageWhite;
462
+ this.setColorTransform();
463
+ }
464
+
465
+ protected setColorTransform() {
466
+ if (!this.voiRange && !this.averageWhite) {
467
+ this.feFilter = null;
468
+ return;
469
+ }
470
+ const white = this.averageWhite || [255, 255, 255];
471
+ const maxWhite = Math.max(...white);
472
+ const scaleWhite = white.map((c) => maxWhite / c);
473
+ // From the DICOM standard: ((x - (c - 0.5)) / (w-1) + 0.5) * (ymax- ymin) + ymin
474
+ // which is x/(w-1) - (c - 0.5) / (w-1) + 0.5 for this case
475
+ const { lower = 0, upper = 255 } = this.voiRange || {};
476
+ const wlScale = (upper - lower + 1) / 255;
477
+ const wlDelta = lower / 255;
478
+ this.feFilter = `url('data:image/svg+xml,\
479
+ <svg xmlns="http://www.w3.org/2000/svg">\
480
+ <filter id="colour" color-interpolation-filters="linearRGB">\
481
+ <feColorMatrix type="matrix" \
482
+ values="\
483
+ ${scaleWhite[0] * wlScale} 0 0 0 ${wlDelta} \
484
+ 0 ${scaleWhite[1] * wlScale} 0 0 ${wlDelta} \
485
+ 0 0 ${scaleWhite[2] * wlScale} 0 ${wlDelta} \
486
+ 0 0 0 1 0" />\
487
+ </filter>\
488
+ </svg>#colour')`;
489
+
490
+ this.canvas.style.filter = this.feFilter;
270
491
  }
271
492
 
272
493
  public setCamera(camera: ICamera): void {
@@ -339,6 +560,10 @@ class VideoViewport extends Viewport implements IVideoViewport {
339
560
  return true;
340
561
  };
341
562
 
563
+ public getNumberOfSlices = (): number => {
564
+ return (this.videoElement.duration * this.fps) / this.scrollSpeed;
565
+ };
566
+
342
567
  public getFrameOfReferenceUID = (): string => {
343
568
  // The video itself is the frame of reference.
344
569
  return this.videoElement.src;
@@ -411,6 +636,20 @@ class VideoViewport extends Viewport implements IVideoViewport {
411
636
  return canvasPos;
412
637
  };
413
638
 
639
+ protected canvasToIndex = (canvasPos: Point2): Point2 => {
640
+ const [x, y] = canvasPos;
641
+ const ratio = this.videoWidth / this.canvas.width;
642
+ const pan = this.getPan();
643
+ return [(x + pan[0]) * ratio, (y + pan[1]) * ratio];
644
+ };
645
+
646
+ protected indexToCanvas = (indexPos: Point2): Point2 => {
647
+ const [x, y] = indexPos;
648
+ const ratio = this.canvas.width / this.videoWidth;
649
+ const pan = this.getPan();
650
+ return [x * ratio - pan[0], y * ratio - pan[1]];
651
+ };
652
+
414
653
  private refreshRenderValues() {
415
654
  // this means that each unit (pixel) in the world (video) would be
416
655
  // represented by n pixels in the canvas.
@@ -127,6 +127,7 @@ class Viewport implements IViewport {
127
127
  resize: () => void;
128
128
  getProperties: () => void;
129
129
  updateRenderingPipeline: () => void;
130
+ getNumberOfSlices: () => number;
130
131
 
131
132
  static get useCustomRenderingPipeline(): boolean {
132
133
  return false;
@@ -25,6 +25,7 @@ import BaseVolumeViewport from './BaseVolumeViewport';
25
25
  import setDefaultVolumeVOI from './helpers/setDefaultVolumeVOI';
26
26
  import { setTransferFunctionNodes } from '../utilities/transferFunctionUtils';
27
27
  import { ImageActor } from '../types/IActor';
28
+ import getImageSliceDataForVolumeViewport from '../utilities/getImageSliceDataForVolumeViewport';
28
29
 
29
30
  /**
30
31
  * An object representing a VolumeViewport. VolumeViewports are used to render
@@ -82,6 +83,12 @@ class VolumeViewport extends BaseVolumeViewport {
82
83
  return super.setVolumes(volumeInputArray, immediate, suppressEvents);
83
84
  }
84
85
 
86
+ /** Gets the number of slices the volume is broken up into in the camera direction */
87
+ public getNumberOfSlices = (): number => {
88
+ const { numberOfSlices } = getImageSliceDataForVolumeViewport(this);
89
+ return numberOfSlices;
90
+ };
91
+
85
92
  /**
86
93
  * Creates and adds volume actors for all volumes defined in the `volumeInputArray`.
87
94
  * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Contains the names for the metadata modules.
3
+ * Recommendation is to add all module names here rather than having them
4
+ * just use string names.
5
+ * The naming convention is that the enum has the modules in it, so the
6
+ * enum key does not repeat the Modules, but the enum value does (to agree
7
+ * with existing naming conventions)
8
+ */
9
+ enum MetadataModules {
10
+ CINE = 'cineModule',
11
+ IMAGE_URL = 'imageUrlModule',
12
+ GENERAL_SERIES = 'generalSeriesModule',
13
+ PATIENT_STUDY = 'patientStudyModule',
14
+ NM_MULTIFRAME_GEOMETRY = 'nmMultiframeGeometryModule',
15
+ IMAGE_PLANE = 'imagePlaneModule',
16
+ IMAGE_PIXEL = 'imagePixelModule',
17
+ MULTIFRAME = 'multiframeModule',
18
+ }
19
+
20
+ export default MetadataModules;
@@ -13,6 +13,7 @@ import CalibrationTypes from './CalibrationTypes';
13
13
  import ViewportStatus from './ViewportStatus';
14
14
  import ImageQualityStatus from './ImageQualityStatus';
15
15
  import * as VideoViewport from './VideoViewport';
16
+ import MetadataModules from './MetadataModules';
16
17
 
17
18
  export {
18
19
  Events,
@@ -29,5 +30,6 @@ export {
29
30
  DynamicOperatorType,
30
31
  ViewportStatus,
31
32
  VideoViewport,
33
+ MetadataModules,
32
34
  ImageQualityStatus,
33
35
  };
@@ -19,15 +19,22 @@ export default interface IVideoViewport extends IViewport {
19
19
  */
20
20
  getProperties: () => VideoViewportProperties;
21
21
 
22
+ setVideo: (
23
+ imageIds: string | string[],
24
+ imageIdIndex?: number
25
+ ) => Promise<unknown>;
26
+
22
27
  setVideoURL: (url: string) => void;
23
28
 
24
29
  play: () => void;
25
30
 
26
31
  pause: () => void;
32
+
27
33
  /**
28
34
  * Reset the viewport properties to the default values
29
35
  */
30
36
  resetProperties(): void;
37
+
31
38
  /**
32
39
  * Centers Pan and resets the zoom for stack viewport.
33
40
  */
@@ -104,6 +104,8 @@ interface IViewport {
104
104
  setPan(pan: Point2, storeAsInitialCamera?: boolean);
105
105
  /** sets the camera */
106
106
  setCamera(cameraInterface: ICamera, storeAsInitialCamera?: boolean): void;
107
+ /** Gets the number of slices in the current camera orientation */
108
+ getNumberOfSlices(): number;
107
109
  /** whether the viewport has custom rendering */
108
110
  customRenderViewportToCanvas: () => unknown;
109
111
  _getCorners(bounds: Array<number>): Array<number>[];
@@ -9,9 +9,7 @@ type VideoViewportProperties = ViewportProperties & {
9
9
  muted?: boolean;
10
10
  pan?: Point2;
11
11
  playbackRate?: number;
12
- // The zoom factor, naming consistent with vtk cameras for now,
13
- // but this isn't necessarily necessary.
14
- parallelScale?: number;
12
+ scrollSpeed?: number;
15
13
  };
16
14
 
17
15
  export default VideoViewportProperties;
@@ -52,6 +52,7 @@ import getImageLegacy from './getImageLegacy';
52
52
  import ProgressiveIterator from './ProgressiveIterator';
53
53
  import decimate from './decimate';
54
54
  import imageRetrieveMetadataProvider from './imageRetrieveMetadataProvider';
55
+ import isVideoTransferSyntax from './isVideoTransferSyntax';
55
56
 
56
57
  // name spaces
57
58
  import * as planar from './planar';
@@ -119,4 +120,5 @@ export {
119
120
  decimate,
120
121
  imageRetrieveMetadataProvider,
121
122
  transferFunctionUtils,
123
+ isVideoTransferSyntax,
122
124
  };
@@ -0,0 +1,26 @@
1
+ export const videoUIDs = new Set<string>([
2
+ '1.2.840.10008.1.2.4.100',
3
+ '1.2.840.10008.1.2.4.100.1',
4
+ '1.2.840.10008.1.2.4.101',
5
+ '1.2.840.10008.1.2.4.101.1',
6
+ '1.2.840.10008.1.2.4.102',
7
+ '1.2.840.10008.1.2.4.102.1',
8
+ '1.2.840.10008.1.2.4.103',
9
+ '1.2.840.10008.1.2.4.103.1',
10
+ '1.2.840.10008.1.2.4.104',
11
+ '1.2.840.10008.1.2.4.104.1',
12
+ '1.2.840.10008.1.2.4.105',
13
+ '1.2.840.10008.1.2.4.105.1',
14
+ '1.2.840.10008.1.2.4.106',
15
+ '1.2.840.10008.1.2.4.106.1',
16
+ '1.2.840.10008.1.2.4.107',
17
+ '1.2.840.10008.1.2.4.108',
18
+ ]);
19
+
20
+ export default function isVideoTransferSyntax(uidOrUids: string | string[]) {
21
+ if (!uidOrUids) {
22
+ return false;
23
+ }
24
+ const uids = Array.isArray(uidOrUids) ? uidOrUids : [uidOrUids];
25
+ return uids.find((uid) => videoUIDs.has(uid));
26
+ }