@cornerstonejs/dicom-image-loader 3.10.30 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,6 +23,7 @@ const typedArrayConstructors = {
23
23
  Uint16Array,
24
24
  Int16Array,
25
25
  Float32Array,
26
+ Uint32Array,
26
27
  };
27
28
  function postProcessDecodedPixels(imageFrame, options, start, decodeConfig) {
28
29
  const shouldShift = imageFrame.pixelRepresentation !== undefined &&
@@ -69,8 +70,8 @@ function postProcessDecodedPixels(imageFrame, options, start, decodeConfig) {
69
70
  const scalingParameters = options.preScale.scalingParameters;
70
71
  _validateScalingParameters(scalingParameters);
71
72
  const { rescaleSlope, rescaleIntercept } = scalingParameters;
72
- const isSlopeAndInterceptNumbers = typeof rescaleSlope === 'number' && typeof rescaleIntercept === 'number';
73
- if (isSlopeAndInterceptNumbers) {
73
+ const isRequiredScaling = _isRequiredScaling(scalingParameters);
74
+ if (isRequiredScaling) {
74
75
  applyModalityLUT(pixelDataArray, scalingParameters);
75
76
  imageFrame.preScale = {
76
77
  ...options.preScale,
@@ -100,6 +101,13 @@ function postProcessDecodedPixels(imageFrame, options, start, decodeConfig) {
100
101
  imageFrame.decodeTimeInMS = end - start;
101
102
  return imageFrame;
102
103
  }
104
+ function _isRequiredScaling(scalingParameters) {
105
+ const { rescaleSlope, rescaleIntercept, modality, doseGridScaling, suvbw } = scalingParameters;
106
+ const hasRescaleValues = typeof rescaleSlope === 'number' && typeof rescaleIntercept === 'number';
107
+ const isRTDOSEWithScaling = modality === 'RTDOSE' && typeof doseGridScaling === 'number';
108
+ const isPTWithSUV = modality === 'PT' && typeof suvbw === 'number';
109
+ return hasRescaleValues || isRTDOSEWithScaling || isPTWithSUV;
110
+ }
103
111
  function _handleTargetBuffer(options, imageFrame, typedArrayConstructors, pixelDataArray) {
104
112
  const { arrayBuffer, type, offset: rawOffset = 0, length: rawLength, rows, } = options.targetBuffer;
105
113
  const TypedArrayConstructor = typedArrayConstructors[type];
@@ -61,6 +61,7 @@ function createImage(imageId, pixelData, transferSyntax, options = {}) {
61
61
  Uint16Array,
62
62
  Int16Array,
63
63
  Float32Array,
64
+ Uint32Array,
64
65
  };
65
66
  if (length !== imageFrame.pixelDataLength) {
66
67
  throw new Error(`target array for image does not have the same length (${length}) as the decoded image length (${imageFrame.pixelDataLength}).`);
@@ -1,4 +1,8 @@
1
1
  export default function getScalingParameters(metaData: any, imageId: string): {
2
+ doseGridScaling: any;
3
+ doseSummation: any;
4
+ doseType: any;
5
+ doseUnit: any;
2
6
  suvbw: any;
3
7
  rescaleSlope: any;
4
8
  rescaleIntercept: any;
@@ -8,9 +8,15 @@ export default function getScalingParameters(metaData, imageId) {
8
8
  rescaleIntercept: modalityLutModule.rescaleIntercept,
9
9
  modality,
10
10
  };
11
- const suvFactor = metaData.get('scalingModule', imageId) || {};
11
+ const scalingModules = metaData.get('scalingModule', imageId) || {};
12
12
  return {
13
13
  ...scalingParameters,
14
- ...(modality === 'PT' && { suvbw: suvFactor.suvbw }),
14
+ ...(modality === 'PT' && { suvbw: scalingModules.suvbw }),
15
+ ...(modality === 'RTDOSE' && {
16
+ doseGridScaling: scalingModules.DoseGridScaling,
17
+ doseSummation: scalingModules.DoseSummation,
18
+ doseType: scalingModules.DoseType,
19
+ doseUnit: scalingModules.DoseUnit,
20
+ }),
15
21
  };
16
22
  }
@@ -3,12 +3,12 @@ function getFrameInformation(PerFrameFunctionalGroupsSequence, SharedFunctionalG
3
3
  const shared = (SharedFunctionalGroupsSequence
4
4
  ? Object.values(SharedFunctionalGroupsSequence[0])
5
5
  : [])
6
- .map((it) => it[0])
6
+ .map((it) => it['Value']?.[0])
7
7
  .filter((it) => it !== undefined && typeof it === 'object');
8
8
  const perFrame = (PerFrameFunctionalGroupsSequence
9
9
  ? Object.values(PerFrameFunctionalGroupsSequence[frameNumber - 1])
10
10
  : [])
11
- .map((it) => it.Value[0])
11
+ .map((it) => it['Value']?.[0])
12
12
  .filter((it) => it !== undefined && typeof it === 'object');
13
13
  return {
14
14
  shared,
@@ -22,7 +22,18 @@ async function decodeLittleEndian(imageFrame, pixelData) {
22
22
  arrayBuffer = arrayBuffer.slice(offset);
23
23
  offset = 0;
24
24
  }
25
- imageFrame.pixelData = new Float32Array(arrayBuffer, offset, length / 4);
25
+ if (imageFrame.floatPixelData || imageFrame.doubleFloatPixelData) {
26
+ throw new Error('Float pixel data is not supported for parsing into ImageFrame');
27
+ }
28
+ if (imageFrame.pixelRepresentation === 0) {
29
+ imageFrame.pixelData = new Uint32Array(arrayBuffer, offset, length / 4);
30
+ }
31
+ else if (imageFrame.pixelRepresentation === 1) {
32
+ imageFrame.pixelData = new Int32Array(arrayBuffer, offset, length / 4);
33
+ }
34
+ else {
35
+ imageFrame.pixelData = new Float32Array(arrayBuffer, offset, length / 4);
36
+ }
26
37
  }
27
38
  return imageFrame;
28
39
  }
@@ -8,6 +8,9 @@ export default function getPixelDataTypeFromMinMax(min, max) {
8
8
  else if (max <= 65535) {
9
9
  pixelDataType = Uint16Array;
10
10
  }
11
+ else if (max <= 4294967295) {
12
+ pixelDataType = Uint32Array;
13
+ }
11
14
  }
12
15
  else {
13
16
  if (min >= -128 && max <= 127) {
@@ -1,6 +1,6 @@
1
1
  export default function scaleArray(array, scalingParameters) {
2
2
  const arrayLength = array.length;
3
- const { rescaleSlope, rescaleIntercept, suvbw } = scalingParameters;
3
+ const { rescaleSlope, rescaleIntercept, suvbw, doseGridScaling } = scalingParameters;
4
4
  if (scalingParameters.modality === 'PT' &&
5
5
  typeof suvbw === 'number' &&
6
6
  !isNaN(suvbw)) {
@@ -8,6 +8,13 @@ export default function scaleArray(array, scalingParameters) {
8
8
  array[i] = suvbw * (array[i] * rescaleSlope + rescaleIntercept);
9
9
  }
10
10
  }
11
+ else if (scalingParameters.modality === 'RTDOSE' &&
12
+ typeof doseGridScaling === 'number' &&
13
+ !isNaN(doseGridScaling)) {
14
+ for (let i = 0; i < arrayLength; i++) {
15
+ array[i] = array[i] * doseGridScaling;
16
+ }
17
+ }
11
18
  else {
12
19
  for (let i = 0; i < arrayLength; i++) {
13
20
  array[i] = array[i] * rescaleSlope + rescaleIntercept;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cornerstonejs/dicom-image-loader",
3
- "version": "3.10.30",
3
+ "version": "3.11.0",
4
4
  "description": "Cornerstone Image Loader for DICOM WADO-URI and WADO-RS and Local file",
5
5
  "keywords": [
6
6
  "DICOM",
@@ -116,7 +116,7 @@
116
116
  "uuid": "^9.0.0"
117
117
  },
118
118
  "peerDependencies": {
119
- "@cornerstonejs/core": "^3.10.30",
119
+ "@cornerstonejs/core": "^3.11.0",
120
120
  "dicom-parser": "^1.8.9"
121
121
  },
122
122
  "lint-staged": {
@@ -131,5 +131,5 @@
131
131
  "path": "./node_modules/cz-conventional-changelog"
132
132
  }
133
133
  },
134
- "gitHead": "884fc7a5c0a10dc9b10dbfe43dda583ad48c3f17"
134
+ "gitHead": "e051da49a8fb4e7559861e9d3de08fdeb108c53b"
135
135
  }