UNPKG

@cornerstonejs/dicom-image-loader

Version:

Cornerstone Image Loader for DICOM WADO-URI and WADO-RS and Local file

142 lines (141 loc) 4.75 kB
import * as dicomParser from 'dicom-parser'; import { xhrRequest } from '../internal/index'; import dataSetFromPartialContent from './dataset-from-partial-content'; import { combineFrameInstanceDataset } from './combineFrameInstanceDataset'; import multiframeDataset from './retrieveMultiframeDataset'; import { loadedDataSets, purgeLoadedDataSets } from './loadedDataSets'; import { eventTarget, triggerEvent } from '@cornerstonejs/core'; let cacheSizeInBytes = 0; let promises = {}; function isLoaded(uri) { return loadedDataSets[uri] !== undefined; } function get(uri) { let dataSet; if (uri.includes('&frame=')) { const { frame, dataSet: multiframeDataSet } = multiframeDataset.retrieveMultiframeDataset(uri); dataSet = combineFrameInstanceDataset(frame, multiframeDataSet); } else if (loadedDataSets[uri]) { dataSet = loadedDataSets[uri].dataSet; } return dataSet; } function update(uri, dataSet) { const loadedDataSet = loadedDataSets[uri]; if (!loadedDataSet) { console.error(`No loaded dataSet for uri ${uri}`); return; } cacheSizeInBytes -= loadedDataSet.dataSet.byteArray.length; loadedDataSet.dataSet = dataSet; cacheSizeInBytes += dataSet.byteArray.length; triggerEvent(eventTarget, 'datasetscachechanged', { uri, action: 'updated', cacheInfo: getInfo(), }); } function load(uri, loadRequest = xhrRequest, imageId) { if (loadedDataSets[uri]) { return new Promise((resolve) => { loadedDataSets[uri].cacheCount++; resolve(loadedDataSets[uri].dataSet); }); } if (promises[uri]) { promises[uri].cacheCount++; return promises[uri]; } const loadDICOMPromise = loadRequest(uri, imageId); const promise = new Promise((resolve, reject) => { loadDICOMPromise .then(async function (dicomPart10AsArrayBuffer) { const partialContent = { isPartialContent: false, fileTotalLength: null, }; if (!(dicomPart10AsArrayBuffer instanceof ArrayBuffer)) { if (!dicomPart10AsArrayBuffer.arrayBuffer) { return reject(new Error('If not returning ArrayBuffer, must return object with `arrayBuffer` parameter')); } partialContent.isPartialContent = dicomPart10AsArrayBuffer.flags.isPartialContent; partialContent.fileTotalLength = dicomPart10AsArrayBuffer.flags.fileTotalLength; dicomPart10AsArrayBuffer = dicomPart10AsArrayBuffer.arrayBuffer; } const byteArray = new Uint8Array(dicomPart10AsArrayBuffer); let dataSet; try { if (partialContent.isPartialContent) { dataSet = await dataSetFromPartialContent(byteArray, loadRequest, { uri, imageId, fileTotalLength: partialContent.fileTotalLength, }); } else { dataSet = dicomParser.parseDicom(byteArray); } } catch (error) { return reject(error); } loadedDataSets[uri] = { dataSet, cacheCount: promise.cacheCount, }; cacheSizeInBytes += dataSet.byteArray.length; resolve(dataSet); triggerEvent(eventTarget, 'datasetscachechanged', { uri, action: 'loaded', cacheInfo: getInfo(), }); }, reject) .then(() => { delete promises[uri]; }, () => { delete promises[uri]; }); }); promise.cacheCount = 1; promises[uri] = promise; return promise; } function unload(uri) { if (loadedDataSets[uri]) { loadedDataSets[uri].cacheCount--; if (loadedDataSets[uri].cacheCount === 0) { cacheSizeInBytes -= loadedDataSets[uri].dataSet.byteArray.length; delete loadedDataSets[uri]; triggerEvent(eventTarget, 'datasetscachechanged', { uri, action: 'unloaded', cacheInfo: getInfo(), }); } } } export function getInfo() { return { cacheSizeInBytes, numberOfDataSetsCached: Object.keys(loadedDataSets).length, }; } function purge() { purgeLoadedDataSets(); promises = {}; cacheSizeInBytes = 0; } export default { isLoaded, load, unload, getInfo, purge, get, update, }; export { loadedDataSets };