@cornerstonejs/nifti-volume-loader 2.0.0-beta.8 → 2.0.1

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.
Files changed (44) hide show
  1. package/dist/esm/constants/index.js +0 -1
  2. package/dist/esm/constants/niftiLoaderScheme.js +0 -1
  3. package/dist/esm/cornerstoneNiftiImageLoader.d.ts +2 -7
  4. package/dist/esm/cornerstoneNiftiImageLoader.js +123 -7
  5. package/dist/esm/createNiftiImageIdsAndCacheMetadata.d.ts +17 -0
  6. package/dist/esm/createNiftiImageIdsAndCacheMetadata.js +250 -0
  7. package/dist/esm/enums/Events.js +0 -1
  8. package/dist/esm/enums/index.js +0 -1
  9. package/dist/esm/helpers/affineUtilities.js +0 -1
  10. package/dist/esm/helpers/convert.d.ts +1 -1
  11. package/dist/esm/helpers/convert.js +1 -5
  12. package/dist/esm/helpers/dataTypeCodeHelper.d.ts +1 -0
  13. package/dist/esm/helpers/dataTypeCodeHelper.js +22 -0
  14. package/dist/esm/helpers/index.d.ts +1 -2
  15. package/dist/esm/helpers/index.js +1 -3
  16. package/dist/esm/helpers/makeVolumeMetadata.d.ts +2 -2
  17. package/dist/esm/helpers/makeVolumeMetadata.js +4 -14
  18. package/dist/esm/helpers/modalityScaleNifti.d.ts +1 -1
  19. package/dist/esm/helpers/modalityScaleNifti.js +6 -19
  20. package/dist/esm/helpers/niftiConstants.js +0 -1
  21. package/dist/esm/index.d.ts +3 -3
  22. package/dist/esm/index.js +3 -4
  23. package/dist/umd/index.js +1 -2
  24. package/package.json +41 -17
  25. package/dist/esm/NiftiImageVolume.d.ts +0 -21
  26. package/dist/esm/NiftiImageVolume.js +0 -26
  27. package/dist/esm/NiftiImageVolume.js.map +0 -1
  28. package/dist/esm/constants/index.js.map +0 -1
  29. package/dist/esm/constants/niftiLoaderScheme.js.map +0 -1
  30. package/dist/esm/cornerstoneNiftiImageLoader.js.map +0 -1
  31. package/dist/esm/enums/Events.js.map +0 -1
  32. package/dist/esm/enums/index.js.map +0 -1
  33. package/dist/esm/helpers/affineUtilities.js.map +0 -1
  34. package/dist/esm/helpers/convert.js.map +0 -1
  35. package/dist/esm/helpers/fetchAndAllocateNiftiVolume.d.ts +0 -3
  36. package/dist/esm/helpers/fetchAndAllocateNiftiVolume.js +0 -95
  37. package/dist/esm/helpers/fetchAndAllocateNiftiVolume.js.map +0 -1
  38. package/dist/esm/helpers/index.js.map +0 -1
  39. package/dist/esm/helpers/makeVolumeMetadata.js.map +0 -1
  40. package/dist/esm/helpers/modalityScaleNifti.js.map +0 -1
  41. package/dist/esm/helpers/niftiConstants.js.map +0 -1
  42. package/dist/esm/index.js.map +0 -1
  43. package/dist/umd/index.js.LICENSE.txt +0 -3
  44. package/dist/umd/index.js.map +0 -1
@@ -1,3 +1,2 @@
1
1
  import NIFTI_LOADER_SCHEME from './niftiLoaderScheme';
2
2
  export { NIFTI_LOADER_SCHEME };
3
- //# sourceMappingURL=index.js.map
@@ -1,3 +1,2 @@
1
1
  const niftiLoaderScheme = 'nifti';
2
2
  export default niftiLoaderScheme;
3
- //# sourceMappingURL=niftiLoaderScheme.js.map
@@ -1,7 +1,2 @@
1
- import NiftiImageVolume from './NiftiImageVolume';
2
- interface IVolumeLoader {
3
- promise: Promise<NiftiImageVolume>;
4
- cancel: () => void;
5
- }
6
- export default function cornerstoneNiftiImageVolumeLoader(volumeId: string): IVolumeLoader;
7
- export {};
1
+ import type { Types } from '@cornerstonejs/core';
2
+ export default function cornerstoneNiftiImageLoader(imageId: string): Types.IImageLoadObject;
@@ -1,10 +1,126 @@
1
- import { fetchAndAllocateNiftiVolume } from './helpers';
2
- export default function cornerstoneNiftiImageVolumeLoader(volumeId) {
3
- const niftiVolumePromise = fetchAndAllocateNiftiVolume(volumeId);
1
+ import { Enums, eventTarget, metaData, triggerEvent, utilities, } from '@cornerstonejs/core';
2
+ import * as NiftiReader from 'nifti-reader-js';
3
+ import { Events } from './enums';
4
+ import { modalityScaleNifti } from './helpers';
5
+ const fetchStarted = new Map();
6
+ let niftiScalarData = null;
7
+ function fetchArrayBuffer({ url, signal, onload, }) {
8
+ return new Promise((resolve, reject) => {
9
+ const xhr = new XMLHttpRequest();
10
+ xhr.open('GET', url, true);
11
+ xhr.responseType = 'arraybuffer';
12
+ const onLoadHandler = function (e) {
13
+ if (onload && typeof onload === 'function') {
14
+ onload();
15
+ }
16
+ if (signal) {
17
+ signal.removeEventListener('abort', onAbortHandler);
18
+ }
19
+ resolve(xhr.response);
20
+ };
21
+ const onAbortHandler = () => {
22
+ xhr.abort();
23
+ xhr.removeEventListener('load', onLoadHandler);
24
+ reject(new Error('Request aborted'));
25
+ };
26
+ xhr.addEventListener('load', onLoadHandler);
27
+ const onProgress = (loaded, total) => {
28
+ const data = { url, loaded, total };
29
+ triggerEvent(eventTarget, Events.NIFTI_VOLUME_PROGRESS, { data });
30
+ };
31
+ xhr.onprogress = function (e) {
32
+ onProgress(e.loaded, e.total);
33
+ };
34
+ if (signal && signal.aborted) {
35
+ xhr.abort();
36
+ reject(new Error('Request aborted'));
37
+ }
38
+ else if (signal) {
39
+ signal.addEventListener('abort', onAbortHandler);
40
+ }
41
+ xhr.send();
42
+ });
43
+ }
44
+ export default function cornerstoneNiftiImageLoader(imageId) {
45
+ const [url, frame] = imageId.substring(6).split('?frame=');
46
+ const sliceIndex = parseInt(frame, 10);
47
+ const imagePixelModule = metaData.get(Enums.MetadataModules.IMAGE_PIXEL, imageId);
48
+ const imagePlaneModule = metaData.get(Enums.MetadataModules.IMAGE_PLANE, imageId);
49
+ const promise = new Promise((resolve, reject) => {
50
+ if (!fetchStarted.get(url)) {
51
+ fetchStarted.set(url, true);
52
+ fetchAndProcessNiftiData(imageId, url, sliceIndex, imagePixelModule, imagePlaneModule)
53
+ .then(resolve)
54
+ .catch(reject);
55
+ }
56
+ else {
57
+ waitForNiftiData(imageId, sliceIndex, imagePixelModule, imagePlaneModule)
58
+ .then(resolve)
59
+ .catch(reject);
60
+ }
61
+ });
62
+ return {
63
+ promise: promise,
64
+ cancelFn: undefined,
65
+ };
66
+ }
67
+ async function fetchAndProcessNiftiData(imageId, url, sliceIndex, imagePixelModule, imagePlaneModule) {
68
+ let niftiBuffer = await fetchArrayBuffer({ url });
69
+ let niftiHeader = null;
70
+ let niftiImage = null;
71
+ if (NiftiReader.isCompressed(niftiBuffer)) {
72
+ niftiBuffer = NiftiReader.decompress(niftiBuffer);
73
+ }
74
+ if (NiftiReader.isNIFTI(niftiBuffer)) {
75
+ niftiHeader = NiftiReader.readHeader(niftiBuffer);
76
+ niftiImage = NiftiReader.readImage(niftiHeader, niftiBuffer);
77
+ }
78
+ else {
79
+ const errorMessage = 'The provided buffer is not a valid NIFTI file.';
80
+ console.warn(errorMessage);
81
+ throw new Error(errorMessage);
82
+ }
83
+ const { scalarData } = modalityScaleNifti(niftiHeader, niftiImage);
84
+ niftiScalarData = scalarData;
85
+ return createImage(imageId, sliceIndex, imagePixelModule, imagePlaneModule);
86
+ }
87
+ function waitForNiftiData(imageId, sliceIndex, imagePixelModule, imagePlaneModule) {
88
+ return new Promise((resolve) => {
89
+ const intervalId = setInterval(() => {
90
+ if (niftiScalarData) {
91
+ clearInterval(intervalId);
92
+ resolve(createImage(imageId, sliceIndex, imagePixelModule, imagePlaneModule));
93
+ }
94
+ }, 10);
95
+ });
96
+ }
97
+ function createImage(imageId, sliceIndex, imagePixelModule, imagePlaneModule) {
98
+ const { rows, columns } = imagePlaneModule;
99
+ const numVoxels = rows * columns;
100
+ const sliceOffset = numVoxels * sliceIndex;
101
+ const pixelData = new niftiScalarData.constructor(numVoxels);
102
+ pixelData.set(niftiScalarData.subarray(sliceOffset, sliceOffset + numVoxels));
103
+ const voxelManager = utilities.VoxelManager.createImageVoxelManager({
104
+ width: columns,
105
+ height: rows,
106
+ numberOfComponents: 1,
107
+ scalarData: pixelData,
108
+ });
4
109
  return {
5
- promise: niftiVolumePromise,
6
- cancel: () => {
7
- },
110
+ imageId,
111
+ dataType: niftiScalarData.constructor
112
+ .name,
113
+ columnPixelSpacing: imagePlaneModule.columnPixelSpacing,
114
+ columns: imagePlaneModule.columns,
115
+ height: imagePlaneModule.rows,
116
+ invert: imagePixelModule.photometricInterpretation === 'MONOCHROME1',
117
+ rowPixelSpacing: imagePlaneModule.rowPixelSpacing,
118
+ rows: imagePlaneModule.rows,
119
+ sizeInBytes: rows * columns * niftiScalarData.BYTES_PER_ELEMENT,
120
+ width: imagePlaneModule.columns,
121
+ getPixelData: () => voxelManager.getScalarData(),
122
+ getCanvas: undefined,
123
+ numberOfComponents: undefined,
124
+ voxelManager,
8
125
  };
9
126
  }
10
- //# sourceMappingURL=cornerstoneNiftiImageLoader.js.map
@@ -0,0 +1,17 @@
1
+ export declare const urlsMap: Map<any, any>;
2
+ export declare function fetchArrayBuffer({ url, onProgress, controller, onLoad, onHeader, loadFullVolume, }: {
3
+ url: any;
4
+ onProgress: any;
5
+ controller: any;
6
+ onLoad: any;
7
+ onHeader: any;
8
+ loadFullVolume?: boolean;
9
+ }): Promise<{
10
+ data: Uint8Array;
11
+ headerInfo: any;
12
+ sliceInfo: any;
13
+ }>;
14
+ declare function createNiftiImageIdsAndCacheMetadata({ url }: {
15
+ url: any;
16
+ }): Promise<any[]>;
17
+ export { createNiftiImageIdsAndCacheMetadata };
@@ -0,0 +1,250 @@
1
+ import * as NiftiReader from 'nifti-reader-js';
2
+ import { eventTarget, triggerEvent, utilities } from '@cornerstonejs/core';
3
+ import { rasToLps } from './helpers/convert';
4
+ import Events from './enums/Events';
5
+ import { NIFTI_LOADER_SCHEME } from './constants';
6
+ import makeVolumeMetadata from './helpers/makeVolumeMetadata';
7
+ import { getArrayConstructor } from './helpers/dataTypeCodeHelper';
8
+ export const urlsMap = new Map();
9
+ const NIFTI1_HEADER_SIZE = 348;
10
+ const NIFTI2_HEADER_SIZE = 540;
11
+ const HEADER_CHECK_SIZE = Math.max(NIFTI1_HEADER_SIZE, NIFTI2_HEADER_SIZE);
12
+ export async function fetchArrayBuffer({ url, onProgress, controller, onLoad, onHeader, loadFullVolume = false, }) {
13
+ const isCompressed = url.endsWith('.gz');
14
+ let receivedData = new Uint8Array(0);
15
+ let niftiHeader = null;
16
+ const sliceInfo = null;
17
+ let contentLength;
18
+ const receivedLength = 0;
19
+ const signal = controller.signal;
20
+ try {
21
+ const response = await fetch(url, { signal });
22
+ if (!response.ok) {
23
+ throw new Error(`HTTP error! status: ${response.status}`);
24
+ }
25
+ contentLength = response.headers.get('Content-Length');
26
+ const reader = response.body.getReader();
27
+ const decompressionStream = isCompressed
28
+ ? new DecompressionStream('gzip')
29
+ : null;
30
+ const decompressionWriter = decompressionStream
31
+ ? decompressionStream.writable.getWriter()
32
+ : null;
33
+ readStream(reader, decompressionWriter, isCompressed, receivedLength, processChunk, controller).catch(console.error);
34
+ if (isCompressed) {
35
+ const decompressedStream = decompressionStream.readable.getReader();
36
+ while (true) {
37
+ const { done, value } = await decompressedStream.read();
38
+ if (done) {
39
+ break;
40
+ }
41
+ processChunk(value);
42
+ if (niftiHeader && !loadFullVolume) {
43
+ controller.abort();
44
+ break;
45
+ }
46
+ }
47
+ }
48
+ if (onLoad && typeof onLoad === 'function') {
49
+ onLoad();
50
+ }
51
+ return { data: receivedData, headerInfo: niftiHeader, sliceInfo };
52
+ }
53
+ catch (error) {
54
+ if (error.name === 'AbortError') {
55
+ console.log('Fetch aborted');
56
+ }
57
+ else {
58
+ console.error('Fetch error:', error);
59
+ }
60
+ throw error;
61
+ }
62
+ function processChunk(chunk) {
63
+ appendData(chunk);
64
+ if (onProgress && typeof onProgress === 'function') {
65
+ onProgress(receivedLength, contentLength);
66
+ }
67
+ }
68
+ function appendData(data) {
69
+ const newData = new Uint8Array(receivedData.length + data.length);
70
+ newData.set(receivedData);
71
+ newData.set(data, receivedData.length);
72
+ receivedData = newData;
73
+ if (!loadFullVolume &&
74
+ !niftiHeader &&
75
+ receivedData.length >= HEADER_CHECK_SIZE) {
76
+ niftiHeader = handleNiftiHeader(receivedData);
77
+ if (niftiHeader && niftiHeader.isValid) {
78
+ controller.abort();
79
+ }
80
+ onHeader?.(niftiHeader);
81
+ }
82
+ }
83
+ }
84
+ async function readStream(reader, decompressionWriter, isCompressed, receivedLength, processChunk, controller) {
85
+ while (true) {
86
+ const { done, value } = await reader.read();
87
+ if (done) {
88
+ if (isCompressed) {
89
+ decompressionWriter.close();
90
+ }
91
+ break;
92
+ }
93
+ receivedLength += value.length;
94
+ if (isCompressed) {
95
+ await decompressionWriter.write(value);
96
+ }
97
+ else {
98
+ processChunk(value);
99
+ }
100
+ if (controller.signal.aborted) {
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ function handleNiftiHeader(data) {
106
+ if (data.length < HEADER_CHECK_SIZE) {
107
+ return { isValid: false, message: 'Not enough data to check header' };
108
+ }
109
+ try {
110
+ const headerBuffer = data.slice(0, HEADER_CHECK_SIZE).buffer;
111
+ const header = NiftiReader.readHeader(headerBuffer);
112
+ const version = header.sizeof_hdr === NIFTI2_HEADER_SIZE ? 2 : 1;
113
+ const { orientation, origin, spacing } = rasToLps(header);
114
+ const { dimensions, direction } = makeVolumeMetadata(header, orientation, 1);
115
+ const arrayConstructor = getArrayConstructor(header.datatypeCode);
116
+ return {
117
+ dimensions,
118
+ direction,
119
+ isValid: true,
120
+ message: `Valid Nifti-${version} header detected`,
121
+ origin,
122
+ version,
123
+ orientation,
124
+ spacing,
125
+ header,
126
+ arrayConstructor,
127
+ };
128
+ }
129
+ catch (error) {
130
+ console.error('Error reading Nifti header:', error);
131
+ return { isValid: false, message: 'Error reading Nifti header' };
132
+ }
133
+ }
134
+ async function fetchAndAllocateNiftiVolume(volumeId) {
135
+ const niftiURL = volumeId.substring(NIFTI_LOADER_SCHEME.length + 1);
136
+ const onProgress = (loaded, total) => {
137
+ const data = { volumeId, loaded, total };
138
+ triggerEvent(eventTarget, Events.NIFTI_VOLUME_PROGRESS, { data });
139
+ };
140
+ const onLoad = () => {
141
+ const data = { volumeId };
142
+ triggerEvent(eventTarget, Events.NIFTI_VOLUME_LOADED, { data });
143
+ };
144
+ const controller = new AbortController();
145
+ urlsMap.set(niftiURL, { controller, loading: true });
146
+ const niftiHeader = (await new Promise((resolve) => {
147
+ fetchArrayBuffer({
148
+ url: niftiURL,
149
+ onProgress,
150
+ controller,
151
+ onLoad,
152
+ onHeader: resolve,
153
+ });
154
+ }));
155
+ const { dimensions, direction, isValid, message, origin, version, header, spacing, arrayConstructor, } = niftiHeader;
156
+ const numImages = dimensions[2];
157
+ if (!isValid) {
158
+ console.error(message);
159
+ return;
160
+ }
161
+ const imageIds = [];
162
+ for (let i = 0; i < numImages; i++) {
163
+ const imageId = `nifti:${niftiURL}?frame=${i}`;
164
+ const imageIdIndex = i;
165
+ imageIds.push(imageId);
166
+ const imageOrientationPatient = [
167
+ direction[0],
168
+ direction[1],
169
+ direction[2],
170
+ direction[3],
171
+ direction[4],
172
+ direction[5],
173
+ ];
174
+ const precision = 6;
175
+ const imagePositionPatient = [
176
+ parseFloat((origin[0] + imageIdIndex * direction[6] * spacing[0]).toFixed(precision)),
177
+ parseFloat((origin[1] + imageIdIndex * direction[7] * spacing[1]).toFixed(precision)),
178
+ parseFloat((origin[2] + imageIdIndex * direction[8] * spacing[2]).toFixed(precision)),
179
+ ];
180
+ const imagePlaneMetadata = {
181
+ frameOfReferenceUID: '1.2.840.10008.1.4',
182
+ rows: dimensions[1],
183
+ columns: dimensions[0],
184
+ imageOrientationPatient,
185
+ rowCosines: direction.slice(0, 3),
186
+ columnCosines: direction.slice(3, 6),
187
+ imagePositionPatient,
188
+ sliceThickness: spacing[2],
189
+ sliceLocation: origin[2] + i * spacing[2],
190
+ pixelSpacing: [spacing[0], spacing[1]],
191
+ rowPixelSpacing: spacing[1],
192
+ columnPixelSpacing: spacing[0],
193
+ };
194
+ const imagePixelMetadata = {
195
+ samplesPerPixel: 1,
196
+ photometricInterpretation: 'MONOCHROME2',
197
+ rows: dimensions[1],
198
+ columns: dimensions[0],
199
+ bitsAllocated: arrayConstructor.BYTES_PER_ELEMENT * 8,
200
+ bitsStored: arrayConstructor.BYTES_PER_ELEMENT * 8,
201
+ highBit: arrayConstructor.BYTES_PER_ELEMENT * 8 - 1,
202
+ pixelRepresentation: 1,
203
+ planarConfiguration: 0,
204
+ pixelAspectRatio: '1\\1',
205
+ redPaletteColorLookupTableDescriptor: [],
206
+ greenPaletteColorLookupTableDescriptor: [],
207
+ bluePaletteColorLookupTableDescriptor: [],
208
+ redPaletteColorLookupTableData: [],
209
+ greenPaletteColorLookupTableData: [],
210
+ bluePaletteColorLookupTableData: [],
211
+ smallestPixelValue: undefined,
212
+ largestPixelValue: undefined,
213
+ };
214
+ const generalSeriesMetadata = {
215
+ seriesDate: new Date(),
216
+ seriesTime: new Date(),
217
+ };
218
+ utilities.genericMetadataProvider.add(imageId, {
219
+ type: 'imagePixelModule',
220
+ metadata: imagePixelMetadata,
221
+ });
222
+ utilities.genericMetadataProvider.add(imageId, {
223
+ type: 'imagePlaneModule',
224
+ metadata: imagePlaneMetadata,
225
+ });
226
+ utilities.genericMetadataProvider.add(imageId, {
227
+ type: 'generalSeriesModule',
228
+ metadata: generalSeriesMetadata,
229
+ });
230
+ utilities.genericMetadataProvider.add(imageId, {
231
+ type: 'niftiVersion',
232
+ metadata: {
233
+ version,
234
+ },
235
+ });
236
+ utilities.genericMetadataProvider.addRaw(imageId, {
237
+ type: 'niftiHeader',
238
+ metadata: {
239
+ header,
240
+ },
241
+ });
242
+ }
243
+ urlsMap.delete(niftiURL);
244
+ return imageIds;
245
+ }
246
+ async function createNiftiImageIdsAndCacheMetadata({ url }) {
247
+ const imageIds = await fetchAndAllocateNiftiVolume(url);
248
+ return imageIds;
249
+ }
250
+ export { createNiftiImageIdsAndCacheMetadata };
@@ -4,4 +4,3 @@ var Events;
4
4
  Events["NIFTI_VOLUME_PROGRESS"] = "CORNERSTONE_NIFTI_VOLUME_PROGRESS";
5
5
  })(Events || (Events = {}));
6
6
  export default Events;
7
- //# sourceMappingURL=Events.js.map
@@ -1,3 +1,2 @@
1
1
  import Events from './Events';
2
2
  export { Events };
3
- //# sourceMappingURL=index.js.map
@@ -42,4 +42,3 @@ function parseAffineMatrix(affine) {
42
42
  return { origin, orientation, spacing };
43
43
  }
44
44
  export { generateAffineMatrix, parseAffineMatrix };
45
- //# sourceMappingURL=affineUtilities.js.map
@@ -1,4 +1,4 @@
1
- import { Types } from '@cornerstonejs/core';
1
+ import type { Types } from '@cornerstonejs/core';
2
2
  declare const invertDataPerFrame: (dimensions: any, imageDataArray: any) => any;
3
3
  declare function rasToLps(niftiHeader: any): {
4
4
  origin: Types.Point3;
@@ -1,12 +1,9 @@
1
- import { getShouldUseSharedArrayBuffer } from '@cornerstonejs/core';
2
1
  import { parseAffineMatrix } from './affineUtilities';
3
2
  const invertDataPerFrame = (dimensions, imageDataArray) => {
4
3
  let TypedArrayConstructor;
5
4
  let bytesPerVoxel;
6
5
  if (imageDataArray instanceof Uint8Array ||
7
- imageDataArray instanceof ArrayBuffer ||
8
- (getShouldUseSharedArrayBuffer() &&
9
- imageDataArray instanceof SharedArrayBuffer)) {
6
+ imageDataArray instanceof ArrayBuffer) {
10
7
  TypedArrayConstructor = Uint8Array;
11
8
  bytesPerVoxel = 1;
12
9
  }
@@ -82,4 +79,3 @@ function lpsToRas(header) {
82
79
  };
83
80
  }
84
81
  export { lpsToRas, rasToLps, invertDataPerFrame };
85
- //# sourceMappingURL=convert.js.map
@@ -0,0 +1 @@
1
+ export declare function getArrayConstructor(datatypeCode: number): unknown;
@@ -0,0 +1,22 @@
1
+ import * as NIFTICONSTANTS from './niftiConstants';
2
+ export function getArrayConstructor(datatypeCode) {
3
+ switch (datatypeCode) {
4
+ case NIFTICONSTANTS.NIFTI_TYPE_UINT8:
5
+ return Uint8Array;
6
+ case NIFTICONSTANTS.NIFTI_TYPE_INT16:
7
+ return Int16Array;
8
+ case NIFTICONSTANTS.NIFTI_TYPE_INT32:
9
+ return Int32Array;
10
+ case NIFTICONSTANTS.NIFTI_TYPE_FLOAT32: {
11
+ return Float32Array;
12
+ }
13
+ case NIFTICONSTANTS.NIFTI_TYPE_INT8:
14
+ return Int8Array;
15
+ case NIFTICONSTANTS.NIFTI_TYPE_UINT16:
16
+ return Uint16Array;
17
+ case NIFTICONSTANTS.NIFTI_TYPE_UINT32:
18
+ return Uint32Array;
19
+ default:
20
+ throw new Error(`NIFTI datatypeCode ${datatypeCode} is not yet supported`);
21
+ }
22
+ }
@@ -1,4 +1,3 @@
1
1
  import makeVolumeMetadata from './makeVolumeMetadata';
2
2
  import modalityScaleNifti from './modalityScaleNifti';
3
- import fetchAndAllocateNiftiVolume from './fetchAndAllocateNiftiVolume';
4
- export { modalityScaleNifti, makeVolumeMetadata, fetchAndAllocateNiftiVolume };
3
+ export { modalityScaleNifti, makeVolumeMetadata };
@@ -1,5 +1,3 @@
1
1
  import makeVolumeMetadata from './makeVolumeMetadata';
2
2
  import modalityScaleNifti from './modalityScaleNifti';
3
- import fetchAndAllocateNiftiVolume from './fetchAndAllocateNiftiVolume';
4
- export { modalityScaleNifti, makeVolumeMetadata, fetchAndAllocateNiftiVolume };
5
- //# sourceMappingURL=index.js.map
3
+ export { modalityScaleNifti, makeVolumeMetadata };
@@ -1,5 +1,5 @@
1
- import { Types } from '@cornerstonejs/core';
2
- export default function makeVolumeMetadata(niftiHeader: any, orientation: any, scalarData: any, pixelRepresentation: any): {
1
+ import type { Types } from '@cornerstonejs/core';
2
+ export default function makeVolumeMetadata(niftiHeader: any, orientation: any, pixelRepresentation: any): {
3
3
  volumeMetadata: Types.Metadata;
4
4
  dimensions: Types.Point3;
5
5
  direction: Types.Mat3;
@@ -1,23 +1,14 @@
1
1
  import { utilities } from '@cornerstonejs/core';
2
2
  import { vec3 } from 'gl-matrix';
3
3
  const { windowLevel } = utilities;
4
- export default function makeVolumeMetadata(niftiHeader, orientation, scalarData, pixelRepresentation) {
4
+ export default function makeVolumeMetadata(niftiHeader, orientation, pixelRepresentation) {
5
5
  const { numBitsPerVoxel, littleEndian, pixDims, dims } = niftiHeader;
6
- let min = Infinity;
7
- let max = -Infinity;
6
+ const min = Infinity;
7
+ const max = -Infinity;
8
8
  const frameLength = dims[1] * dims[2];
9
9
  const middleFrameIndex = Math.floor(dims[3] / 2);
10
10
  const offset = frameLength * middleFrameIndex;
11
- for (let voxelIndex = offset; voxelIndex < offset + frameLength; voxelIndex++) {
12
- const voxelValue = scalarData[voxelIndex];
13
- if (voxelValue > max) {
14
- max = voxelValue;
15
- }
16
- if (voxelValue < min) {
17
- min = voxelValue;
18
- }
19
- }
20
- const { windowWidth, windowCenter } = windowLevel.toWindowLevel(min, max);
11
+ const { windowWidth, windowCenter } = { windowWidth: 400, windowCenter: 40 };
21
12
  const rowCosines = vec3.create();
22
13
  const columnCosines = vec3.create();
23
14
  const scanAxisNormal = vec3.create();
@@ -62,4 +53,3 @@ export default function makeVolumeMetadata(niftiHeader, orientation, scalarData,
62
53
  ]),
63
54
  };
64
55
  }
65
- //# sourceMappingURL=makeVolumeMetadata.js.map
@@ -1,4 +1,4 @@
1
- import { Types } from '@cornerstonejs/core';
1
+ import type { Types } from '@cornerstonejs/core';
2
2
  export default function modalityScaleNifti(niftiHeader: any, niftiImageBuffer: any): {
3
3
  scalarData: Types.PixelDataTypedArray;
4
4
  pixelRepresentation: number;
@@ -1,6 +1,5 @@
1
- import { cache, Enums, getShouldUseSharedArrayBuffer, utilities, } from '@cornerstonejs/core';
1
+ import { cache, Enums } from '@cornerstonejs/core';
2
2
  import * as NIFTICONSTANTS from './niftiConstants';
3
- const { createFloat32SharedArray, createInt16SharedArray, createUint8SharedArray, createUint16SharedArray, } = utilities;
4
3
  export default function modalityScaleNifti(niftiHeader, niftiImageBuffer) {
5
4
  const { datatypeCode, scl_slope, scl_inter } = niftiHeader;
6
5
  let slope = scl_slope;
@@ -101,43 +100,32 @@ function checkCacheAvailable(bitsAllocated, length) {
101
100
  function allocateScalarData(types, niiBuffer) {
102
101
  let bitsAllocated;
103
102
  let scalarData;
104
- const useSharedArrayBuffer = getShouldUseSharedArrayBuffer();
105
103
  const nVox = niiBuffer.length;
106
104
  switch (types) {
107
105
  case 'Float32Array':
108
106
  bitsAllocated = 32;
109
107
  checkCacheAvailable(bitsAllocated, nVox);
110
- scalarData = useSharedArrayBuffer
111
- ? createFloat32SharedArray(nVox)
112
- : new Float32Array(nVox);
108
+ scalarData = new Float32Array(nVox);
113
109
  break;
114
110
  case 'Int16Array':
115
111
  bitsAllocated = 16;
116
112
  checkCacheAvailable(bitsAllocated, nVox);
117
- scalarData = useSharedArrayBuffer
118
- ? createInt16SharedArray(nVox)
119
- : new Int16Array(nVox);
113
+ scalarData = new Int16Array(nVox);
120
114
  break;
121
115
  case 'Int8Array':
122
116
  bitsAllocated = 8;
123
117
  checkCacheAvailable(bitsAllocated, nVox);
124
- scalarData = useSharedArrayBuffer
125
- ? createInt16SharedArray(nVox)
126
- : new Int16Array(nVox);
118
+ scalarData = new Int16Array(nVox);
127
119
  break;
128
120
  case 'Uint16Array':
129
121
  bitsAllocated = 16;
130
122
  checkCacheAvailable(bitsAllocated, nVox);
131
- scalarData = useSharedArrayBuffer
132
- ? createUint16SharedArray(nVox)
133
- : new Uint16Array(nVox);
123
+ scalarData = new Uint16Array(nVox);
134
124
  break;
135
125
  case 'Uint8Array':
136
126
  bitsAllocated = 8;
137
127
  checkCacheAvailable(bitsAllocated, nVox);
138
- scalarData = useSharedArrayBuffer
139
- ? createUint8SharedArray(nVox)
140
- : new Uint8Array(nVox);
128
+ scalarData = new Uint8Array(nVox);
141
129
  break;
142
130
  default:
143
131
  throw new Error(`TypedArray ${types} is not yet supported`);
@@ -145,4 +133,3 @@ function allocateScalarData(types, niiBuffer) {
145
133
  scalarData.set(niiBuffer);
146
134
  return scalarData;
147
135
  }
148
- //# sourceMappingURL=modalityScaleNifti.js.map
@@ -41,4 +41,3 @@ const NIFTI1_HEADER_ENDOFFILE_STRING = '0000';
41
41
  const NIFTI1_ALIGNED_ANAT = 2;
42
42
  const NIFTI1_XYZT_UNITS_UNKNOWN = 0;
43
43
  export { NIFTI_TYPE_UINT8, NIFTI_TYPE_INT16, NIFTI_TYPE_INT32, NIFTI_TYPE_FLOAT32, NIFTI_TYPE_COMPLEX64, NIFTI_TYPE_FLOAT64, NIFTI_TYPE_RGB24, NIFTI_TYPE_INT8, NIFTI_TYPE_UINT16, NIFTI_TYPE_UINT32, NIFTI_TYPE_INT64, NIFTI_TYPE_UINT64, NIFTI_TYPE_FLOAT128, NIFTI_TYPE_COMPLEX128, NIFTI_TYPE_COMPLEX256, NIFTI_TYPE_RGBA32, NIFTI2_HEADER_TOTAL_LENGTH_BYTES, NIFTI2_HEADER_TOTAL_LENGTH_BITS, NIFTI2_HEADER_MAGIC_LENGTH_BYTES, NIFTI2_HEADER_DESCRIPTION_LENGTH_BYTES, NIFTI2_HEADER_AUX_FILE_LENGTH_BYTES, NIFTI2_HEADER_INTENT_NAME_LENGTH_BYTES, NIFTI2_HEADER_DIM_INFO_LENGTH_BYTES, NIFTI2_HEADER_ENDOFFILE_LENGTH_BYTES, NIFTI2_VOX_OFFSET_BYTES, NIFTI2_HEADER_MAGIC_STRING, NIFTI2_HEADER_ENDOFFILE_STRING, NIFTI2_ALIGNED_ANAT, NIFTI2_XYZT_UNITS_UNKNOWN, NIFTI1_HEADER_TOTAL_LENGTH_BYTES, NIFTI1_HEADER_TOTAL_LENGTH_BITS, NIFTI1_HEADER_MAGIC_LENGTH_BYTES, NIFTI1_HEADER_DESCRIPTION_LENGTH_BYTES, NIFTI1_HEADER_AUX_FILE_LENGTH_BYTES, NIFTI1_HEADER_INTENT_NAME_LENGTH_BYTES, NIFTI1_HEADER_DIM_INFO_LENGTH_BYTES, NIFTI1_HEADER_ENDOFFILE_LENGTH_BYTES, NIFTI1_VOX_OFFSET_BYTES, NIFTI1_HEADER_MAGIC_STRING, NIFTI1_HEADER_ENDOFFILE_STRING, NIFTI1_ALIGNED_ANAT, NIFTI1_XYZT_UNITS_UNKNOWN, };
44
- //# sourceMappingURL=niftiConstants.js.map
@@ -1,5 +1,5 @@
1
- import cornerstoneNiftiImageVolumeLoader from './cornerstoneNiftiImageLoader';
2
- import NiftiImageVolume from './NiftiImageVolume';
1
+ import cornerstoneNiftiImageLoader from './cornerstoneNiftiImageLoader';
3
2
  import * as helpers from './helpers';
4
3
  import * as Enums from './enums';
5
- export { cornerstoneNiftiImageVolumeLoader, NiftiImageVolume, helpers, Enums };
4
+ import { createNiftiImageIdsAndCacheMetadata } from './createNiftiImageIdsAndCacheMetadata';
5
+ export { cornerstoneNiftiImageLoader, helpers, Enums, createNiftiImageIdsAndCacheMetadata, };
package/dist/esm/index.js CHANGED
@@ -1,6 +1,5 @@
1
- import cornerstoneNiftiImageVolumeLoader from './cornerstoneNiftiImageLoader';
2
- import NiftiImageVolume from './NiftiImageVolume';
1
+ import cornerstoneNiftiImageLoader from './cornerstoneNiftiImageLoader';
3
2
  import * as helpers from './helpers';
4
3
  import * as Enums from './enums';
5
- export { cornerstoneNiftiImageVolumeLoader, NiftiImageVolume, helpers, Enums };
6
- //# sourceMappingURL=index.js.map
4
+ import { createNiftiImageIdsAndCacheMetadata } from './createNiftiImageIdsAndCacheMetadata';
5
+ export { cornerstoneNiftiImageLoader, helpers, Enums, createNiftiImageIdsAndCacheMetadata, };