ohif-viewer/extensions/dicom-video/src/getSopClassHandlerModule.js
Joe Boccanfuso 8eaa1877fd
fix(DICOM PDF and Video): fixes for local DICOM load and remote data sources (#3374)
* fix(DICOM PDF and Video)
- added retrieve.directURL for local DICOM load data source; it returns a data URL
- fixed various checks for video using transfer syntaxes and SOP class UID with number of frames
- added call to 'rendered' endpoint for those data sources that support it; others get BulkDataURI

* Added DOC (PDF) and OT (for video in particular) to list of non-image thumbnail modalities.

* Fixed broken e2e tests.
2023-05-10 12:42:48 -04:00

121 lines
3.4 KiB
JavaScript

import { SOPClassHandlerId } from './id';
import { utils } from '@ohif/core';
const SOP_CLASS_UIDS = {
VIDEO_MICROSCOPIC_IMAGE_STORAGE: '1.2.840.10008.5.1.4.1.1.77.1.2.1',
VIDEO_PHOTOGRAPHIC_IMAGE_STORAGE: '1.2.840.10008.5.1.4.1.1.77.1.4.1',
VIDEO_ENDOSCOPIC_IMAGE_STORAGE: '1.2.840.10008.5.1.4.1.1.77.1.1.1',
/** Need to use fallback, could be video or image */
SECONDARY_CAPTURE_IMAGE_STORAGE: '1.2.840.10008.5.1.4.1.1.7',
MULTIFRAME_TRUE_COLOR_SECONDARY_CAPTURE_IMAGE_STORAGE:
'1.2.840.10008.5.1.4.1.1.7.4',
};
const sopClassUids = Object.values(SOP_CLASS_UIDS);
const SupportedTransferSyntaxes = {
MPEG4_AVC_264_HIGH_PROFILE: '1.2.840.10008.1.2.4.102',
MPEG4_AVC_264_BD_COMPATIBLE_HIGH_PROFILE: '1.2.840.10008.1.2.4.103',
MPEG4_AVC_264_HIGH_PROFILE_FOR_2D_VIDEO: '1.2.840.10008.1.2.4.104',
MPEG4_AVC_264_HIGH_PROFILE_FOR_3D_VIDEO: '1.2.840.10008.1.2.4.105',
MPEG4_AVC_264_STEREO_HIGH_PROFILE: '1.2.840.10008.1.2.4.106',
HEVC_265_MAIN_PROFILE: '1.2.840.10008.1.2.4.107',
HEVC_265_MAIN_10_PROFILE: '1.2.840.10008.1.2.4.108',
};
const supportedTransferSyntaxUIDs = Object.values(SupportedTransferSyntaxes);
const _getDisplaySetsFromSeries = (
instances,
servicesManager,
extensionManager
) => {
const dataSource = extensionManager.getActiveDataSource()[0];
return instances
.filter(metadata => {
const tsuid =
metadata.AvailableTransferSyntaxUID ||
metadata.TransferSyntaxUID ||
metadata['00083002'];
if (supportedTransferSyntaxUIDs.includes(tsuid)) {
return true;
}
// Assume that an instance with certain SOPClassUID and
// with at least 90 frames (i.e. typically 3 seconds of video) is indeed a video.
return (
metadata.SOPClassUID ===
SOP_CLASS_UIDS.MULTIFRAME_TRUE_COLOR_SECONDARY_CAPTURE_IMAGE_STORAGE &&
metadata.NumberOfFrames >= 90
);
})
.map(instance => {
const {
Modality,
SOPInstanceUID,
SeriesDescription = 'VIDEO',
} = instance;
const {
SeriesNumber,
SeriesDate,
SeriesInstanceUID,
StudyInstanceUID,
NumberOfFrames,
} = instance;
const displaySet = {
//plugin: id,
Modality,
displaySetInstanceUID: utils.guid(),
SeriesDescription,
SeriesNumber,
SeriesDate,
SOPInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
SOPClassHandlerId,
referencedImages: null,
measurements: null,
videoUrl: dataSource.retrieve.directURL({
instance,
singlepart: 'video',
tag: 'PixelData',
}),
instances: [instance],
thumbnailSrc: dataSource.retrieve.directURL({
instance,
defaultPath: '/thumbnail',
defaultType: 'image/jpeg',
tag: 'Absent',
}),
isDerivedDisplaySet: true,
isLoaded: false,
sopClassUids,
numImageFrames: NumberOfFrames,
instance,
};
return displaySet;
});
};
export default function getSopClassHandlerModule({
servicesManager,
extensionManager,
}) {
const getDisplaySetsFromSeries = instances => {
return _getDisplaySetsFromSeries(
instances,
servicesManager,
extensionManager
);
};
return [
{
name: 'dicom-video',
sopClassUids,
getDisplaySetsFromSeries,
},
];
}