@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
JavaScript
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 };