Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 1x | import { vec3 } from 'gl-matrix'; import { cache, utilities, Enums } from '@cornerstonejs/core'; import type { Types } from '@cornerstonejs/core'; const { createUint8SharedArray, createFloat32SharedArray } = utilities; function getVolumeInfo(imageIds: string[]) { const volumeMetadata = utilities.makeVolumeMetadata(imageIds); const { BitsAllocated, PixelRepresentation, PhotometricInterpretation, ImageOrientationPatient, PixelSpacing, Columns, Rows, } = volumeMetadata; const rowCosineVec = vec3.fromValues( ImageOrientationPatient[0], ImageOrientationPatient[1], ImageOrientationPatient[2] ); const colCosineVec = vec3.fromValues( ImageOrientationPatient[3], ImageOrientationPatient[4], ImageOrientationPatient[5] ); const scanAxisNormal = vec3.create(); vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec); const { zSpacing, origin, sortedImageIds } = utilities.sortImageIdsAndGetSpacing(imageIds, scanAxisNormal); const numFrames = imageIds.length; // Spacing goes [1] then [0], as [1] is column spacing (x) and [0] is row spacing (y) const spacing = <Types.Point3>[PixelSpacing[1], PixelSpacing[0], zSpacing]; const dimensions = <Types.Point3>[Columns, Rows, numFrames]; const direction = [ ...rowCosineVec, ...colCosineVec, ...scanAxisNormal, ] as Types.Mat3; const signed = PixelRepresentation === 1; // Check if it fits in the cache before we allocate data // TODO Improve this when we have support for more types // NOTE: We use 4 bytes per voxel as we are using Float32. const bytesPerVoxel = BitsAllocated === 16 ? 4 : 1; const sizeInBytesPerComponent = bytesPerVoxel * dimensions[0] * dimensions[1] * dimensions[2]; let numComponents = 1; if (PhotometricInterpretation === 'RGB') { numComponents = 3; } const sizeInBytes = sizeInBytesPerComponent * numComponents; // check if there is enough space in unallocated + image Cache const isCacheable = cache.isCacheable(sizeInBytes); if (!isCacheable) { throw new Error(Enums.Events.CACHE_SIZE_EXCEEDED); } cache.decacheIfNecessaryUntilBytesAvailable(sizeInBytes); let scalarData; switch (BitsAllocated) { case 8: if (signed) { throw new Error( '8 Bit signed images are not yet supported by this plugin.' ); } else { scalarData = createUint8SharedArray( dimensions[0] * dimensions[1] * dimensions[2] ); } break; case 16: scalarData = createFloat32SharedArray( dimensions[0] * dimensions[1] * dimensions[2] ); break; case 24: // hacky because we don't support alpha channel in dicom scalarData = createUint8SharedArray( dimensions[0] * dimensions[1] * dimensions[2] * numComponents ); break; } return { metadata: volumeMetadata, sortedImageIds, dimensions, spacing, origin, direction, scalarData, sizeInBytes, }; } export { getVolumeInfo, getVolumeInfo as default }; |