@ohif/app 3.8.0-beta.23 → 3.8.0-beta.24
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/{663.bundle.eae1939c22b73ea4c29f.js → 170.bundle.4334f8b364d969afe84e.js} +11 -20
- package/dist/{181.bundle.bce8ecb8af857b2513df.js → 181.bundle.8bbcaf31270dd56cad1f.js} +4 -4
- package/dist/{563.bundle.4debceb80aee325eec86.js → 185.bundle.4502bc07831d495b9280.js} +4 -11
- package/dist/{126.bundle.0ebe6d5227b3e9481532.js → 199.bundle.361e62f9825452d9e6d4.js} +4 -11
- package/dist/{202.bundle.ec714227032b22d4fa24.js → 202.bundle.07442d396db3161ee7f3.js} +336 -328
- package/dist/20fc4c659b85ccd2a9c0.wasm +0 -0
- package/dist/{250.bundle.6ca102e0e62885294c23.js → 250.bundle.de8df38690c1305b2f8a.js} +2 -2
- package/dist/{575.bundle.b400797624d717956cfb.js → 420.bundle.cb136058d63e468937d7.js} +7 -16
- package/dist/{221.bundle.cf2ed62de0a9445c9239.js → 466.bundle.516808dcd1d56f8d1bd0.js} +6 -13
- package/dist/{47.bundle.01d2751a9fd67b3d5390.js → 47.bundle.3217b1b873983a6aaa43.js} +341 -266
- package/dist/{788.bundle.57fbc328e3554d9f4659.js → 483.bundle.01ef48ca248206277a82.js} +6 -13
- package/dist/{82.bundle.122d1b58bc3e22439dd9.js → 544.bundle.b2b65dd140e9854cb129.js} +1228 -829
- package/dist/{738.bundle.e03f4127b014ff8ab5a5.js → 738.bundle.c2b678137aeffca66247.js} +2 -2
- package/dist/{822.bundle.4f0424bd1dc0308bb489.js → 822.bundle.1f4c9e059e87914fc12a.js} +2 -2
- package/dist/{236.bundle.19118b0e7881c6359804.js → 965.bundle.c9a8527196a3e07a0edb.js} +3 -10
- package/dist/{app.bundle.e18399dc0b54a4851b2d.js → app.bundle.3112c1b1ef2f14ac3dda.js} +81439 -22
- package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
- package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
- package/dist/index.html +1 -1
- package/dist/{index.worker.e62ecca63f1a2e124230.worker.js → index.worker.64c896c4316fcd506666.worker.js} +2 -2
- package/dist/index.worker.64c896c4316fcd506666.worker.js.map +1 -0
- package/dist/sw.js +1 -1
- package/package.json +18 -18
- package/dist/231.bundle.8aad229e39e23731d6c1.js +0 -79023
- package/dist/75788f12450d4c5ed494.wasm +0 -0
- package/dist/775.bundle.2285e7e0e67878948c0d.js +0 -1009
- package/dist/index.worker.e62ecca63f1a2e124230.worker.js.map +0 -1
- /package/dist/{12.bundle.c3dc58d8dff2e83ce920.js → 12.bundle.ea6ad3ba74e12da245ee.js} +0 -0
- /package/dist/{19.bundle.60717b06985980e0a237.js → 19.bundle.d26fd663937cb6da7e4e.js} +0 -0
- /package/dist/{281.bundle.93c845676e4645263c8d.js → 281.bundle.68ff7d9fd09da731bc30.js} +0 -0
- /package/dist/{359.bundle.94a407fdbfcb299f2dc2.js → 359.bundle.c43b9edcde392873039a.js} +0 -0
- /package/dist/{410.bundle.116f4a42e6b76e0a2bcb.js → 410.bundle.69d2ac6302307232feb6.js} +0 -0
- /package/dist/{575.css → 420.css} +0 -0
- /package/dist/{221.css → 466.css} +0 -0
- /package/dist/{506.bundle.20af254ec61a959452cc.js → 506.bundle.b8b35a2d4047ecf0de72.js} +0 -0
- /package/dist/{613.bundle.59befe43e90034b4d879.js → 613.bundle.1470935d8a6ab639ad58.js} +0 -0
- /package/dist/{687.bundle.60a8d6ae5f913c189168.js → 687.bundle.afe4b435252e619caba6.js} +0 -0
- /package/dist/{814.bundle.4b853464ad249a249029.js → 814.bundle.7d70d991bb9a0dde9afb.js} +0 -0
|
@@ -12,8 +12,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
12
12
|
|
|
13
13
|
// UNUSED EXPORTS: Enums, StreamingDynamicImageVolume, StreamingImageVolume, cornerstoneStreamingDynamicImageVolumeLoader, helpers
|
|
14
14
|
|
|
15
|
-
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js +
|
|
16
|
-
var esm = __webpack_require__(
|
|
15
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 356 modules
|
|
16
|
+
var esm = __webpack_require__(63442);
|
|
17
17
|
// EXTERNAL MODULE: ../../../node_modules/gl-matrix/esm/index.js + 10 modules
|
|
18
18
|
var gl_matrix_esm = __webpack_require__(45451);
|
|
19
19
|
;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/streaming-image-volume-loader/dist/esm/helpers/makeVolumeMetadata.js
|
|
@@ -315,14 +315,22 @@ function scaleArray(array, scalingParameters) {
|
|
|
315
315
|
;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/streaming-image-volume-loader/dist/esm/BaseStreamingImageVolume.js
|
|
316
316
|
|
|
317
317
|
|
|
318
|
-
const
|
|
319
|
-
const { getMinMax } = esm.utilities;
|
|
318
|
+
const requestTypeDefault = esm.Enums.RequestType.Prefetch;
|
|
319
|
+
const { getMinMax, ProgressiveIterator } = esm.utilities;
|
|
320
|
+
const { ImageQualityStatus } = esm.Enums;
|
|
321
|
+
const { imageRetrieveMetadataProvider } = esm.utilities;
|
|
320
322
|
class BaseStreamingImageVolume_BaseStreamingImageVolume extends esm.ImageVolume {
|
|
321
323
|
constructor(imageVolumeProperties, streamingProperties) {
|
|
322
324
|
super(imageVolumeProperties);
|
|
323
325
|
this.framesLoaded = 0;
|
|
324
326
|
this.framesProcessed = 0;
|
|
327
|
+
this.framesUpdated = 0;
|
|
325
328
|
this.cornerstoneImageMetaData = null;
|
|
329
|
+
this.autoRenderOnLoad = true;
|
|
330
|
+
this.cachedFrames = [];
|
|
331
|
+
this.reRenderTarget = 0;
|
|
332
|
+
this.reRenderFraction = 2;
|
|
333
|
+
this.imagesLoader = this;
|
|
326
334
|
this.cancelLoading = () => {
|
|
327
335
|
const { loadStatus } = this;
|
|
328
336
|
if (!loadStatus || !loadStatus.loading) {
|
|
@@ -336,10 +344,15 @@ class BaseStreamingImageVolume_BaseStreamingImageVolume extends esm.ImageVolume
|
|
|
336
344
|
};
|
|
337
345
|
esm.imageLoadPoolManager.filterRequests(filterFunction);
|
|
338
346
|
};
|
|
339
|
-
this.load = (callback
|
|
347
|
+
this.load = (callback) => {
|
|
340
348
|
const { imageIds, loadStatus, numFrames } = this;
|
|
349
|
+
const { transferSyntaxUID } = esm.metaData.get('transferSyntax', imageIds[0]) || {};
|
|
350
|
+
const imageRetrieveConfiguration = esm.metaData.get(imageRetrieveMetadataProvider.IMAGE_RETRIEVE_CONFIGURATION, this.volumeId, transferSyntaxUID, 'volume');
|
|
351
|
+
this.imagesLoader = imageRetrieveConfiguration
|
|
352
|
+
? (imageRetrieveConfiguration.create ||
|
|
353
|
+
esm.ProgressiveRetrieveImages.createProgressive)(imageRetrieveConfiguration)
|
|
354
|
+
: this;
|
|
341
355
|
if (loadStatus.loading === true) {
|
|
342
|
-
console.log(`loadVolume: Loading is already in progress for ${this.volumeId}`);
|
|
343
356
|
return;
|
|
344
357
|
}
|
|
345
358
|
const { loaded } = this.loadStatus;
|
|
@@ -359,255 +372,7 @@ class BaseStreamingImageVolume_BaseStreamingImageVolume extends esm.ImageVolume
|
|
|
359
372
|
if (callback) {
|
|
360
373
|
this.loadStatus.callbacks.push(callback);
|
|
361
374
|
}
|
|
362
|
-
this._prefetchImageIds(
|
|
363
|
-
};
|
|
364
|
-
this.getImageIdsRequests = (imageIds, scalarData, priority) => {
|
|
365
|
-
const { loadStatus } = this;
|
|
366
|
-
const { cachedFrames } = loadStatus;
|
|
367
|
-
const { vtkOpenGLTexture, imageData, metadata, volumeId } = this;
|
|
368
|
-
const { FrameOfReferenceUID } = metadata;
|
|
369
|
-
const arrayBuffer = scalarData.buffer;
|
|
370
|
-
const numFrames = imageIds.length;
|
|
371
|
-
const length = scalarData.length / numFrames;
|
|
372
|
-
const lengthInBytes = arrayBuffer.byteLength / numFrames;
|
|
373
|
-
let type;
|
|
374
|
-
if (scalarData instanceof Uint8Array) {
|
|
375
|
-
type = 'Uint8Array';
|
|
376
|
-
}
|
|
377
|
-
else if (scalarData instanceof Float32Array) {
|
|
378
|
-
type = 'Float32Array';
|
|
379
|
-
}
|
|
380
|
-
else if (scalarData instanceof Uint16Array) {
|
|
381
|
-
type = 'Uint16Array';
|
|
382
|
-
}
|
|
383
|
-
else if (scalarData instanceof Int16Array) {
|
|
384
|
-
type = 'Int16Array';
|
|
385
|
-
}
|
|
386
|
-
else {
|
|
387
|
-
throw new Error('Unsupported array type');
|
|
388
|
-
}
|
|
389
|
-
const totalNumFrames = this.imageIds.length;
|
|
390
|
-
const autoRenderOnLoad = true;
|
|
391
|
-
const autoRenderPercentage = 2;
|
|
392
|
-
let reRenderFraction;
|
|
393
|
-
let reRenderTarget;
|
|
394
|
-
if (autoRenderOnLoad) {
|
|
395
|
-
reRenderFraction = totalNumFrames * (autoRenderPercentage / 100);
|
|
396
|
-
reRenderTarget = reRenderFraction;
|
|
397
|
-
}
|
|
398
|
-
function callLoadStatusCallback(evt) {
|
|
399
|
-
if (autoRenderOnLoad) {
|
|
400
|
-
if (evt.framesProcessed > reRenderTarget ||
|
|
401
|
-
evt.framesProcessed === evt.totalNumFrames) {
|
|
402
|
-
reRenderTarget += reRenderFraction;
|
|
403
|
-
helpers_autoLoad(volumeId);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
if (evt.framesProcessed === evt.totalNumFrames) {
|
|
407
|
-
loadStatus.callbacks.forEach((callback) => callback(evt));
|
|
408
|
-
const eventDetail = {
|
|
409
|
-
FrameOfReferenceUID,
|
|
410
|
-
volumeId: volumeId,
|
|
411
|
-
};
|
|
412
|
-
(0,esm.triggerEvent)(esm.eventTarget, esm.Enums.Events.IMAGE_VOLUME_LOADING_COMPLETED, eventDetail);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
const updateTextureAndTriggerEvents = (volume, imageIdIndex, imageId) => {
|
|
416
|
-
const frameIndex = this._imageIdIndexToFrameIndex(imageIdIndex);
|
|
417
|
-
cachedFrames[imageIdIndex] = true;
|
|
418
|
-
this.framesLoaded++;
|
|
419
|
-
this.framesProcessed++;
|
|
420
|
-
vtkOpenGLTexture.setUpdatedFrame(frameIndex);
|
|
421
|
-
imageData.modified();
|
|
422
|
-
const eventDetail = {
|
|
423
|
-
FrameOfReferenceUID,
|
|
424
|
-
imageVolume: volume,
|
|
425
|
-
};
|
|
426
|
-
(0,esm.triggerEvent)(esm.eventTarget, esm.Enums.Events.IMAGE_VOLUME_MODIFIED, eventDetail);
|
|
427
|
-
if (this.framesProcessed === totalNumFrames) {
|
|
428
|
-
loadStatus.loaded = true;
|
|
429
|
-
loadStatus.loading = false;
|
|
430
|
-
callLoadStatusCallback({
|
|
431
|
-
success: true,
|
|
432
|
-
imageIdIndex,
|
|
433
|
-
imageId,
|
|
434
|
-
framesLoaded: this.framesLoaded,
|
|
435
|
-
framesProcessed: this.framesProcessed,
|
|
436
|
-
numFrames,
|
|
437
|
-
totalNumFrames,
|
|
438
|
-
});
|
|
439
|
-
loadStatus.callbacks = [];
|
|
440
|
-
}
|
|
441
|
-
else {
|
|
442
|
-
callLoadStatusCallback({
|
|
443
|
-
success: true,
|
|
444
|
-
imageIdIndex,
|
|
445
|
-
imageId,
|
|
446
|
-
framesLoaded: this.framesLoaded,
|
|
447
|
-
framesProcessed: this.framesProcessed,
|
|
448
|
-
numFrames,
|
|
449
|
-
totalNumFrames,
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
};
|
|
453
|
-
const successCallback = (imageIdIndex, imageId, scalingParameters) => {
|
|
454
|
-
const frameIndex = this._imageIdIndexToFrameIndex(imageIdIndex);
|
|
455
|
-
const cachedImage = esm.cache.getCachedImageBasedOnImageURI(imageId);
|
|
456
|
-
const cachedVolume = esm.cache.getVolumeContainingImageId(imageId);
|
|
457
|
-
if (loadStatus.cancelled) {
|
|
458
|
-
console.warn('volume load cancelled, returning for imageIdIndex: ', imageIdIndex);
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
if (!cachedImage?.image &&
|
|
462
|
-
!(cachedVolume && cachedVolume.volume !== this)) {
|
|
463
|
-
return updateTextureAndTriggerEvents(this, imageIdIndex, imageId);
|
|
464
|
-
}
|
|
465
|
-
const isFromImageCache = !!cachedImage;
|
|
466
|
-
const cachedImageOrVolume = cachedImage || cachedVolume.volume;
|
|
467
|
-
this.handleImageComingFromCache(cachedImageOrVolume, isFromImageCache, scalingParameters, scalarData, frameIndex, arrayBuffer, updateTextureAndTriggerEvents, imageIdIndex, imageId, errorCallback);
|
|
468
|
-
};
|
|
469
|
-
function errorCallback(error, imageIdIndex, imageId) {
|
|
470
|
-
this.framesProcessed++;
|
|
471
|
-
if (this.framesProcessed === totalNumFrames) {
|
|
472
|
-
loadStatus.loaded = true;
|
|
473
|
-
loadStatus.loading = false;
|
|
474
|
-
callLoadStatusCallback({
|
|
475
|
-
success: false,
|
|
476
|
-
imageId,
|
|
477
|
-
imageIdIndex,
|
|
478
|
-
error,
|
|
479
|
-
framesLoaded: this.framesLoaded,
|
|
480
|
-
framesProcessed: this.framesProcessed,
|
|
481
|
-
numFrames,
|
|
482
|
-
totalNumFrames,
|
|
483
|
-
});
|
|
484
|
-
loadStatus.callbacks = [];
|
|
485
|
-
}
|
|
486
|
-
else {
|
|
487
|
-
callLoadStatusCallback({
|
|
488
|
-
success: false,
|
|
489
|
-
imageId,
|
|
490
|
-
imageIdIndex,
|
|
491
|
-
error,
|
|
492
|
-
framesLoaded: this.framesLoaded,
|
|
493
|
-
framesProcessed: this.framesProcessed,
|
|
494
|
-
numFrames,
|
|
495
|
-
totalNumFrames,
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
const eventDetail = {
|
|
499
|
-
error,
|
|
500
|
-
imageIdIndex,
|
|
501
|
-
imageId,
|
|
502
|
-
};
|
|
503
|
-
(0,esm.triggerEvent)(esm.eventTarget, esm.Enums.Events.IMAGE_LOAD_ERROR, eventDetail);
|
|
504
|
-
}
|
|
505
|
-
function handleArrayBufferLoad(scalarData, image, options) {
|
|
506
|
-
if (!(scalarData.buffer instanceof ArrayBuffer)) {
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
const offset = options.targetBuffer.offset;
|
|
510
|
-
const length = options.targetBuffer.length;
|
|
511
|
-
const pixelData = image.pixelData
|
|
512
|
-
? image.pixelData
|
|
513
|
-
: image.getPixelData();
|
|
514
|
-
try {
|
|
515
|
-
if (scalarData instanceof Float32Array) {
|
|
516
|
-
const bytesInFloat = 4;
|
|
517
|
-
const floatView = new Float32Array(pixelData);
|
|
518
|
-
if (floatView.length !== length) {
|
|
519
|
-
throw 'Error pixelData length does not match frame length';
|
|
520
|
-
}
|
|
521
|
-
scalarData.set(floatView, offset / bytesInFloat);
|
|
522
|
-
}
|
|
523
|
-
if (scalarData instanceof Int16Array) {
|
|
524
|
-
const bytesInInt16 = 2;
|
|
525
|
-
const intView = new Int16Array(pixelData);
|
|
526
|
-
if (intView.length !== length) {
|
|
527
|
-
throw 'Error pixelData length does not match frame length';
|
|
528
|
-
}
|
|
529
|
-
scalarData.set(intView, offset / bytesInInt16);
|
|
530
|
-
}
|
|
531
|
-
if (scalarData instanceof Uint16Array) {
|
|
532
|
-
const bytesInUint16 = 2;
|
|
533
|
-
const intView = new Uint16Array(pixelData);
|
|
534
|
-
if (intView.length !== length) {
|
|
535
|
-
throw 'Error pixelData length does not match frame length';
|
|
536
|
-
}
|
|
537
|
-
scalarData.set(intView, offset / bytesInUint16);
|
|
538
|
-
}
|
|
539
|
-
if (scalarData instanceof Uint8Array) {
|
|
540
|
-
const bytesInUint8 = 1;
|
|
541
|
-
const intView = new Uint8Array(pixelData);
|
|
542
|
-
if (intView.length !== length) {
|
|
543
|
-
throw 'Error pixelData length does not match frame length';
|
|
544
|
-
}
|
|
545
|
-
scalarData.set(intView, offset / bytesInUint8);
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
catch (e) {
|
|
549
|
-
console.error(e);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
const requests = imageIds.map((imageId, frameIndex) => {
|
|
553
|
-
const imageIdIndex = this.getImageIdIndex(imageId);
|
|
554
|
-
if (cachedFrames[imageIdIndex]) {
|
|
555
|
-
this.framesLoaded++;
|
|
556
|
-
this.framesProcessed++;
|
|
557
|
-
return;
|
|
558
|
-
}
|
|
559
|
-
const modalityLutModule = esm.metaData.get('modalityLutModule', imageId) || {};
|
|
560
|
-
const generalSeriesModule = esm.metaData.get('generalSeriesModule', imageId) || {};
|
|
561
|
-
const scalingParameters = {
|
|
562
|
-
rescaleSlope: modalityLutModule.rescaleSlope,
|
|
563
|
-
rescaleIntercept: modalityLutModule.rescaleIntercept,
|
|
564
|
-
modality: generalSeriesModule.modality,
|
|
565
|
-
};
|
|
566
|
-
if (scalingParameters.modality === 'PT') {
|
|
567
|
-
const suvFactor = esm.metaData.get('scalingModule', imageId);
|
|
568
|
-
if (suvFactor) {
|
|
569
|
-
this._addScalingToVolume(suvFactor);
|
|
570
|
-
scalingParameters.suvbw = suvFactor.suvbw;
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
const isSlopeAndInterceptNumbers = typeof scalingParameters.rescaleSlope === 'number' &&
|
|
574
|
-
typeof scalingParameters.rescaleIntercept === 'number';
|
|
575
|
-
this.isPreScaled = isSlopeAndInterceptNumbers;
|
|
576
|
-
const options = {
|
|
577
|
-
targetBuffer: {
|
|
578
|
-
arrayBuffer: arrayBuffer instanceof ArrayBuffer ? undefined : arrayBuffer,
|
|
579
|
-
offset: frameIndex * lengthInBytes,
|
|
580
|
-
length,
|
|
581
|
-
type,
|
|
582
|
-
},
|
|
583
|
-
skipCreateImage: true,
|
|
584
|
-
preScale: {
|
|
585
|
-
enabled: true,
|
|
586
|
-
scalingParameters,
|
|
587
|
-
},
|
|
588
|
-
transferPixelData: true,
|
|
589
|
-
};
|
|
590
|
-
const callLoadImage = (imageId, imageIdIndex, options) => {
|
|
591
|
-
return esm.imageLoader.loadImage(imageId, options).then((image) => {
|
|
592
|
-
handleArrayBufferLoad(scalarData, image, options);
|
|
593
|
-
successCallback(imageIdIndex, imageId, scalingParameters);
|
|
594
|
-
}, (error) => {
|
|
595
|
-
errorCallback.call(this, error, imageIdIndex, imageId);
|
|
596
|
-
});
|
|
597
|
-
};
|
|
598
|
-
return {
|
|
599
|
-
callLoadImage,
|
|
600
|
-
imageId,
|
|
601
|
-
imageIdIndex,
|
|
602
|
-
options,
|
|
603
|
-
priority,
|
|
604
|
-
requestType,
|
|
605
|
-
additionalDetails: {
|
|
606
|
-
volumeId: this.volumeId,
|
|
607
|
-
},
|
|
608
|
-
};
|
|
609
|
-
});
|
|
610
|
-
return requests;
|
|
375
|
+
this._prefetchImageIds();
|
|
611
376
|
};
|
|
612
377
|
this.imageIds = streamingProperties.imageIds;
|
|
613
378
|
this.loadStatus = streamingProperties.loadStatus;
|
|
@@ -691,7 +456,215 @@ class BaseStreamingImageVolume_BaseStreamingImageVolume extends esm.ImageVolume
|
|
|
691
456
|
clearLoadCallbacks() {
|
|
692
457
|
this.loadStatus.callbacks = [];
|
|
693
458
|
}
|
|
694
|
-
|
|
459
|
+
callLoadStatusCallback(evt) {
|
|
460
|
+
const { framesUpdated, framesProcessed, totalNumFrames } = evt;
|
|
461
|
+
const { volumeId, reRenderFraction, loadStatus, metadata } = this;
|
|
462
|
+
const { FrameOfReferenceUID } = metadata;
|
|
463
|
+
if (this.autoRenderOnLoad) {
|
|
464
|
+
if (framesUpdated > this.reRenderTarget ||
|
|
465
|
+
framesProcessed === totalNumFrames) {
|
|
466
|
+
this.reRenderTarget += reRenderFraction;
|
|
467
|
+
helpers_autoLoad(volumeId);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (framesProcessed === totalNumFrames) {
|
|
471
|
+
loadStatus.callbacks.forEach((callback) => callback(evt));
|
|
472
|
+
const eventDetail = {
|
|
473
|
+
FrameOfReferenceUID,
|
|
474
|
+
volumeId: volumeId,
|
|
475
|
+
};
|
|
476
|
+
(0,esm.triggerEvent)(esm.eventTarget, esm.Enums.Events.IMAGE_VOLUME_LOADING_COMPLETED, eventDetail);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
updateTextureAndTriggerEvents(imageIdIndex, imageId, imageQualityStatus = ImageQualityStatus.FULL_RESOLUTION) {
|
|
480
|
+
const frameIndex = this._imageIdIndexToFrameIndex(imageIdIndex);
|
|
481
|
+
const { cachedFrames, numFrames, totalNumFrames } = this;
|
|
482
|
+
const { FrameOfReferenceUID } = this.metadata;
|
|
483
|
+
const currentStatus = cachedFrames[frameIndex];
|
|
484
|
+
if (currentStatus > imageQualityStatus) {
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
if (cachedFrames[frameIndex] === ImageQualityStatus.FULL_RESOLUTION) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
const complete = imageQualityStatus === ImageQualityStatus.FULL_RESOLUTION;
|
|
491
|
+
cachedFrames[imageIdIndex] = imageQualityStatus;
|
|
492
|
+
this.framesUpdated++;
|
|
493
|
+
if (complete) {
|
|
494
|
+
this.framesLoaded++;
|
|
495
|
+
this.framesProcessed++;
|
|
496
|
+
}
|
|
497
|
+
this.vtkOpenGLTexture.setUpdatedFrame(frameIndex);
|
|
498
|
+
this.imageData.modified();
|
|
499
|
+
const eventDetail = {
|
|
500
|
+
FrameOfReferenceUID,
|
|
501
|
+
imageVolume: this,
|
|
502
|
+
};
|
|
503
|
+
(0,esm.triggerEvent)(esm.eventTarget, esm.Enums.Events.IMAGE_VOLUME_MODIFIED, eventDetail);
|
|
504
|
+
if (complete && this.framesProcessed === this.totalNumFrames) {
|
|
505
|
+
this.loadStatus.loaded = true;
|
|
506
|
+
this.loadStatus.loading = false;
|
|
507
|
+
}
|
|
508
|
+
this.callLoadStatusCallback({
|
|
509
|
+
success: true,
|
|
510
|
+
imageIdIndex,
|
|
511
|
+
imageId,
|
|
512
|
+
framesLoaded: this.framesLoaded,
|
|
513
|
+
framesProcessed: this.framesProcessed,
|
|
514
|
+
framesUpdated: this.framesUpdated,
|
|
515
|
+
numFrames,
|
|
516
|
+
totalNumFrames,
|
|
517
|
+
complete,
|
|
518
|
+
imageQualityStatus,
|
|
519
|
+
});
|
|
520
|
+
if (this.loadStatus.loaded) {
|
|
521
|
+
this.loadStatus.callbacks = [];
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
successCallback(imageId, image) {
|
|
525
|
+
const imageIdIndex = this.getImageIdIndex(imageId);
|
|
526
|
+
const options = this.getLoaderImageOptions(imageId);
|
|
527
|
+
const scalarData = this._getScalarDataByImageIdIndex(imageIdIndex);
|
|
528
|
+
handleArrayBufferLoad(scalarData, image, options);
|
|
529
|
+
const { scalingParameters } = image.preScale || {};
|
|
530
|
+
const { imageQualityStatus } = image;
|
|
531
|
+
const frameIndex = this._imageIdIndexToFrameIndex(imageIdIndex);
|
|
532
|
+
const cachedImage = esm.cache.getCachedImageBasedOnImageURI(imageId);
|
|
533
|
+
const cachedVolume = esm.cache.getVolumeContainingImageId(imageId);
|
|
534
|
+
if (this.loadStatus.cancelled) {
|
|
535
|
+
console.warn('volume load cancelled, returning for imageIdIndex: ', imageIdIndex);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
if (!cachedImage && !(cachedVolume && cachedVolume.volume !== this)) {
|
|
539
|
+
return this.updateTextureAndTriggerEvents(imageIdIndex, imageId, imageQualityStatus);
|
|
540
|
+
}
|
|
541
|
+
const isFromImageCache = !!cachedImage;
|
|
542
|
+
const cachedImageOrVolume = cachedImage || cachedVolume.volume;
|
|
543
|
+
this.handleImageComingFromCache(cachedImageOrVolume, isFromImageCache, scalingParameters, scalarData, frameIndex, scalarData.buffer, imageIdIndex, imageId);
|
|
544
|
+
}
|
|
545
|
+
errorCallback(imageId, permanent, error) {
|
|
546
|
+
if (!permanent) {
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
const { totalNumFrames, numFrames } = this;
|
|
550
|
+
const imageIdIndex = this.getImageIdIndex(imageId);
|
|
551
|
+
this.framesProcessed++;
|
|
552
|
+
if (this.framesProcessed === totalNumFrames) {
|
|
553
|
+
this.loadStatus.loaded = true;
|
|
554
|
+
this.loadStatus.loading = false;
|
|
555
|
+
}
|
|
556
|
+
this.callLoadStatusCallback({
|
|
557
|
+
success: false,
|
|
558
|
+
imageId,
|
|
559
|
+
imageIdIndex,
|
|
560
|
+
error,
|
|
561
|
+
framesLoaded: this.framesLoaded,
|
|
562
|
+
framesProcessed: this.framesProcessed,
|
|
563
|
+
framesUpdated: this.framesUpdated,
|
|
564
|
+
numFrames,
|
|
565
|
+
totalNumFrames,
|
|
566
|
+
});
|
|
567
|
+
if (this.loadStatus.loaded) {
|
|
568
|
+
this.loadStatus.callbacks = [];
|
|
569
|
+
}
|
|
570
|
+
const eventDetail = {
|
|
571
|
+
error,
|
|
572
|
+
imageIdIndex,
|
|
573
|
+
imageId,
|
|
574
|
+
};
|
|
575
|
+
(0,esm.triggerEvent)(esm.eventTarget, esm.Enums.Events.IMAGE_LOAD_ERROR, eventDetail);
|
|
576
|
+
}
|
|
577
|
+
getLoaderImageOptions(imageId) {
|
|
578
|
+
const { transferSyntaxUID: transferSyntaxUID } = esm.metaData.get('transferSyntax', imageId) || {};
|
|
579
|
+
const imagePlaneModule = esm.metaData.get('imagePlaneModule', imageId) || {};
|
|
580
|
+
const { rows, columns } = imagePlaneModule;
|
|
581
|
+
const imageIdIndex = this.getImageIdIndex(imageId);
|
|
582
|
+
const scalarData = this._getScalarDataByImageIdIndex(imageIdIndex);
|
|
583
|
+
if (!scalarData) {
|
|
584
|
+
return null;
|
|
585
|
+
}
|
|
586
|
+
const arrayBuffer = scalarData.buffer;
|
|
587
|
+
const { type, length, lengthInBytes } = getScalarDataType(scalarData, this.numFrames);
|
|
588
|
+
const modalityLutModule = esm.metaData.get('modalityLutModule', imageId) || {};
|
|
589
|
+
const generalSeriesModule = esm.metaData.get('generalSeriesModule', imageId) || {};
|
|
590
|
+
const scalingParameters = {
|
|
591
|
+
rescaleSlope: modalityLutModule.rescaleSlope,
|
|
592
|
+
rescaleIntercept: modalityLutModule.rescaleIntercept,
|
|
593
|
+
modality: generalSeriesModule.modality,
|
|
594
|
+
};
|
|
595
|
+
if (scalingParameters.modality === 'PT') {
|
|
596
|
+
const suvFactor = esm.metaData.get('scalingModule', imageId);
|
|
597
|
+
if (suvFactor) {
|
|
598
|
+
this._addScalingToVolume(suvFactor);
|
|
599
|
+
scalingParameters.suvbw = suvFactor.suvbw;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
const isSlopeAndInterceptNumbers = typeof scalingParameters.rescaleSlope === 'number' &&
|
|
603
|
+
typeof scalingParameters.rescaleIntercept === 'number';
|
|
604
|
+
this.isPreScaled = isSlopeAndInterceptNumbers;
|
|
605
|
+
const frameIndex = this._imageIdIndexToFrameIndex(imageIdIndex);
|
|
606
|
+
return {
|
|
607
|
+
targetBuffer: {
|
|
608
|
+
arrayBuffer: arrayBuffer instanceof ArrayBuffer ? undefined : arrayBuffer,
|
|
609
|
+
offset: frameIndex * lengthInBytes,
|
|
610
|
+
length,
|
|
611
|
+
type,
|
|
612
|
+
rows,
|
|
613
|
+
columns,
|
|
614
|
+
},
|
|
615
|
+
skipCreateImage: true,
|
|
616
|
+
preScale: {
|
|
617
|
+
enabled: true,
|
|
618
|
+
scalingParameters,
|
|
619
|
+
},
|
|
620
|
+
transferPixelData: true,
|
|
621
|
+
transferSyntaxUID,
|
|
622
|
+
loader: esm.imageLoader.loadImage,
|
|
623
|
+
additionalDetails: {
|
|
624
|
+
imageId,
|
|
625
|
+
imageIdIndex,
|
|
626
|
+
volumeId: this.volumeId,
|
|
627
|
+
},
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
callLoadImage(imageId, imageIdIndex, options) {
|
|
631
|
+
const { cachedFrames } = this;
|
|
632
|
+
if (cachedFrames[imageIdIndex] === ImageQualityStatus.FULL_RESOLUTION) {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
const uncompressedIterator = ProgressiveIterator.as(esm.imageLoader.loadImage(imageId, options));
|
|
636
|
+
return uncompressedIterator.forEach((image) => {
|
|
637
|
+
this.successCallback(imageId, image);
|
|
638
|
+
}, this.errorCallback.bind(this, imageIdIndex, imageId));
|
|
639
|
+
}
|
|
640
|
+
getImageIdsRequests(imageIds, priorityDefault) {
|
|
641
|
+
this.totalNumFrames = this.imageIds.length;
|
|
642
|
+
const autoRenderPercentage = 2;
|
|
643
|
+
if (this.autoRenderOnLoad) {
|
|
644
|
+
this.reRenderFraction =
|
|
645
|
+
this.totalNumFrames * (autoRenderPercentage / 100);
|
|
646
|
+
this.reRenderTarget = this.reRenderFraction;
|
|
647
|
+
}
|
|
648
|
+
const requests = imageIds.map((imageId) => {
|
|
649
|
+
const imageIdIndex = this.getImageIdIndex(imageId);
|
|
650
|
+
const requestType = requestTypeDefault;
|
|
651
|
+
const priority = priorityDefault;
|
|
652
|
+
const options = this.getLoaderImageOptions(imageId);
|
|
653
|
+
return {
|
|
654
|
+
callLoadImage: this.callLoadImage.bind(this),
|
|
655
|
+
imageId,
|
|
656
|
+
imageIdIndex,
|
|
657
|
+
options,
|
|
658
|
+
priority,
|
|
659
|
+
requestType,
|
|
660
|
+
additionalDetails: {
|
|
661
|
+
volumeId: this.volumeId,
|
|
662
|
+
},
|
|
663
|
+
};
|
|
664
|
+
});
|
|
665
|
+
return requests;
|
|
666
|
+
}
|
|
667
|
+
handleImageComingFromCache(cachedImageOrVolume, isFromImageCache, scalingParameters, scalarData, frameIndex, arrayBuffer, imageIdIndex, imageId) {
|
|
695
668
|
const imageLoadObject = isFromImageCache
|
|
696
669
|
? cachedImageOrVolume.imageLoadObject
|
|
697
670
|
: cachedImageOrVolume.convertToCornerstoneImage(imageId, imageIdIndex);
|
|
@@ -707,18 +680,21 @@ class BaseStreamingImageVolume_BaseStreamingImageVolume extends esm.ImageVolume
|
|
|
707
680
|
}
|
|
708
681
|
const volumeBufferView = new TypedArray(arrayBuffer, byteOffset, pixelsPerImage);
|
|
709
682
|
volumeBufferView.set(imageScalarData);
|
|
710
|
-
updateTextureAndTriggerEvents(
|
|
683
|
+
this.updateTextureAndTriggerEvents(imageIdIndex, imageId, cachedImage.imageQualityStatus);
|
|
711
684
|
})
|
|
712
685
|
.catch((err) => {
|
|
713
|
-
errorCallback
|
|
686
|
+
this.errorCallback(imageId, true, err);
|
|
714
687
|
});
|
|
715
688
|
}
|
|
716
689
|
getImageLoadRequests(_priority) {
|
|
717
690
|
throw new Error('Abstract method');
|
|
718
691
|
}
|
|
719
|
-
|
|
692
|
+
getImageIdsToLoad() {
|
|
693
|
+
throw new Error('Abstract method');
|
|
694
|
+
}
|
|
695
|
+
loadImages(imageIds, listener) {
|
|
720
696
|
this.loadStatus.loading = true;
|
|
721
|
-
const requests = this.getImageLoadRequests(
|
|
697
|
+
const requests = this.getImageLoadRequests(5);
|
|
722
698
|
requests.reverse().forEach((request) => {
|
|
723
699
|
if (!request) {
|
|
724
700
|
return;
|
|
@@ -726,6 +702,22 @@ class BaseStreamingImageVolume_BaseStreamingImageVolume extends esm.ImageVolume
|
|
|
726
702
|
const { callLoadImage, imageId, imageIdIndex, options, priority, requestType, additionalDetails, } = request;
|
|
727
703
|
esm.imageLoadPoolManager.addRequest(callLoadImage.bind(this, imageId, imageIdIndex, options), requestType, additionalDetails, priority);
|
|
728
704
|
});
|
|
705
|
+
return Promise.resolve(true);
|
|
706
|
+
}
|
|
707
|
+
_prefetchImageIds() {
|
|
708
|
+
this.loadStatus.loading = true;
|
|
709
|
+
const imageIds = [...this.getImageIdsToLoad()];
|
|
710
|
+
imageIds.reverse();
|
|
711
|
+
this.totalNumFrames = this.imageIds.length;
|
|
712
|
+
const autoRenderPercentage = 2;
|
|
713
|
+
if (this.autoRenderOnLoad) {
|
|
714
|
+
this.reRenderFraction =
|
|
715
|
+
this.totalNumFrames * (autoRenderPercentage / 100);
|
|
716
|
+
this.reRenderTarget = this.reRenderFraction;
|
|
717
|
+
}
|
|
718
|
+
return this.imagesLoader.loadImages(imageIds, this).catch((e) => {
|
|
719
|
+
console.debug('progressive loading failed to complete', e);
|
|
720
|
+
});
|
|
729
721
|
}
|
|
730
722
|
_scaleIfNecessary(image, scalingParametersToUse) {
|
|
731
723
|
const imageIsAlreadyScaled = image.preScale?.scaled;
|
|
@@ -877,20 +869,94 @@ class BaseStreamingImageVolume_BaseStreamingImageVolume extends esm.ImageVolume
|
|
|
877
869
|
}
|
|
878
870
|
}
|
|
879
871
|
}
|
|
872
|
+
function getScalarDataType(scalarData, numFrames) {
|
|
873
|
+
let type, byteSize;
|
|
874
|
+
if (scalarData instanceof Uint8Array) {
|
|
875
|
+
type = 'Uint8Array';
|
|
876
|
+
byteSize = 1;
|
|
877
|
+
}
|
|
878
|
+
else if (scalarData instanceof Float32Array) {
|
|
879
|
+
type = 'Float32Array';
|
|
880
|
+
byteSize = 4;
|
|
881
|
+
}
|
|
882
|
+
else if (scalarData instanceof Uint16Array) {
|
|
883
|
+
type = 'Uint16Array';
|
|
884
|
+
byteSize = 2;
|
|
885
|
+
}
|
|
886
|
+
else if (scalarData instanceof Int16Array) {
|
|
887
|
+
type = 'Int16Array';
|
|
888
|
+
byteSize = 2;
|
|
889
|
+
}
|
|
890
|
+
else {
|
|
891
|
+
throw new Error('Unsupported array type');
|
|
892
|
+
}
|
|
893
|
+
const length = scalarData.length / numFrames;
|
|
894
|
+
const lengthInBytes = length * byteSize;
|
|
895
|
+
return { type, byteSize, length, lengthInBytes };
|
|
896
|
+
}
|
|
897
|
+
function handleArrayBufferLoad(scalarData, image, options) {
|
|
898
|
+
if (!(scalarData.buffer instanceof ArrayBuffer)) {
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
const offset = options.targetBuffer.offset;
|
|
902
|
+
const length = options.targetBuffer.length;
|
|
903
|
+
const pixelData = image.pixelData ? image.pixelData : image.getPixelData();
|
|
904
|
+
try {
|
|
905
|
+
if (scalarData instanceof Float32Array) {
|
|
906
|
+
const bytesInFloat = 4;
|
|
907
|
+
const floatView = new Float32Array(pixelData);
|
|
908
|
+
if (floatView.length !== length) {
|
|
909
|
+
throw 'Error pixelData length does not match frame length';
|
|
910
|
+
}
|
|
911
|
+
scalarData.set(floatView, offset / bytesInFloat);
|
|
912
|
+
}
|
|
913
|
+
if (scalarData instanceof Int16Array) {
|
|
914
|
+
const bytesInInt16 = 2;
|
|
915
|
+
const intView = new Int16Array(pixelData);
|
|
916
|
+
if (intView.length !== length) {
|
|
917
|
+
throw 'Error pixelData length does not match frame length';
|
|
918
|
+
}
|
|
919
|
+
scalarData.set(intView, offset / bytesInInt16);
|
|
920
|
+
}
|
|
921
|
+
if (scalarData instanceof Uint16Array) {
|
|
922
|
+
const bytesInUint16 = 2;
|
|
923
|
+
const intView = new Uint16Array(pixelData);
|
|
924
|
+
if (intView.length !== length) {
|
|
925
|
+
throw 'Error pixelData length does not match frame length';
|
|
926
|
+
}
|
|
927
|
+
scalarData.set(intView, offset / bytesInUint16);
|
|
928
|
+
}
|
|
929
|
+
if (scalarData instanceof Uint8Array) {
|
|
930
|
+
const bytesInUint8 = 1;
|
|
931
|
+
const intView = new Uint8Array(pixelData);
|
|
932
|
+
if (intView.length !== length) {
|
|
933
|
+
throw 'Error pixelData length does not match frame length';
|
|
934
|
+
}
|
|
935
|
+
scalarData.set(intView, offset / bytesInUint8);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
catch (e) {
|
|
939
|
+
console.error(e);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
880
942
|
|
|
881
943
|
;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/streaming-image-volume-loader/dist/esm/StreamingImageVolume.js
|
|
882
944
|
|
|
883
945
|
class StreamingImageVolume extends BaseStreamingImageVolume_BaseStreamingImageVolume {
|
|
884
946
|
constructor(imageVolumeProperties, streamingProperties) {
|
|
885
947
|
super(imageVolumeProperties, streamingProperties);
|
|
948
|
+
this.getImageIdsToLoad = () => {
|
|
949
|
+
const { imageIds } = this;
|
|
950
|
+
this.numFrames = imageIds.length;
|
|
951
|
+
return imageIds;
|
|
952
|
+
};
|
|
886
953
|
}
|
|
887
954
|
getScalarData() {
|
|
888
955
|
return this.scalarData;
|
|
889
956
|
}
|
|
890
957
|
getImageLoadRequests(priority) {
|
|
891
958
|
const { imageIds } = this;
|
|
892
|
-
|
|
893
|
-
return this.getImageIdsRequests(imageIds, scalarData, priority);
|
|
959
|
+
return this.getImageIdsRequests(imageIds, priority);
|
|
894
960
|
}
|
|
895
961
|
}
|
|
896
962
|
|
|
@@ -929,7 +995,7 @@ function cornerstoneStreamingImageVolumeLoader(volumeId, options) {
|
|
|
929
995
|
});
|
|
930
996
|
})).catch(console.error);
|
|
931
997
|
}
|
|
932
|
-
const { imageIds } = options;
|
|
998
|
+
const { imageIds, progressiveRendering } = options;
|
|
933
999
|
const volumeMetadata = makeVolumeMetadata_makeVolumeMetadata(imageIds);
|
|
934
1000
|
const imageIdIndex = Math.floor(imageIds.length / 2);
|
|
935
1001
|
const imageId = imageIds[imageIdIndex];
|
|
@@ -1071,8 +1137,8 @@ class StreamingDynamicImageVolume_StreamingDynamicImageVolume extends (/* unused
|
|
|
1071
1137
|
super(imageVolumeProperties, streamingProperties);
|
|
1072
1138
|
this._timePointIndex = 0;
|
|
1073
1139
|
this._getTimePointRequests = (timePoint, priority) => {
|
|
1074
|
-
const { imageIds
|
|
1075
|
-
return this.getImageIdsRequests(imageIds,
|
|
1140
|
+
const { imageIds } = timePoint;
|
|
1141
|
+
return this.getImageIdsRequests(imageIds, priority);
|
|
1076
1142
|
};
|
|
1077
1143
|
this._getTimePointsRequests = (priority) => {
|
|
1078
1144
|
const timePoints = this._getTimePointsToLoad();
|
|
@@ -1084,7 +1150,7 @@ class StreamingDynamicImageVolume_StreamingDynamicImageVolume extends (/* unused
|
|
|
1084
1150
|
return timePointsRequests;
|
|
1085
1151
|
};
|
|
1086
1152
|
this.getImageLoadRequests = (priority) => {
|
|
1087
|
-
return this._getTimePointsRequests(priority)
|
|
1153
|
+
return this._getTimePointsRequests(priority);
|
|
1088
1154
|
};
|
|
1089
1155
|
this._numTimePoints = this.scalarData.length;
|
|
1090
1156
|
this._timePoints = this._getTimePointsData();
|
|
@@ -1128,6 +1194,15 @@ class StreamingDynamicImageVolume_StreamingDynamicImageVolume extends (/* unused
|
|
|
1128
1194
|
}
|
|
1129
1195
|
return timePointsToLoad;
|
|
1130
1196
|
}
|
|
1197
|
+
getImageIdsToLoad() {
|
|
1198
|
+
const timePoints = this._getTimePointsToLoad();
|
|
1199
|
+
let imageIds = [];
|
|
1200
|
+
timePoints.forEach((timePoint) => {
|
|
1201
|
+
const { imageIds: timePointIds } = timePoint;
|
|
1202
|
+
imageIds = imageIds.concat(timePointIds);
|
|
1203
|
+
});
|
|
1204
|
+
return imageIds;
|
|
1205
|
+
}
|
|
1131
1206
|
isDynamicVolume() {
|
|
1132
1207
|
return true;
|
|
1133
1208
|
}
|