@cornerstonejs/dicom-image-loader 2.2.14 → 2.2.16
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.
|
@@ -12,93 +12,18 @@ import decodeJPEG2000 from './shared/decoders/decodeJPEG2000';
|
|
|
12
12
|
import decodeHTJ2K from './shared/decoders/decodeHTJ2K';
|
|
13
13
|
import applyModalityLUT from './shared/scaling/scaleArray';
|
|
14
14
|
import getMinMax from './shared/getMinMax';
|
|
15
|
-
import getPixelDataTypeFromMinMax from './shared/getPixelDataTypeFromMinMax';
|
|
15
|
+
import getPixelDataTypeFromMinMax, { validatePixelDataType, } from './shared/getPixelDataTypeFromMinMax';
|
|
16
16
|
import isColorImage from './shared/isColorImage';
|
|
17
17
|
const imageUtils = {
|
|
18
18
|
bilinear,
|
|
19
19
|
replicate,
|
|
20
20
|
};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
case '1.2.840.10008.1.2.1':
|
|
28
|
-
decodePromise = decodeLittleEndian(imageFrame, pixelData);
|
|
29
|
-
break;
|
|
30
|
-
case '1.2.840.10008.1.2.2':
|
|
31
|
-
decodePromise = decodeBigEndian(imageFrame, pixelData);
|
|
32
|
-
break;
|
|
33
|
-
case '1.2.840.10008.1.2.1.99':
|
|
34
|
-
decodePromise = decodeLittleEndian(imageFrame, pixelData);
|
|
35
|
-
break;
|
|
36
|
-
case '1.2.840.10008.1.2.5':
|
|
37
|
-
decodePromise = decodeRLE(imageFrame, pixelData);
|
|
38
|
-
break;
|
|
39
|
-
case '1.2.840.10008.1.2.4.50':
|
|
40
|
-
opts = {
|
|
41
|
-
...imageFrame,
|
|
42
|
-
};
|
|
43
|
-
decodePromise = decodeJPEGBaseline8Bit(pixelData, opts);
|
|
44
|
-
break;
|
|
45
|
-
case '1.2.840.10008.1.2.4.51':
|
|
46
|
-
decodePromise = decodeJPEGBaseline12Bit(imageFrame, pixelData);
|
|
47
|
-
break;
|
|
48
|
-
case '1.2.840.10008.1.2.4.57':
|
|
49
|
-
decodePromise = decodeJPEGLossless(imageFrame, pixelData);
|
|
50
|
-
break;
|
|
51
|
-
case '1.2.840.10008.1.2.4.70':
|
|
52
|
-
decodePromise = decodeJPEGLossless(imageFrame, pixelData);
|
|
53
|
-
break;
|
|
54
|
-
case '1.2.840.10008.1.2.4.80':
|
|
55
|
-
opts = {
|
|
56
|
-
signed: imageFrame.pixelRepresentation === 1,
|
|
57
|
-
bytesPerPixel: imageFrame.bitsAllocated <= 8 ? 1 : 2,
|
|
58
|
-
...imageFrame,
|
|
59
|
-
};
|
|
60
|
-
decodePromise = decodeJPEGLS(pixelData, opts);
|
|
61
|
-
break;
|
|
62
|
-
case '1.2.840.10008.1.2.4.81':
|
|
63
|
-
opts = {
|
|
64
|
-
signed: imageFrame.pixelRepresentation === 1,
|
|
65
|
-
bytesPerPixel: imageFrame.bitsAllocated <= 8 ? 1 : 2,
|
|
66
|
-
...imageFrame,
|
|
67
|
-
};
|
|
68
|
-
decodePromise = decodeJPEGLS(pixelData, opts);
|
|
69
|
-
break;
|
|
70
|
-
case '1.2.840.10008.1.2.4.90':
|
|
71
|
-
opts = {
|
|
72
|
-
...imageFrame,
|
|
73
|
-
};
|
|
74
|
-
decodePromise = decodeJPEG2000(pixelData, opts);
|
|
75
|
-
break;
|
|
76
|
-
case '1.2.840.10008.1.2.4.91':
|
|
77
|
-
opts = {
|
|
78
|
-
...imageFrame,
|
|
79
|
-
};
|
|
80
|
-
decodePromise = decodeJPEG2000(pixelData, opts);
|
|
81
|
-
break;
|
|
82
|
-
case '3.2.840.10008.1.2.4.96':
|
|
83
|
-
case '1.2.840.10008.1.2.4.201':
|
|
84
|
-
case '1.2.840.10008.1.2.4.202':
|
|
85
|
-
case '1.2.840.10008.1.2.4.203':
|
|
86
|
-
opts = {
|
|
87
|
-
...imageFrame,
|
|
88
|
-
};
|
|
89
|
-
decodePromise = decodeHTJ2K(pixelData, opts);
|
|
90
|
-
break;
|
|
91
|
-
default:
|
|
92
|
-
throw new Error(`no decoder for transfer syntax ${transferSyntax}`);
|
|
93
|
-
}
|
|
94
|
-
if (!decodePromise) {
|
|
95
|
-
throw new Error('decodePromise not defined');
|
|
96
|
-
}
|
|
97
|
-
const decodedFrame = await decodePromise;
|
|
98
|
-
const postProcessed = postProcessDecodedPixels(decodedFrame, options, start, decodeConfig);
|
|
99
|
-
callbackFn?.(postProcessed);
|
|
100
|
-
return postProcessed;
|
|
101
|
-
}
|
|
21
|
+
const typedArrayConstructors = {
|
|
22
|
+
Uint8Array,
|
|
23
|
+
Uint16Array,
|
|
24
|
+
Int16Array,
|
|
25
|
+
Float32Array,
|
|
26
|
+
};
|
|
102
27
|
function postProcessDecodedPixels(imageFrame, options, start, decodeConfig) {
|
|
103
28
|
const shouldShift = imageFrame.pixelRepresentation !== undefined &&
|
|
104
29
|
imageFrame.pixelRepresentation === 1;
|
|
@@ -113,22 +38,22 @@ function postProcessDecodedPixels(imageFrame, options, start, decodeConfig) {
|
|
|
113
38
|
let pixelDataArray = imageFrame.pixelData;
|
|
114
39
|
imageFrame.pixelDataLength = imageFrame.pixelData.length;
|
|
115
40
|
const { min: minBeforeScale, max: maxBeforeScale } = getMinMax(imageFrame.pixelData);
|
|
116
|
-
const typedArrayConstructors = {
|
|
117
|
-
Uint8Array,
|
|
118
|
-
Uint16Array,
|
|
119
|
-
Int16Array,
|
|
120
|
-
Float32Array,
|
|
121
|
-
};
|
|
122
|
-
const type = options.targetBuffer?.type;
|
|
123
41
|
const canRenderFloat = typeof options.allowFloatRendering !== 'undefined'
|
|
124
42
|
? options.allowFloatRendering
|
|
125
43
|
: true;
|
|
126
|
-
|
|
44
|
+
let invalidType = isColorImage(imageFrame.photometricInterpretation) &&
|
|
127
45
|
options.targetBuffer?.offset === undefined;
|
|
128
46
|
const willScale = options.preScale?.enabled;
|
|
129
47
|
const hasFloatRescale = willScale &&
|
|
130
48
|
Object.values(options.preScale.scalingParameters).some((v) => typeof v === 'number' && !Number.isInteger(v));
|
|
131
49
|
const disableScale = !options.preScale.enabled || (!canRenderFloat && hasFloatRescale);
|
|
50
|
+
const type = options.targetBuffer?.type;
|
|
51
|
+
if (type && options.preScale.enabled && !disableScale) {
|
|
52
|
+
const { rescaleSlope, rescaleIntercept } = options.preScale.scalingParameters;
|
|
53
|
+
const minAfterScale = rescaleSlope * minBeforeScale + rescaleIntercept;
|
|
54
|
+
const maxAfterScale = rescaleSlope * maxBeforeScale + rescaleIntercept;
|
|
55
|
+
invalidType = !validatePixelDataType(minAfterScale, maxAfterScale, type);
|
|
56
|
+
}
|
|
132
57
|
if (type && !invalidType) {
|
|
133
58
|
pixelDataArray = _handleTargetBuffer(options, imageFrame, typedArrayConstructors, pixelDataArray);
|
|
134
59
|
}
|
|
@@ -255,6 +180,87 @@ function scaleImageFrame(imageFrame, targetBuffer, TypedArrayConstructor) {
|
|
|
255
180
|
imageFrame.pixelDataLength = imageFrame.pixelData.length;
|
|
256
181
|
return imageFrame;
|
|
257
182
|
}
|
|
183
|
+
async function decodeImageFrame(imageFrame, transferSyntax, pixelData, decodeConfig, options, callbackFn) {
|
|
184
|
+
const start = new Date().getTime();
|
|
185
|
+
let decodePromise = null;
|
|
186
|
+
let opts;
|
|
187
|
+
switch (transferSyntax) {
|
|
188
|
+
case '1.2.840.10008.1.2':
|
|
189
|
+
case '1.2.840.10008.1.2.1':
|
|
190
|
+
decodePromise = decodeLittleEndian(imageFrame, pixelData);
|
|
191
|
+
break;
|
|
192
|
+
case '1.2.840.10008.1.2.2':
|
|
193
|
+
decodePromise = decodeBigEndian(imageFrame, pixelData);
|
|
194
|
+
break;
|
|
195
|
+
case '1.2.840.10008.1.2.1.99':
|
|
196
|
+
decodePromise = decodeLittleEndian(imageFrame, pixelData);
|
|
197
|
+
break;
|
|
198
|
+
case '1.2.840.10008.1.2.5':
|
|
199
|
+
decodePromise = decodeRLE(imageFrame, pixelData);
|
|
200
|
+
break;
|
|
201
|
+
case '1.2.840.10008.1.2.4.50':
|
|
202
|
+
opts = {
|
|
203
|
+
...imageFrame,
|
|
204
|
+
};
|
|
205
|
+
decodePromise = decodeJPEGBaseline8Bit(pixelData, opts);
|
|
206
|
+
break;
|
|
207
|
+
case '1.2.840.10008.1.2.4.51':
|
|
208
|
+
decodePromise = decodeJPEGBaseline12Bit(imageFrame, pixelData);
|
|
209
|
+
break;
|
|
210
|
+
case '1.2.840.10008.1.2.4.57':
|
|
211
|
+
decodePromise = decodeJPEGLossless(imageFrame, pixelData);
|
|
212
|
+
break;
|
|
213
|
+
case '1.2.840.10008.1.2.4.70':
|
|
214
|
+
decodePromise = decodeJPEGLossless(imageFrame, pixelData);
|
|
215
|
+
break;
|
|
216
|
+
case '1.2.840.10008.1.2.4.80':
|
|
217
|
+
opts = {
|
|
218
|
+
signed: imageFrame.pixelRepresentation === 1,
|
|
219
|
+
bytesPerPixel: imageFrame.bitsAllocated <= 8 ? 1 : 2,
|
|
220
|
+
...imageFrame,
|
|
221
|
+
};
|
|
222
|
+
decodePromise = decodeJPEGLS(pixelData, opts);
|
|
223
|
+
break;
|
|
224
|
+
case '1.2.840.10008.1.2.4.81':
|
|
225
|
+
opts = {
|
|
226
|
+
signed: imageFrame.pixelRepresentation === 1,
|
|
227
|
+
bytesPerPixel: imageFrame.bitsAllocated <= 8 ? 1 : 2,
|
|
228
|
+
...imageFrame,
|
|
229
|
+
};
|
|
230
|
+
decodePromise = decodeJPEGLS(pixelData, opts);
|
|
231
|
+
break;
|
|
232
|
+
case '1.2.840.10008.1.2.4.90':
|
|
233
|
+
opts = {
|
|
234
|
+
...imageFrame,
|
|
235
|
+
};
|
|
236
|
+
decodePromise = decodeJPEG2000(pixelData, opts);
|
|
237
|
+
break;
|
|
238
|
+
case '1.2.840.10008.1.2.4.91':
|
|
239
|
+
opts = {
|
|
240
|
+
...imageFrame,
|
|
241
|
+
};
|
|
242
|
+
decodePromise = decodeJPEG2000(pixelData, opts);
|
|
243
|
+
break;
|
|
244
|
+
case '3.2.840.10008.1.2.4.96':
|
|
245
|
+
case '1.2.840.10008.1.2.4.201':
|
|
246
|
+
case '1.2.840.10008.1.2.4.202':
|
|
247
|
+
case '1.2.840.10008.1.2.4.203':
|
|
248
|
+
opts = {
|
|
249
|
+
...imageFrame,
|
|
250
|
+
};
|
|
251
|
+
decodePromise = decodeHTJ2K(pixelData, opts);
|
|
252
|
+
break;
|
|
253
|
+
default:
|
|
254
|
+
throw new Error(`no decoder for transfer syntax ${transferSyntax}`);
|
|
255
|
+
}
|
|
256
|
+
if (!decodePromise) {
|
|
257
|
+
throw new Error('decodePromise not defined');
|
|
258
|
+
}
|
|
259
|
+
const decodedFrame = await decodePromise;
|
|
260
|
+
const postProcessed = postProcessDecodedPixels(decodedFrame, options, start, decodeConfig);
|
|
261
|
+
callbackFn?.(postProcessed);
|
|
262
|
+
return postProcessed;
|
|
263
|
+
}
|
|
258
264
|
const obj = {
|
|
259
265
|
decodeTask({ imageFrame, transferSyntax, decodeConfig, options, pixelData, callbackFn, }) {
|
|
260
266
|
return decodeImageFrame(imageFrame, transferSyntax, pixelData, decodeConfig, options, callbackFn);
|
|
@@ -20,3 +20,7 @@ export default function getPixelDataTypeFromMinMax(min, max) {
|
|
|
20
20
|
}
|
|
21
21
|
return pixelDataType || Float32Array;
|
|
22
22
|
}
|
|
23
|
+
export function validatePixelDataType(min, max, type) {
|
|
24
|
+
const pixelDataType = getPixelDataTypeFromMinMax(min, max);
|
|
25
|
+
return pixelDataType === type;
|
|
26
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cornerstonejs/dicom-image-loader",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.16",
|
|
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": "^2.2.
|
|
119
|
+
"@cornerstonejs/core": "^2.2.16",
|
|
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": "
|
|
134
|
+
"gitHead": "9fd2da0d880ff6f8ac1edb780ce901189722e0ea"
|
|
135
135
|
}
|