From 19e8af50c602cf3db218d41103333cfff999029d Mon Sep 17 00:00:00 2001 From: Forrest Date: Thu, 1 Aug 2024 15:56:25 -0400 Subject: [PATCH] fix(allocateImageFromChunks): support multi-frame --- src/core/dicomTags.ts | 1 + src/utils/allocateImageFromChunks.ts | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/core/dicomTags.ts b/src/core/dicomTags.ts index 0b09ec03..3a1ee6e0 100644 --- a/src/core/dicomTags.ts +++ b/src/core/dicomTags.ts @@ -32,6 +32,7 @@ const tags: Tag[] = [ { name: 'SamplesPerPixel', tag: '0028|0002' }, { name: 'RescaleIntercept', tag: '0028|1052' }, { name: 'RescaleSlope', tag: '0028|1053' }, + { name: 'NumberOfFrames', tag: '0028|0008' }, ]; export const TAG_TO_NAME = new Map(tags.map((t) => [t.tag, t.name])); diff --git a/src/utils/allocateImageFromChunks.ts b/src/utils/allocateImageFromChunks.ts index 4434b285..d1d16c88 100644 --- a/src/utils/allocateImageFromChunks.ts +++ b/src/utils/allocateImageFromChunks.ts @@ -5,6 +5,7 @@ import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData'; import { Vector3 } from '@kitware/vtk.js/types'; import { mat3, vec3 } from 'gl-matrix'; import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray'; +import { vtkWarningMacro } from '@kitware/vtk.js/macros'; const ImagePositionPatientTag = NAME_TO_TAG.get('ImagePositionPatient')!; const ImageOrientationPatientTag = NAME_TO_TAG.get('ImageOrientationPatient')!; @@ -16,6 +17,7 @@ const PixelRepresentationTag = NAME_TO_TAG.get('PixelRepresentation')!; const SamplesPerPixelTag = NAME_TO_TAG.get('SamplesPerPixel')!; const RescaleIntercept = NAME_TO_TAG.get('RescaleIntercept')!; const RescaleSlope = NAME_TO_TAG.get('RescaleSlope')!; +const NumberOfFrames = NAME_TO_TAG.get('NumberOfFrames')!; function toVec(s: Maybe): number[] | null { if (!s?.length) return null; @@ -84,8 +86,18 @@ export function allocateImageFromChunks(sortedChunks: Chunk[]) { const samplesPerPixel = Number(meta.get(SamplesPerPixelTag) ?? 1); const rescaleIntercept = Number(meta.get(RescaleIntercept) ?? 0); const rescaleSlope = Number(meta.get(RescaleSlope) ?? 1); + const numberOfFrames = meta.has(NumberOfFrames) + ? Number(meta.get(NumberOfFrames)) + : null; + + // If we have NumberOfFrames, chances are it's a multi-frame DICOM. + if (numberOfFrames !== null && sortedChunks.length > 1) { + vtkWarningMacro( + 'Found a multi-frame chunk in a group of chunks of size > 1' + ); + } - const slices = sortedChunks.length; + const slices = numberOfFrames === null ? sortedChunks.length : numberOfFrames; const TypedArrayCtor = getTypedArrayConstructor( bitsStored, pixelRepresentation,