larvitar 0.18.2 → 1.2.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.
- package/.github/workflows/deploy.yml +3 -12
- package/MIGRATION.md +25 -0
- package/README.md +28 -27
- package/docs/documentation/Mixins.polygonSegmentationMixin%20-%20segmentation%20operations%20for%20polyline.html +171 -0
- package/docs/documentation/Tools.Annotation.ContoursTool.html +218 -0
- package/docs/documentation/Tools.Annotation.DiameterTool.html +219 -0
- package/docs/documentation/Tools.Annotation.SeedsTool.html +214 -0
- package/docs/documentation/Tools.Brush.BrushTool.html +218 -0
- package/docs/documentation/Tools.Brush.ThresholdsBrushTool.html +218 -0
- package/docs/documentation/Tools.PolylineScissorsTool.html +218 -0
- package/docs/documentation/fonts/Montserrat/Montserrat-Bold.eot +0 -0
- package/docs/documentation/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
- package/docs/documentation/fonts/Montserrat/Montserrat-Bold.woff +0 -0
- package/docs/documentation/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
- package/docs/documentation/fonts/Montserrat/Montserrat-Regular.eot +0 -0
- package/docs/documentation/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
- package/docs/documentation/fonts/Montserrat/Montserrat-Regular.woff +0 -0
- package/docs/documentation/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- package/docs/documentation/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- package/docs/documentation/global.html +1303 -0
- package/docs/documentation/imageAnonymization.js.html +245 -0
- package/docs/documentation/imageColormaps.js.html +283 -0
- package/docs/documentation/imageContours.js.html +278 -0
- package/docs/documentation/imageIo.js.html +291 -0
- package/docs/documentation/imageLayers.js.html +188 -0
- package/docs/documentation/imageLoading.js.html +297 -0
- package/docs/documentation/imageParsing.js.html +385 -0
- package/docs/documentation/imagePresets.js.html +207 -0
- package/docs/documentation/imageRendering.js.html +849 -0
- package/docs/documentation/imageReslice.js.html +162 -0
- package/docs/documentation/imageStore.js.html +360 -0
- package/docs/documentation/imageTools.js.html +784 -0
- package/docs/documentation/imageUtils.js.html +1609 -0
- package/docs/documentation/image_colormaps.js.html +283 -0
- package/docs/documentation/image_contours.js.html +279 -0
- package/docs/documentation/image_io.js.html +288 -0
- package/docs/documentation/image_layers.js.html +188 -0
- package/docs/documentation/image_loading.js.html +294 -0
- package/docs/documentation/image_parsing.js.html +391 -0
- package/docs/documentation/image_presets.js.html +207 -0
- package/docs/documentation/image_rendering.js.html +845 -0
- package/docs/documentation/image_reslice.js.html +164 -0
- package/docs/documentation/image_store.js.html +359 -0
- package/docs/documentation/image_tools.js.html +792 -0
- package/docs/documentation/image_utils.js.html +1609 -0
- package/docs/documentation/index.html +175 -0
- package/docs/documentation/loaders_commonLoader.js.html +306 -0
- package/docs/documentation/loaders_dicomLoader.js.html +130 -0
- package/docs/documentation/loaders_fileLoader.js.html +155 -0
- package/docs/documentation/loaders_multiframeLoader.js.html +443 -0
- package/docs/documentation/loaders_niftiLoader.js.html +150 -0
- package/docs/documentation/loaders_nrrdLoader.js.html +545 -0
- package/docs/documentation/loaders_resliceLoader.js.html +258 -0
- package/docs/documentation/module-imaging_contours.html +954 -0
- package/docs/documentation/module-imaging_imageAnonymization.html +544 -0
- package/docs/documentation/module-imaging_imageColormaps.html +1012 -0
- package/docs/documentation/module-imaging_imageContours.html +954 -0
- package/docs/documentation/module-imaging_imageIo.html +1057 -0
- package/docs/documentation/module-imaging_imageLayers.html +904 -0
- package/docs/documentation/module-imaging_imageLoading.html +1301 -0
- package/docs/documentation/module-imaging_imageParsing.html +1356 -0
- package/docs/documentation/module-imaging_imagePresets.html +679 -0
- package/docs/documentation/module-imaging_imageRendering.html +3223 -0
- package/docs/documentation/module-imaging_imageReslice.html +413 -0
- package/docs/documentation/module-imaging_imageStore-Larvitar_Store.html +284 -0
- package/docs/documentation/module-imaging_imageStore.html +1560 -0
- package/docs/documentation/module-imaging_imageTools.html +3617 -0
- package/docs/documentation/module-imaging_imageUtils.html +7253 -0
- package/docs/documentation/module-imaging_io.html +1057 -0
- package/docs/documentation/module-imaging_layers.html +904 -0
- package/docs/documentation/module-imaging_loading.html +1301 -0
- package/docs/documentation/module-imaging_parsing.html +1375 -0
- package/docs/documentation/module-imaging_presets.html +679 -0
- package/docs/documentation/module-imaging_rendering.html +8094 -0
- package/docs/documentation/module-imaging_reslice.html +411 -0
- package/docs/documentation/module-imaging_store-Larvitar_Store.html +284 -0
- package/docs/documentation/module-imaging_store.html +1537 -0
- package/docs/documentation/module-imaging_strategies_eraseFreehand.html +708 -0
- package/docs/documentation/module-imaging_strategies_fillFreehand.html +708 -0
- package/docs/documentation/module-imaging_tools.html +3617 -0
- package/docs/documentation/module-imaging_tools_custom_contourTool.html +207 -0
- package/docs/documentation/module-imaging_tools_custom_diameterTool.html +205 -0
- package/docs/documentation/module-imaging_tools_custom_editMaskTool.html +205 -0
- package/docs/documentation/module-imaging_tools_custom_polygonScissorsTool.html +203 -0
- package/docs/documentation/module-imaging_tools_custom_thresholdBrushTool.html +684 -0
- package/docs/documentation/module-imaging_tools_default.html +205 -0
- package/docs/documentation/module-imaging_tools_interaction.html +530 -0
- package/docs/documentation/module-imaging_tools_io.html +832 -0
- package/docs/documentation/module-imaging_tools_main.html +2028 -0
- package/docs/documentation/module-imaging_tools_polygonSegmentationMixin.html +567 -0
- package/docs/documentation/module-imaging_tools_segmentation.html +3586 -0
- package/docs/documentation/module-imaging_tools_state.html +494 -0
- package/docs/documentation/module-imaging_utils.html +7253 -0
- package/docs/documentation/module-loaders_commonLoader.html +1313 -0
- package/docs/documentation/module-loaders_dicomLoader.html +522 -0
- package/docs/documentation/module-loaders_fileLoader.html +593 -0
- package/docs/documentation/module-loaders_multiframeLoader.html +1169 -0
- package/docs/documentation/module-loaders_niftiLoader.html +565 -0
- package/docs/documentation/module-loaders_nrrdLoader.html +1459 -0
- package/docs/documentation/module-loaders_resliceLoader.html +590 -0
- package/docs/documentation/module-monitors_memory.html +980 -0
- package/docs/documentation/module-tools_default.html +740 -0
- package/docs/documentation/module.exports_module.exports.html +203 -0
- package/docs/documentation/monitors_memory.js.html +189 -0
- package/docs/documentation/parsers_nrrd.js.html +569 -0
- package/docs/documentation/scripts/collapse.js +20 -0
- package/docs/documentation/scripts/linenumber.js +25 -0
- package/docs/documentation/scripts/nav.js +12 -0
- package/docs/documentation/scripts/polyfill.js +4 -0
- package/docs/documentation/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/documentation/scripts/prettify/lang-css.js +2 -0
- package/docs/documentation/scripts/prettify/prettify.js +28 -0
- package/docs/documentation/scripts/search.js +83 -0
- package/docs/documentation/styles/jsdoc.css +765 -0
- package/docs/documentation/styles/prettify.css +80 -0
- package/docs/documentation/tools_contourTool.js.html +1963 -0
- package/docs/documentation/tools_custom_contourTool.js.html +1968 -0
- package/docs/documentation/tools_custom_diameterTool.js.html +225 -0
- package/docs/documentation/tools_custom_editMaskTool.js.html +225 -0
- package/docs/documentation/tools_custom_polylineScissorsTool.js.html +143 -0
- package/docs/documentation/tools_custom_thresholdsBrushTool.js.html +245 -0
- package/docs/documentation/tools_default.js.html +576 -0
- package/docs/documentation/tools_diameterTool.js.html +219 -0
- package/docs/documentation/tools_editMaskTool.js.html +219 -0
- package/docs/documentation/tools_interaction.js.html +258 -0
- package/docs/documentation/tools_io.js.html +297 -0
- package/docs/documentation/tools_main.js.html +443 -0
- package/docs/documentation/tools_polygonSegmentationMixin.js.html +329 -0
- package/docs/documentation/tools_polylineScissorsTool.js.html +136 -0
- package/docs/documentation/tools_seedTool.js.html +423 -0
- package/docs/documentation/tools_segmentation.js.html +558 -0
- package/docs/documentation/tools_state.js.html +163 -0
- package/docs/documentation/tools_strategies_eraseFreehand.js.html +160 -0
- package/docs/documentation/tools_strategies_fillFreehand.js.html +163 -0
- package/docs/documentation/tools_thresholdsBrushTool.js.html +239 -0
- package/docs/documentation/tools_tools.default.js.html +569 -0
- package/docs/documentation/tools_tools.interaction.js.html +251 -0
- package/docs/documentation/tools_tools.io.js.html +288 -0
- package/docs/documentation/tools_tools.main.js.html +442 -0
- package/docs/documentation/tools_tools.segmentation.js.html +445 -0
- package/docs/documentation/tools_tools.state.js.html +157 -0
- package/docs/examples/base.html +170 -0
- package/docs/examples/colorMaps.html +181 -0
- package/docs/examples/defaultTools.html +246 -0
- package/docs/examples/demo/anon1 +0 -0
- package/docs/examples/demo/anon10 +0 -0
- package/docs/examples/demo/anon11 +0 -0
- package/docs/examples/demo/anon12 +0 -0
- package/docs/examples/demo/anon13 +0 -0
- package/docs/examples/demo/anon14 +0 -0
- package/docs/examples/demo/anon15 +0 -0
- package/docs/examples/demo/anon16 +0 -0
- package/docs/examples/demo/anon17 +0 -0
- package/docs/examples/demo/anon18 +0 -0
- package/docs/examples/demo/anon19 +0 -0
- package/docs/examples/demo/anon2 +0 -0
- package/docs/examples/demo/anon20 +0 -0
- package/docs/examples/demo/anon21 +0 -0
- package/docs/examples/demo/anon22 +0 -0
- package/docs/examples/demo/anon23 +0 -0
- package/docs/examples/demo/anon24 +0 -0
- package/docs/examples/demo/anon3 +0 -0
- package/docs/examples/demo/anon4 +0 -0
- package/docs/examples/demo/anon5 +0 -0
- package/docs/examples/demo/anon6 +0 -0
- package/docs/examples/demo/anon7 +0 -0
- package/docs/examples/demo/anon8 +0 -0
- package/docs/examples/demo/anon9 +0 -0
- package/docs/examples/demo/example.nrrd +0 -0
- package/docs/examples/demo/segmentation.nrrd +0 -0
- package/docs/examples/demo/xa_integris.dcm +0 -0
- package/docs/examples/index.html +129 -0
- package/docs/examples/larvitar.js +108623 -0
- package/docs/examples/layers.html +250 -0
- package/docs/examples/masks.html +273 -0
- package/docs/examples/multiframe.html +200 -0
- package/docs/examples/nrrd.html +96 -0
- package/docs/examples/reslice.html +174 -0
- package/docs/index.html +92 -0
- package/imaging/dataDictionary.json +21865 -21865
- package/imaging/imageAnonymization.js +161 -0
- package/imaging/{image_colormaps.js → imageColormaps.js} +2 -2
- package/imaging/{image_contours.js → imageContours.js} +1 -2
- package/imaging/{image_io.js → imageIo.js} +18 -15
- package/imaging/{image_layers.js → imageLayers.js} +2 -2
- package/imaging/{image_loading.js → imageLoading.js} +9 -6
- package/imaging/imageParsing.js +301 -0
- package/imaging/{image_presets.js → imagePresets.js} +2 -2
- package/imaging/{image_rendering.js → imageRendering.js} +36 -32
- package/imaging/imageReslice.js +78 -0
- package/imaging/{image_store.js → imageStore.js} +8 -7
- package/imaging/{image_tools.js → imageTools.js} +15 -23
- package/imaging/{image_utils.js → imageUtils.js} +1 -1
- package/imaging/loaders/commonLoader.js +1 -1
- package/imaging/loaders/dicomLoader.js +1 -1
- package/imaging/loaders/fileLoader.js +2 -2
- package/imaging/loaders/multiframeLoader.js +6 -2
- package/imaging/loaders/nrrdLoader.js +11 -7
- package/imaging/tools/{contourTool.js → custom/contourTool.js} +25 -20
- package/imaging/tools/{diameterTool.js → custom/diameterTool.js} +9 -3
- package/imaging/tools/{editMaskTool.js → custom/editMaskTool.js} +7 -1
- package/imaging/tools/{polylineScissorsTool.js → custom/polylineScissorsTool.js} +12 -5
- package/imaging/tools/{seedTool.js → custom/seedTool.js} +3 -3
- package/imaging/tools/{thresholdsBrushTool.js → custom/thresholdsBrushTool.js} +7 -1
- package/imaging/tools/{tools.default.js → default.js} +10 -3
- package/imaging/tools/{tools.interaction.js → interaction.js} +13 -6
- package/imaging/tools/{tools.io.js → io.js} +15 -6
- package/imaging/tools/{tools.main.js → main.js} +16 -14
- package/imaging/tools/polygonSegmentationMixin.js +8 -4
- package/imaging/tools/{tools.segmentation.js → segmentation.js} +171 -58
- package/imaging/tools/segmentations.md +38 -0
- package/imaging/tools/setLabelMap3D.js +248 -0
- package/imaging/tools/{tools.state.js → state.js} +7 -1
- package/imaging/tools/strategies/eraseFreehand.js +8 -9
- package/imaging/tools/strategies/fillFreehand.js +8 -9
- package/index.js +44 -39
- package/modules/vuex/larvitar.js +13 -3
- package/package.json +13 -10
- package/imaging/image_parsing.js +0 -307
- package/imaging/image_reslice.js +0 -80
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/** @module imaging/imageAnonymization
|
|
2
|
+
* @desc This file provides anonymization functionalities on DICOM images
|
|
3
|
+
* following http://dicom.nema.org/medical/dicom/current/output/html/part15.html#chapter_E
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// external libraries
|
|
7
|
+
import aes from "crypto-js/aes";
|
|
8
|
+
import sha256 from "crypto-js/sha256";
|
|
9
|
+
import Hex from "crypto-js/enc-hex";
|
|
10
|
+
import { forEach } from "lodash";
|
|
11
|
+
|
|
12
|
+
// global vars
|
|
13
|
+
const TAGS = [
|
|
14
|
+
"x00080014", // Instance Creator UID
|
|
15
|
+
"x00080018", // SOP Instance UID
|
|
16
|
+
"x00080050", // Accession Number
|
|
17
|
+
"x00080080", // Institution Name
|
|
18
|
+
"x00080081", // Institution Address
|
|
19
|
+
"x00080081", // Institution Address
|
|
20
|
+
"x00080090", // Referring Physician's Name
|
|
21
|
+
"x00080092", // Referring Physician's Address
|
|
22
|
+
"x00080094", // Referring Physician's Telephone numbers
|
|
23
|
+
"x00081010", // Station Name
|
|
24
|
+
"x00081030", // Study Description
|
|
25
|
+
"x0008103e", // Series Description
|
|
26
|
+
"x00081040", // Institutional Department name
|
|
27
|
+
"x00081048", // Physician(s) of Record
|
|
28
|
+
"x00081050", // Performing Physicians' Name
|
|
29
|
+
"x00081060", // Name of Physician(s) Reading study
|
|
30
|
+
"x00081070", // Operator's Name
|
|
31
|
+
"x00081080", // Admitting Diagnoses Description
|
|
32
|
+
"x00081155", // Referenced SOP Instance UID
|
|
33
|
+
"x00082111", // Derivation Description
|
|
34
|
+
"x00100010", // Patient's Name
|
|
35
|
+
"x00100020", // Patient ID
|
|
36
|
+
"x00100030", // Patient's Birth Date
|
|
37
|
+
"x00100032", // Patient's Birth Time
|
|
38
|
+
"x00100040", // Patient's Sex
|
|
39
|
+
"x00101000", // Other Patient Ids
|
|
40
|
+
"x00101001", // Other Patient Names
|
|
41
|
+
"x00101010", // Patient's Age
|
|
42
|
+
"x00101020", // Patient's Size
|
|
43
|
+
"x00101030", // Patient's Weight
|
|
44
|
+
"x00101090", // Medical Record Locator
|
|
45
|
+
"x00102160", // Ethnic Group
|
|
46
|
+
"x00102180", // Occupation
|
|
47
|
+
"x001021b0", // Additional Patient's History
|
|
48
|
+
"x00104000", // Patient Comments
|
|
49
|
+
"x00181000", // Device Serial Number
|
|
50
|
+
"x00181030", // Protocol Name
|
|
51
|
+
"x0020000d", // Study Instance UID
|
|
52
|
+
"x0020000e", // Series Instance UID
|
|
53
|
+
"x00200010", // Study ID
|
|
54
|
+
"x00200052", // Frame of Reference UID
|
|
55
|
+
"x00200200", // Synchronization Frame of Reference UID
|
|
56
|
+
"x00204000", // Image Comments
|
|
57
|
+
"x00400275", // Request Attributes Sequence
|
|
58
|
+
"x0040a124", // UID
|
|
59
|
+
"x0040a730", // Content Sequence
|
|
60
|
+
"x00880140", // Storage Media File-set UID
|
|
61
|
+
"x30060024", // Referenced Frame of Reference UID
|
|
62
|
+
"x300600c2" // Related Frame of Reference UID
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
/*
|
|
66
|
+
* This module provides the following functions to be exported:
|
|
67
|
+
* anonymize(series)
|
|
68
|
+
* encrypt(series, passphrase)
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Anonymize DICOM series' metadata using sha256
|
|
73
|
+
* @function anonymize
|
|
74
|
+
* @param {Object} series - Cornerstone series object
|
|
75
|
+
* @returns {Object} anonymized_series: Cornerstone anonymized series object
|
|
76
|
+
*/
|
|
77
|
+
export const anonymize = function (series) {
|
|
78
|
+
forEach(series.instances, function (instance) {
|
|
79
|
+
forEach(TAGS, function (tag) {
|
|
80
|
+
if (tag in instance.metadata) {
|
|
81
|
+
let anonymized_value = sha256(instance.metadata[tag]).toString(Hex);
|
|
82
|
+
instance.metadata[tag] = anonymized_value;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
instance.metadata.seriesUID = instance.metadata["x0020000e"];
|
|
86
|
+
instance.metadata.instanceUID = instance.metadata["x00080018"];
|
|
87
|
+
instance.metadata.studyUID = instance.metadata["x0020000d"];
|
|
88
|
+
instance.metadata.accessionNumber = instance.metadata["x00080050"];
|
|
89
|
+
instance.metadata.studyDescription = instance.metadata["x00081030"];
|
|
90
|
+
instance.metadata.patientName = instance.metadata["x00100010"];
|
|
91
|
+
instance.metadata.patientBirthdate = instance.metadata["x00100030"];
|
|
92
|
+
instance.metadata.seriesDescription = instance.metadata["x0008103e"];
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
delete series["instanceUIDs"];
|
|
96
|
+
series.instanceUIDs = {};
|
|
97
|
+
|
|
98
|
+
forEach(series.imageIds, function (imageId) {
|
|
99
|
+
series.instanceUIDs[series.instances[imageId].metadata.instanceUID] =
|
|
100
|
+
imageId;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
series.larvitarSeriesInstanceUID = sha256(
|
|
104
|
+
series.larvitarSeriesInstanceUID
|
|
105
|
+
).toString(Hex);
|
|
106
|
+
series.seriesUID = sha256(series.seriesUID).toString(Hex);
|
|
107
|
+
series.seriesDescription = sha256(series.seriesDescription).toString(Hex);
|
|
108
|
+
series.studyUID = sha256(series.studyUID).toString(Hex);
|
|
109
|
+
|
|
110
|
+
return series;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Encrypt DICOM series' metadata using AES
|
|
115
|
+
* @function encrypt
|
|
116
|
+
* @param {Object} series - Cornerstone series object
|
|
117
|
+
* @param {String} passphrase - AES passphrase
|
|
118
|
+
* @returns {Object} anonymized_series: Cornerstone encrypted series object
|
|
119
|
+
*/
|
|
120
|
+
export const encrypt = function (series, passphrase) {
|
|
121
|
+
if (!passphrase) {
|
|
122
|
+
return "Error, provide a valid passphrase";
|
|
123
|
+
}
|
|
124
|
+
forEach(series.instances, function (instance) {
|
|
125
|
+
forEach(TAGS, function (tag) {
|
|
126
|
+
if (tag in instance.metadata) {
|
|
127
|
+
let anonymized_value = aes
|
|
128
|
+
.encrypt(instance.metadata[tag], passphrase)
|
|
129
|
+
.toString();
|
|
130
|
+
instance.metadata[tag] = anonymized_value;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
instance.metadata.seriesUID = instance.metadata["x0020000e"];
|
|
134
|
+
instance.metadata.instanceUID = instance.metadata["x00080018"];
|
|
135
|
+
instance.metadata.studyUID = instance.metadata["x0020000d"];
|
|
136
|
+
instance.metadata.accessionNumber = instance.metadata["x00080050"];
|
|
137
|
+
instance.metadata.studyDescription = instance.metadata["x00081030"];
|
|
138
|
+
instance.metadata.patientName = instance.metadata["x00100010"];
|
|
139
|
+
instance.metadata.patientBirthdate = instance.metadata["x00100030"];
|
|
140
|
+
instance.metadata.seriesDescription = instance.metadata["x0008103e"];
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
delete series["instanceUIDs"];
|
|
144
|
+
series.instanceUIDs = {};
|
|
145
|
+
|
|
146
|
+
forEach(series.imageIds, function (imageId) {
|
|
147
|
+
series.instanceUIDs[series.instances[imageId].metadata.instanceUID] =
|
|
148
|
+
imageId;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
series.larvitarSeriesInstanceUID = aes
|
|
152
|
+
.encrypt(series.larvitarSeriesInstanceUID, passphrase)
|
|
153
|
+
.toString();
|
|
154
|
+
series.seriesUID = aes.encrypt(series.seriesUID, passphrase).toString();
|
|
155
|
+
series.seriesDescription = aes
|
|
156
|
+
.encrypt(series.seriesDescription, passphrase)
|
|
157
|
+
.toString();
|
|
158
|
+
series.studyUID = aes.encrypt(series.studyUID, passphrase).toString();
|
|
159
|
+
|
|
160
|
+
return series;
|
|
161
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @module imaging/
|
|
1
|
+
/** @module imaging/imageContours
|
|
2
2
|
* @desc This file provides functionalities to render a set of points on a canvas.
|
|
3
3
|
* Use this in order to render image contours (e.g. from binary masks).
|
|
4
4
|
*/
|
|
@@ -21,7 +21,6 @@ import { each, range } from "lodash";
|
|
|
21
21
|
* @param {Array} viewports - Viewport array ids
|
|
22
22
|
* @returns {Number} Number of array elements consumed
|
|
23
23
|
*/
|
|
24
|
-
|
|
25
24
|
export const parseContours = function (
|
|
26
25
|
contoursData,
|
|
27
26
|
pointBatchSize,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @module imaging/
|
|
1
|
+
/** @module imaging/imageIo
|
|
2
2
|
* @desc This file provides I/O functionalities on NRRD files and DICOM images
|
|
3
3
|
*/
|
|
4
4
|
|
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
getMeanValue,
|
|
12
12
|
getDistanceBetweenSlices,
|
|
13
13
|
getTypedArrayFromDataType
|
|
14
|
-
} from "./
|
|
15
|
-
import { larvitar_store } from "./
|
|
14
|
+
} from "./imageUtils.js";
|
|
15
|
+
import { larvitar_store } from "./imageStore";
|
|
16
16
|
import { parse } from "./parsers/nrrd";
|
|
17
17
|
import { checkMemoryAllocation } from "./monitors/memory";
|
|
18
18
|
|
|
@@ -71,22 +71,25 @@ export const buildHeader = function (series) {
|
|
|
71
71
|
* Get cached pixel data
|
|
72
72
|
* @function getCachedPixelData
|
|
73
73
|
* @param {String} imageId - ImageId of the cached image
|
|
74
|
-
* @returns {
|
|
74
|
+
* @returns {Promise} A promise which will resolve to a pixel data array or fail if an error occurs
|
|
75
75
|
*/
|
|
76
76
|
|
|
77
|
-
export const getCachedPixelData = function (imageId
|
|
77
|
+
export const getCachedPixelData = function (imageId) {
|
|
78
78
|
let cachedImage = find(cornerstone.imageCache.cachedImages, [
|
|
79
79
|
"imageId",
|
|
80
80
|
imageId
|
|
81
81
|
]);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
let promise = new Promise((resolve, reject) => {
|
|
83
|
+
if (cachedImage && cachedImage.image) {
|
|
84
|
+
resolve(cachedImage.image.getPixelData());
|
|
85
|
+
} else {
|
|
86
|
+
cornerstone
|
|
87
|
+
.loadImage(imageId)
|
|
88
|
+
.then(image => resolve(image.getPixelData()))
|
|
89
|
+
.catch(err => reject(err));
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return promise;
|
|
90
93
|
};
|
|
91
94
|
|
|
92
95
|
/**
|
|
@@ -122,7 +125,7 @@ export const buildData = function (series, useSeriesData) {
|
|
|
122
125
|
} else {
|
|
123
126
|
larvitar_store.addSeriesIds(series.seriesUID, series.imageIds);
|
|
124
127
|
forEach(series.imageIds, function (imageId) {
|
|
125
|
-
getCachedPixelData(imageId
|
|
128
|
+
getCachedPixelData(imageId).then(sliceData => {
|
|
126
129
|
data.set(sliceData, offsetData);
|
|
127
130
|
offsetData += sliceData.length;
|
|
128
131
|
});
|
|
@@ -166,7 +169,7 @@ export const buildDataAsync = function (series, time, resolve, reject) {
|
|
|
166
169
|
function runFillPixelData(data) {
|
|
167
170
|
let imageId = imageIds.shift();
|
|
168
171
|
if (imageId) {
|
|
169
|
-
getCachedPixelData(imageId
|
|
172
|
+
getCachedPixelData(imageId).then(sliceData => {
|
|
170
173
|
data.set(sliceData, offsetData);
|
|
171
174
|
offsetData += sliceData.length;
|
|
172
175
|
// this does the trick: delay next computation to next tick
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @module imaging/
|
|
1
|
+
/** @module imaging/imageLayers
|
|
2
2
|
* @desc This file provides functionalities for
|
|
3
3
|
* rendering image layers using cornerstone stack
|
|
4
4
|
*/
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import cornerstone from "cornerstone-core";
|
|
8
8
|
|
|
9
9
|
// internal libraries
|
|
10
|
-
import { isElement } from "./
|
|
10
|
+
import { isElement } from "./imageUtils";
|
|
11
11
|
|
|
12
12
|
/*
|
|
13
13
|
* This module provides the following functions to be exported:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @module imaging/
|
|
1
|
+
/** @module imaging/imageLoading
|
|
2
2
|
* @desc This file provides functionalities for
|
|
3
3
|
* initialize, configure and update WadoImageLoader
|
|
4
4
|
*/
|
|
@@ -12,8 +12,8 @@ import cornerstoneFileImageLoader from "cornerstone-file-image-loader";
|
|
|
12
12
|
import { forEach } from "lodash";
|
|
13
13
|
|
|
14
14
|
// internal libraries
|
|
15
|
-
import { larvitar_store } from "./
|
|
16
|
-
import { getSortedStack, getSortedUIDs } from "./
|
|
15
|
+
import { larvitar_store } from "./imageStore";
|
|
16
|
+
import { getSortedStack, getSortedUIDs } from "./imageUtils";
|
|
17
17
|
import { loadNrrdImage } from "./loaders/nrrdLoader";
|
|
18
18
|
import { loadReslicedImage } from "./loaders/resliceLoader";
|
|
19
19
|
import { loadMultiFrameImage } from "./loaders/multiframeLoader";
|
|
@@ -26,16 +26,19 @@ import { loadMultiFrameImage } from "./loaders/multiframeLoader";
|
|
|
26
26
|
* @property {String} webWorkerPath - path to default WADO web worker
|
|
27
27
|
* @property {} - see https://github.com/cornerstonejs/cornerstoneWADOImageLoader/blob/master/docs/WebWorkers.md
|
|
28
28
|
*/
|
|
29
|
+
|
|
29
30
|
const globalConfig = {
|
|
30
31
|
maxWebWorkers: navigator.hardwareConcurrency || 1,
|
|
31
|
-
webWorkerPath: "/cornerstoneWADOImageLoaderWebWorker.js",
|
|
32
32
|
startWebWorkersOnDemand: true,
|
|
33
|
+
webWorkerTaskPaths: [
|
|
34
|
+
"https://unpkg.com/cornerstone-wado-image-loader@4.1.0/dist/610.bundle.min.worker.js",
|
|
35
|
+
"https://unpkg.com/cornerstone-wado-image-loader@4.1.0/dist/888.bundle.min.worker.js"
|
|
36
|
+
],
|
|
33
37
|
taskConfiguration: {
|
|
34
38
|
decodeTask: {
|
|
35
39
|
loadCodecsOnStartup: true,
|
|
36
40
|
initializeCodecsOnStartup: false,
|
|
37
|
-
|
|
38
|
-
usePDFJS: false
|
|
41
|
+
strict: true
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
};
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/** @module imaging/imageParsing
|
|
2
|
+
* @desc This file provides functionalities for parsing DICOM image files
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// external libraries
|
|
6
|
+
import { parseDicom } from "dicom-parser";
|
|
7
|
+
import { forEach, each, has, pick } from "lodash";
|
|
8
|
+
|
|
9
|
+
// internal libraries
|
|
10
|
+
import { getPixelRepresentation, randomId, parseTag } from "./imageUtils.js";
|
|
11
|
+
import { updateLoadedStack } from "./imageLoading.js";
|
|
12
|
+
import { checkMemoryAllocation } from "./monitors/memory.js";
|
|
13
|
+
|
|
14
|
+
// global module variables
|
|
15
|
+
var t0 = null; // t0 variable for timing debugging purpose
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* This module provides the following functions to be exported:
|
|
19
|
+
* readFiles(fileList)
|
|
20
|
+
* readFile(file)
|
|
21
|
+
* parseDataSet(dataSet, metadata, customFilter)
|
|
22
|
+
* clearImageParsing(seriesStack)
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Reset series stack object and its internal data
|
|
27
|
+
* @instance
|
|
28
|
+
* @function clearImageParsing
|
|
29
|
+
* @param {Object} seriesStack - Parsed series stack object
|
|
30
|
+
*/
|
|
31
|
+
export const clearImageParsing = function (seriesStack) {
|
|
32
|
+
each(seriesStack, function (stack) {
|
|
33
|
+
each(stack.instances, function (instance) {
|
|
34
|
+
if (instance.dataSet) {
|
|
35
|
+
instance.dataSet.byteArray = null;
|
|
36
|
+
}
|
|
37
|
+
instance.dataSet = null;
|
|
38
|
+
instance.file = null;
|
|
39
|
+
instance.metadata = null;
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
seriesStack = null;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Read dicom files and return allSeriesStack object
|
|
47
|
+
* @instance
|
|
48
|
+
* @function readFiles
|
|
49
|
+
* @param {Array} entries - List of file objects
|
|
50
|
+
* @returns {Promise} - Return a promise which will resolve to a image object list or fail if an error occurs
|
|
51
|
+
*/
|
|
52
|
+
export const readFiles = function (entries) {
|
|
53
|
+
let promise = new Promise((resolve, reject) => {
|
|
54
|
+
parseFiles(entries).then(resolve).catch(reject);
|
|
55
|
+
});
|
|
56
|
+
return promise;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Read a single dicom file and return parsed object
|
|
61
|
+
* @instance
|
|
62
|
+
* @function readFile
|
|
63
|
+
* @param {File} entry - File object
|
|
64
|
+
* @returns {Promise} - Return a promise which will resolve to a image object or fail if an error occurs
|
|
65
|
+
*/
|
|
66
|
+
export const readFile = function (entry) {
|
|
67
|
+
let promise = new Promise((resolve, reject) => {
|
|
68
|
+
parseFile(entry).then(resolve).catch(reject);
|
|
69
|
+
});
|
|
70
|
+
return promise;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/* Internal module functions */
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Parse metadata from dicom parser dataSet object
|
|
77
|
+
* @instance
|
|
78
|
+
* @function parseDataSet
|
|
79
|
+
* @param {Object} dataSet - dicom parser dataSet object
|
|
80
|
+
* @param {Array} metadata - Initialized metadata object
|
|
81
|
+
* @param {Array} customFilter - Optional filter: {tags:[], frameId: 0}
|
|
82
|
+
*/
|
|
83
|
+
// This function iterates through dataSet recursively and adds new HTML strings
|
|
84
|
+
// to the output array passed into it
|
|
85
|
+
export const parseDataSet = function (dataSet, metadata, customFilter) {
|
|
86
|
+
// customFilter= {tags:[], frameId:xxx}
|
|
87
|
+
// the dataSet.elements object contains properties for each element parsed. The name of the property
|
|
88
|
+
// is based on the elements tag and looks like 'xGGGGEEEE' where GGGG is the group number and EEEE is the
|
|
89
|
+
// element number both with lowercase hexadecimal letters. For example, the Series Description DICOM element 0008,103E would
|
|
90
|
+
// be named 'x0008103e'. Here we iterate over each property (element) so we can build a string describing its
|
|
91
|
+
// contents to add to the output array
|
|
92
|
+
try {
|
|
93
|
+
let elements =
|
|
94
|
+
customFilter && has(customFilter, "tags")
|
|
95
|
+
? pick(dataSet.elements, customFilter.tags)
|
|
96
|
+
: dataSet.elements;
|
|
97
|
+
for (let propertyName in elements) {
|
|
98
|
+
let element = elements[propertyName];
|
|
99
|
+
// Here we check for Sequence items and iterate over them if present. items will not be set in the
|
|
100
|
+
// element object for elements that don't have SQ VR type. Note that implicit little endian
|
|
101
|
+
// sequences will are currently not parsed.
|
|
102
|
+
if (element.items) {
|
|
103
|
+
// each item contains its own data set so we iterate over the items
|
|
104
|
+
// and recursively call this function
|
|
105
|
+
if (customFilter && has(customFilter, "frameId")) {
|
|
106
|
+
let item = element.items[customFilter.frameId];
|
|
107
|
+
parseDataSet(item.dataSet, metadata);
|
|
108
|
+
} else {
|
|
109
|
+
element.items.forEach(function (item) {
|
|
110
|
+
parseDataSet(item.dataSet, metadata);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
let tagValue = parseTag(dataSet, propertyName, element);
|
|
115
|
+
metadata[propertyName] = tagValue;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch (err) {
|
|
119
|
+
console.log(err);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Manage the parsing process waiting for the parsed object before proceeding with the next parse request
|
|
125
|
+
* @inner
|
|
126
|
+
* @function parseNextFile
|
|
127
|
+
* @param {Array} parsingQueue - Array of queued files to be parsed
|
|
128
|
+
* @param {Object} allSeriesStack - Series stack object to be populated
|
|
129
|
+
* @param {Function} resolve - Promise resolve function
|
|
130
|
+
* @param {Function} reject - Promise reject function
|
|
131
|
+
*/
|
|
132
|
+
let parseNextFile = function (parsingQueue, allSeriesStack, resolve, reject) {
|
|
133
|
+
// initialize t0 on first file of the queue
|
|
134
|
+
if (
|
|
135
|
+
Object.keys(allSeriesStack).length === 0 &&
|
|
136
|
+
allSeriesStack.constructor === Object
|
|
137
|
+
) {
|
|
138
|
+
t0 = performance.now();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (parsingQueue.length === 0) {
|
|
142
|
+
let t1 = performance.now();
|
|
143
|
+
console.log(`Call to readFiles took ${t1 - t0} milliseconds.`);
|
|
144
|
+
resolve(allSeriesStack);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// remove and return first item from queue
|
|
149
|
+
let file = parsingQueue.shift();
|
|
150
|
+
|
|
151
|
+
// Check if there is enough memory to parse the file
|
|
152
|
+
if (checkMemoryAllocation(file.size) === false) {
|
|
153
|
+
// do not parse the file and stop parsing
|
|
154
|
+
clearImageParsing(allSeriesStack);
|
|
155
|
+
let t1 = performance.now();
|
|
156
|
+
console.log(`Call to readFiles took ${t1 - t0} milliseconds.`);
|
|
157
|
+
file = null;
|
|
158
|
+
reject(allSeriesStack, "Available memory is not enough");
|
|
159
|
+
return;
|
|
160
|
+
} else {
|
|
161
|
+
// parse the file and wait for results
|
|
162
|
+
parseFile(file)
|
|
163
|
+
.then(seriesData => {
|
|
164
|
+
// add file to cornerstoneWADOImageLoader file manager
|
|
165
|
+
updateLoadedStack(seriesData, allSeriesStack);
|
|
166
|
+
// proceed with the next file to parse
|
|
167
|
+
parseNextFile(parsingQueue, allSeriesStack, resolve, reject);
|
|
168
|
+
seriesData = null;
|
|
169
|
+
file = null;
|
|
170
|
+
})
|
|
171
|
+
.catch(err => {
|
|
172
|
+
console.warn(err);
|
|
173
|
+
parseNextFile(parsingQueue, allSeriesStack, resolve, reject);
|
|
174
|
+
file = null;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Push files in queue and start parsing next file
|
|
181
|
+
* @inner
|
|
182
|
+
* @function parseFiles
|
|
183
|
+
* @param {Array} fileList - Array of file objects
|
|
184
|
+
* @returns {Promise} - Return a promise which will resolve to a image object list or fail if an error occurs
|
|
185
|
+
*/
|
|
186
|
+
let parseFiles = function (fileList) {
|
|
187
|
+
let allSeriesStack = {};
|
|
188
|
+
let parsingQueue = [];
|
|
189
|
+
|
|
190
|
+
forEach(fileList, function (file) {
|
|
191
|
+
if (!file.name.startsWith(".") && !file.name.startsWith("DICOMDIR")) {
|
|
192
|
+
parsingQueue.push(file);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
return new Promise((resolve, reject) => {
|
|
196
|
+
parseNextFile(parsingQueue, allSeriesStack, resolve, reject);
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Parse a single DICOM File (metaData and pixelData)
|
|
202
|
+
* @inner
|
|
203
|
+
* @function parseFile
|
|
204
|
+
* @param {File} file - File object to be parsed
|
|
205
|
+
* @returns {Promise} - Return a promise which will resolve to a image object or fail if an error occurs
|
|
206
|
+
*/
|
|
207
|
+
let parseFile = function (file) {
|
|
208
|
+
let parsePromise = new Promise((resolve, reject) => {
|
|
209
|
+
let reader = new FileReader();
|
|
210
|
+
reader.onload = function () {
|
|
211
|
+
let arrayBuffer = reader.result;
|
|
212
|
+
// Here we have the file data as an ArrayBuffer.
|
|
213
|
+
// dicomParser requires as input a Uint8Array so we create that here.
|
|
214
|
+
let byteArray = new Uint8Array(arrayBuffer);
|
|
215
|
+
let dataSet;
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
dataSet = parseDicom(byteArray);
|
|
219
|
+
byteArray = null;
|
|
220
|
+
let metadata = {};
|
|
221
|
+
parseDataSet(dataSet, metadata);
|
|
222
|
+
|
|
223
|
+
let numberOfFrames = metadata["x00280008"];
|
|
224
|
+
let isMultiframe = numberOfFrames > 1 ? true : false;
|
|
225
|
+
// Overwrite SOPInstanceUID to manage multiframes.
|
|
226
|
+
// Usually different SeriesInstanceUID means different series and that value
|
|
227
|
+
// is used into the application to group different instances into the same series,
|
|
228
|
+
// but if a DICOM file contains a multiframe series, then the SeriesInstanceUID
|
|
229
|
+
// can be shared by other files of the same study.
|
|
230
|
+
// In multiframe cases, the SOPInstanceUID (unique) is used as SeriesInstanceUID.
|
|
231
|
+
let seriesInstanceUID = isMultiframe
|
|
232
|
+
? metadata["x00080018"]
|
|
233
|
+
: metadata["x0020000e"];
|
|
234
|
+
let pixelSpacing = metadata["x00280030"];
|
|
235
|
+
let imageOrientation = metadata["x00200037"];
|
|
236
|
+
let imagePosition = metadata["x00200032"];
|
|
237
|
+
let sliceThickness = metadata["x00180050"];
|
|
238
|
+
|
|
239
|
+
if (dataSet.warnings.length > 0) {
|
|
240
|
+
// warnings
|
|
241
|
+
reject(dataSet.warnings);
|
|
242
|
+
} else {
|
|
243
|
+
let pixelDataElement = dataSet.elements.x7fe00010;
|
|
244
|
+
|
|
245
|
+
if (pixelDataElement) {
|
|
246
|
+
// done, pixelDataElement found
|
|
247
|
+
let instanceUID = metadata["x00080018"] || randomId();
|
|
248
|
+
let imageObject = {
|
|
249
|
+
// data needed for rendering
|
|
250
|
+
file: file,
|
|
251
|
+
dataSet: dataSet
|
|
252
|
+
};
|
|
253
|
+
imageObject.metadata = metadata;
|
|
254
|
+
imageObject.metadata.seriesUID = seriesInstanceUID;
|
|
255
|
+
imageObject.metadata.instanceUID = instanceUID;
|
|
256
|
+
imageObject.metadata.studyUID = metadata["x0020000d"];
|
|
257
|
+
imageObject.metadata.accessionNumber = metadata["x00080050"];
|
|
258
|
+
imageObject.metadata.studyDescription = metadata["x00081030"];
|
|
259
|
+
imageObject.metadata.patientName = metadata["x00100010"];
|
|
260
|
+
imageObject.metadata.patientBirthdate = metadata["x00100030"];
|
|
261
|
+
imageObject.metadata.seriesDescription = metadata["x0008103e"];
|
|
262
|
+
imageObject.metadata.seriesDate = metadata["x00080021"];
|
|
263
|
+
imageObject.metadata.seriesModality =
|
|
264
|
+
metadata["x00080060"].toLowerCase();
|
|
265
|
+
imageObject.metadata.intercept = metadata["x00281052"];
|
|
266
|
+
imageObject.metadata.slope = metadata["x00281053"];
|
|
267
|
+
imageObject.metadata.pixelSpacing = pixelSpacing;
|
|
268
|
+
imageObject.metadata.sliceThickness = sliceThickness;
|
|
269
|
+
imageObject.metadata.imageOrientation = imageOrientation;
|
|
270
|
+
imageObject.metadata.imagePosition = imagePosition;
|
|
271
|
+
imageObject.metadata.rows = metadata["x00280010"];
|
|
272
|
+
imageObject.metadata.cols = metadata["x00280011"];
|
|
273
|
+
imageObject.metadata.numberOfSlices = metadata["x00540081"]
|
|
274
|
+
? metadata["x00540081"] // number of slices
|
|
275
|
+
: metadata["x00201002"]; // number of instances
|
|
276
|
+
imageObject.metadata.numberOfFrames = numberOfFrames;
|
|
277
|
+
if (isMultiframe) {
|
|
278
|
+
imageObject.metadata.frameTime = metadata["x00181063"];
|
|
279
|
+
imageObject.metadata.frameDelay = metadata["x00181066"];
|
|
280
|
+
}
|
|
281
|
+
imageObject.metadata.windowCenter = metadata["x00281050"];
|
|
282
|
+
imageObject.metadata.windowWidth = metadata["x00281051"];
|
|
283
|
+
imageObject.metadata.minPixelValue = metadata["x00280106"];
|
|
284
|
+
imageObject.metadata.maxPixelValue = metadata["x00280107"];
|
|
285
|
+
imageObject.metadata.length = pixelDataElement.length;
|
|
286
|
+
imageObject.metadata.repr = getPixelRepresentation(dataSet);
|
|
287
|
+
resolve(imageObject);
|
|
288
|
+
} else {
|
|
289
|
+
// done, no pixelData
|
|
290
|
+
reject("no pixelData");
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
} catch (err) {
|
|
294
|
+
console.error(err);
|
|
295
|
+
reject("can not read this file");
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
reader.readAsArrayBuffer(file);
|
|
299
|
+
});
|
|
300
|
+
return parsePromise;
|
|
301
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** @module imaging/
|
|
1
|
+
/** @module imaging/imagePresets
|
|
2
2
|
* @desc This file provides functionalities for
|
|
3
3
|
* image presets for ww and wc
|
|
4
4
|
*/
|
|
@@ -8,7 +8,7 @@ import cornerstone from "cornerstone-core";
|
|
|
8
8
|
import { each, find } from "lodash";
|
|
9
9
|
|
|
10
10
|
// internal libraries
|
|
11
|
-
import { larvitar_store } from "./
|
|
11
|
+
import { larvitar_store } from "./imageStore";
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Object used to list image presets
|