@abasb75/dicom-parser 0.0.0-test2 → 0.0.0-test20a
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/Dataset.d.ts +54 -0
- package/Dataset.js +475 -0
- package/Loader.d.ts +8 -0
- package/Loader.js +105 -0
- package/Parser.d.ts +33 -0
- package/Parser.js +317 -0
- package/README.md +17 -1
- package/Tag.d.ts +17 -0
- package/Tag.js +128 -0
- package/Value.d.ts +15 -0
- package/Value.js +220 -0
- package/enums/TagsDictionary.d.ts +8 -0
- package/enums/TagsDictionary.js +3612 -0
- package/enums/TransferSyntax.d.ts +17 -0
- package/enums/TransferSyntax.js +17 -0
- package/enums/ValueRepresentations.d.ts +2 -0
- package/enums/ValueRepresentations.js +2 -0
- package/enums/index.d.ts +12 -0
- package/enums/index.js +9 -0
- package/index.d.ts +10 -276
- package/index.js +49 -1
- package/package.json +2 -2
- package/types.d.ts +96 -0
- package/types.js +1 -0
- package/utils/PaletteColor.d.ts +10 -0
- package/utils/PaletteColor.js +155 -0
- package/utils/PixelData.d.ts +14 -0
- package/utils/PixelData.js +285 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abasb75/dicom-parser",
|
|
3
|
-
"version": "0.0.0-
|
|
3
|
+
"version": "0.0.0-test20a",
|
|
4
4
|
"description": "a javascript powerfull dicom parser",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"license": "ISC",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "
|
|
19
|
+
"url": "https://github.com/abasb75/dicom-parser.git"
|
|
20
20
|
},
|
|
21
21
|
"bugs": {
|
|
22
22
|
"url": "https://github.com/abasb75/dicom-parser/issues"
|
package/types.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import Dataset from "./Dataset";
|
|
2
|
+
import Tag from "./Tag";
|
|
3
|
+
interface Tags {
|
|
4
|
+
[key: string]: Tag;
|
|
5
|
+
}
|
|
6
|
+
interface DicomDate {
|
|
7
|
+
year: string | number;
|
|
8
|
+
month: string | number;
|
|
9
|
+
day: string | number;
|
|
10
|
+
}
|
|
11
|
+
interface DicomTime {
|
|
12
|
+
hour: string | number;
|
|
13
|
+
minute: string | number;
|
|
14
|
+
second: string | number;
|
|
15
|
+
}
|
|
16
|
+
interface DicomDateTime extends DicomDate, DicomTime {
|
|
17
|
+
}
|
|
18
|
+
type DicomDataset = Dataset;
|
|
19
|
+
type PixelArray = Int16Array | Uint16Array | Int32Array | Uint32Array | Int8Array | Uint8Array | Float32Array;
|
|
20
|
+
interface DicomVOILutModule {
|
|
21
|
+
voiLUTFunction: string;
|
|
22
|
+
windowWidth: number | undefined;
|
|
23
|
+
windowCenter: number | undefined;
|
|
24
|
+
voiLUTSequence: unknown;
|
|
25
|
+
lutDescriptor: any;
|
|
26
|
+
lutExplanation: any;
|
|
27
|
+
lutData: any;
|
|
28
|
+
windowCenterAndWidthExplanation: string;
|
|
29
|
+
}
|
|
30
|
+
interface DicomPatientModule {
|
|
31
|
+
patientName: string;
|
|
32
|
+
patientID: string;
|
|
33
|
+
typeofPatientID: string;
|
|
34
|
+
patientSex: string;
|
|
35
|
+
patientBirthDate: string;
|
|
36
|
+
patientAge: string;
|
|
37
|
+
patientSize: string;
|
|
38
|
+
otherPatientIDs: string;
|
|
39
|
+
otherPatientNames: string;
|
|
40
|
+
patientWeight: string;
|
|
41
|
+
}
|
|
42
|
+
interface DicomPixelModule {
|
|
43
|
+
photometricInterpretation: string;
|
|
44
|
+
numberOfFrames: number | undefined;
|
|
45
|
+
pixelRepresentation: number | undefined;
|
|
46
|
+
pixeSpacing: any | undefined;
|
|
47
|
+
rows: number | number | undefined;
|
|
48
|
+
columns: number | number | undefined;
|
|
49
|
+
bitsAllocated: number | undefined;
|
|
50
|
+
highBit: number | undefined;
|
|
51
|
+
bitsStored: number | undefined;
|
|
52
|
+
samplesPerPixel: number | undefined;
|
|
53
|
+
pixelDataProviderURL: any;
|
|
54
|
+
pixelPaddingRangeLimit: any;
|
|
55
|
+
extendedOffsetTable: any;
|
|
56
|
+
extendedOffsetTableLengths: any;
|
|
57
|
+
pixelAspectRatio: any;
|
|
58
|
+
planarConfiguration: number | undefined;
|
|
59
|
+
redPaletteColorLookupTableDescriptor: unknown;
|
|
60
|
+
greenPaletteColorLookupTableDescriptor: unknown;
|
|
61
|
+
bluePaletteColorLookupTableDescriptor: unknown;
|
|
62
|
+
alphaPaletteColorLookupTableDescriptor: unknown;
|
|
63
|
+
redPaletteColorLookupTableData: any;
|
|
64
|
+
greenPaletteColorLookupTableData: any;
|
|
65
|
+
bluePaletteColorLookupTableData: any;
|
|
66
|
+
alphaPaletteColorLookupTableData: any;
|
|
67
|
+
segmentedRedPaletteColorLookupTableData: any;
|
|
68
|
+
segmentedGreenPaletteColorLookupTableData: any;
|
|
69
|
+
segmentedBluePaletteColorLookupTableData: any;
|
|
70
|
+
segmentedAlphaPaletteColorLookupTableData: any;
|
|
71
|
+
}
|
|
72
|
+
interface DicomScalingModule {
|
|
73
|
+
rescaleSlope: number | undefined;
|
|
74
|
+
rescaleIntercept: number | undefined;
|
|
75
|
+
modality: string;
|
|
76
|
+
}
|
|
77
|
+
interface PixelDataDecodeOptions {
|
|
78
|
+
pixelData: DataView;
|
|
79
|
+
bitsAllocated: number;
|
|
80
|
+
pixelRepresentation: number;
|
|
81
|
+
littleEndian: boolean;
|
|
82
|
+
dataset?: Dataset;
|
|
83
|
+
}
|
|
84
|
+
interface PaletteColorDataColor {
|
|
85
|
+
data: number[];
|
|
86
|
+
firstInputValueMapped: number;
|
|
87
|
+
lutEntries: number;
|
|
88
|
+
bitsPerEntry: number;
|
|
89
|
+
}
|
|
90
|
+
interface PaletteColorData {
|
|
91
|
+
red: PaletteColorDataColor | undefined;
|
|
92
|
+
green: PaletteColorDataColor | undefined;
|
|
93
|
+
blue: PaletteColorDataColor | undefined;
|
|
94
|
+
alpha: PaletteColorDataColor | undefined;
|
|
95
|
+
}
|
|
96
|
+
export type { Tags, DicomTime, DicomDate, DicomDateTime, DicomDataset, DicomVOILutModule, DicomPatientModule, DicomPixelModule, DicomScalingModule, PixelArray, PixelDataDecodeOptions, PaletteColorData, PaletteColorDataColor, };
|
package/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Dataset from "../Dataset";
|
|
2
|
+
import { PaletteColorData } from "../types";
|
|
3
|
+
declare class PaletteColor {
|
|
4
|
+
static get(dataset: Dataset): PaletteColorData | undefined;
|
|
5
|
+
private static getData;
|
|
6
|
+
private static get16Array;
|
|
7
|
+
private static get8Array;
|
|
8
|
+
private static segmentedDataToData;
|
|
9
|
+
}
|
|
10
|
+
export default PaletteColor;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
var PaletteColor = /** @class */ (function () {
|
|
2
|
+
function PaletteColor() {
|
|
3
|
+
}
|
|
4
|
+
Object.defineProperty(PaletteColor, "get", {
|
|
5
|
+
enumerable: false,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true,
|
|
8
|
+
value: function (dataset) {
|
|
9
|
+
var _a = dataset.pixelModule, redPaletteColorLookupTableData = _a.redPaletteColorLookupTableData, redPaletteColorLookupTableDescriptor = _a.redPaletteColorLookupTableDescriptor, segmentedRedPaletteColorLookupTableData = _a.segmentedRedPaletteColorLookupTableData, greenPaletteColorLookupTableData = _a.greenPaletteColorLookupTableData, greenPaletteColorLookupTableDescriptor = _a.greenPaletteColorLookupTableDescriptor, segmentedGreenPaletteColorLookupTableData = _a.segmentedGreenPaletteColorLookupTableData, bluePaletteColorLookupTableData = _a.bluePaletteColorLookupTableData, bluePaletteColorLookupTableDescriptor = _a.bluePaletteColorLookupTableDescriptor, segmentedAlphaPaletteColorLookupTableData = _a.segmentedAlphaPaletteColorLookupTableData, alphaPaletteColorLookupTableData = _a.alphaPaletteColorLookupTableData, alphaPaletteColorLookupTableDescriptor = _a.alphaPaletteColorLookupTableDescriptor, segmentedBluePaletteColorLookupTableData = _a.segmentedBluePaletteColorLookupTableData, bitsAllocated = _a.bitsAllocated;
|
|
10
|
+
if (!bitsAllocated || ![8, 16].includes(bitsAllocated)) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
var littleEndian = dataset.littleEndian;
|
|
14
|
+
var red = PaletteColor.getData(redPaletteColorLookupTableDescriptor, redPaletteColorLookupTableData, segmentedRedPaletteColorLookupTableData, bitsAllocated, littleEndian);
|
|
15
|
+
var green = PaletteColor.getData(greenPaletteColorLookupTableDescriptor, greenPaletteColorLookupTableData, segmentedGreenPaletteColorLookupTableData, bitsAllocated, littleEndian);
|
|
16
|
+
var blue = PaletteColor.getData(bluePaletteColorLookupTableDescriptor, bluePaletteColorLookupTableData, segmentedBluePaletteColorLookupTableData, bitsAllocated, littleEndian);
|
|
17
|
+
var alpha = PaletteColor.getData(alphaPaletteColorLookupTableDescriptor, alphaPaletteColorLookupTableData, segmentedAlphaPaletteColorLookupTableData, bitsAllocated, littleEndian);
|
|
18
|
+
return {
|
|
19
|
+
red: red,
|
|
20
|
+
green: green,
|
|
21
|
+
blue: blue,
|
|
22
|
+
alpha: alpha,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(PaletteColor, "getData", {
|
|
27
|
+
enumerable: false,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: function (descriptor, paletteData, segmentedPaletteData, bitsAllocated, littleEndian) {
|
|
31
|
+
var _a;
|
|
32
|
+
if (!Array.isArray(descriptor)
|
|
33
|
+
|| descriptor.length < 3) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
var tableDataArray = null;
|
|
37
|
+
var lutEntries = descriptor[0] || Math.pow(2, 16);
|
|
38
|
+
var firstInputValueMapped = descriptor[1];
|
|
39
|
+
var bitsPerEntry = descriptor[2];
|
|
40
|
+
if (![8, 16].includes(bitsPerEntry)) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
if (paletteData) {
|
|
44
|
+
tableDataArray = bitsPerEntry === 16
|
|
45
|
+
? PaletteColor.get16Array(paletteData, bitsAllocated, littleEndian)
|
|
46
|
+
: PaletteColor.get8Array(paletteData);
|
|
47
|
+
}
|
|
48
|
+
else if (segmentedPaletteData) {
|
|
49
|
+
var segmentedTableDataArray = bitsPerEntry === 16
|
|
50
|
+
? PaletteColor.get16Array(segmentedPaletteData, bitsAllocated, littleEndian)
|
|
51
|
+
: PaletteColor.get8Array(segmentedPaletteData);
|
|
52
|
+
tableDataArray = (_a = PaletteColor.segmentedDataToData(segmentedTableDataArray, lutEntries)) === null || _a === void 0 ? void 0 : _a.tableData;
|
|
53
|
+
}
|
|
54
|
+
if (!tableDataArray) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
data: tableDataArray,
|
|
59
|
+
firstInputValueMapped: firstInputValueMapped,
|
|
60
|
+
lutEntries: lutEntries,
|
|
61
|
+
bitsPerEntry: bitsPerEntry
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
Object.defineProperty(PaletteColor, "get16Array", {
|
|
66
|
+
enumerable: false,
|
|
67
|
+
configurable: true,
|
|
68
|
+
writable: true,
|
|
69
|
+
value: function (paletteData, bitsAllocated, littleEndian) {
|
|
70
|
+
var array = [];
|
|
71
|
+
for (var i = 0; i < paletteData.byteLength; i += 2) {
|
|
72
|
+
if (bitsAllocated === 8) {
|
|
73
|
+
array.push(paletteData.getUint16(i, littleEndian) >> 8);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
array.push(paletteData.getUint16(i, littleEndian));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return array;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
Object.defineProperty(PaletteColor, "get8Array", {
|
|
83
|
+
enumerable: false,
|
|
84
|
+
configurable: true,
|
|
85
|
+
writable: true,
|
|
86
|
+
value: function (paletteData) {
|
|
87
|
+
var array = [];
|
|
88
|
+
for (var i = 0; i < paletteData.byteLength; i++) {
|
|
89
|
+
array.push(paletteData.getUint8(i));
|
|
90
|
+
}
|
|
91
|
+
return array;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
Object.defineProperty(PaletteColor, "segmentedDataToData", {
|
|
95
|
+
enumerable: false,
|
|
96
|
+
configurable: true,
|
|
97
|
+
writable: true,
|
|
98
|
+
value: function (segmentedTableData, lutEntries, segmentedTableDataOffset, valuedTableData, valuedTableDataOffset, stopIndex, prevLastValue) {
|
|
99
|
+
var tableData = valuedTableData
|
|
100
|
+
? valuedTableData : new Array(lutEntries);
|
|
101
|
+
var segmentedDataOffset = segmentedTableDataOffset || 0;
|
|
102
|
+
var tableDataOffset = valuedTableDataOffset || 0;
|
|
103
|
+
var lastValue = prevLastValue || undefined;
|
|
104
|
+
while (segmentedDataOffset < (stopIndex || segmentedTableData.length)) {
|
|
105
|
+
var op = segmentedTableData[segmentedDataOffset];
|
|
106
|
+
segmentedDataOffset++;
|
|
107
|
+
var len = segmentedTableData[segmentedDataOffset];
|
|
108
|
+
segmentedDataOffset++;
|
|
109
|
+
if (op === 2) {
|
|
110
|
+
console.log({ op: op });
|
|
111
|
+
}
|
|
112
|
+
switch (op) {
|
|
113
|
+
case 0:
|
|
114
|
+
for (var i = 0; i < len; i++) {
|
|
115
|
+
tableData[tableDataOffset] = segmentedTableData[segmentedDataOffset];
|
|
116
|
+
segmentedDataOffset++;
|
|
117
|
+
tableDataOffset++;
|
|
118
|
+
}
|
|
119
|
+
lastValue = tableData[segmentedDataOffset - 1] & 0xFFFF;
|
|
120
|
+
break;
|
|
121
|
+
case 1:
|
|
122
|
+
if (typeof lastValue !== "number") {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
var newValue = segmentedTableData[segmentedDataOffset];
|
|
126
|
+
segmentedDataOffset++;
|
|
127
|
+
for (var i = 1; i <= len; i++) {
|
|
128
|
+
tableData[tableDataOffset] = (lastValue + ((newValue - lastValue) / len));
|
|
129
|
+
tableDataOffset++;
|
|
130
|
+
}
|
|
131
|
+
lastValue = newValue & 0xFFFF;
|
|
132
|
+
break;
|
|
133
|
+
case 2: // untested
|
|
134
|
+
if (typeof lastValue !== "number") {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
var startPosition = (segmentedTableData[segmentedDataOffset] & 0xffff)
|
|
138
|
+
| ((segmentedTableData[segmentedDataOffset + 1] & 0xffff) << 16);
|
|
139
|
+
segmentedDataOffset += 2;
|
|
140
|
+
var res = PaletteColor.segmentedDataToData(segmentedTableData, lutEntries, startPosition, tableData, tableDataOffset, startPosition + len, lastValue);
|
|
141
|
+
lastValue = res === null || res === void 0 ? void 0 : res.lastValue;
|
|
142
|
+
tableData = res === null || res === void 0 ? void 0 : res.tableData;
|
|
143
|
+
segmentedDataOffset = res === null || res === void 0 ? void 0 : res.segmentedDataOffset;
|
|
144
|
+
tableDataOffset = res === null || res === void 0 ? void 0 : res.tableDataOffset;
|
|
145
|
+
break;
|
|
146
|
+
default:
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return { tableData: tableData, lastValue: lastValue, segmentedDataOffset: segmentedDataOffset, tableDataOffset: tableDataOffset };
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
return PaletteColor;
|
|
154
|
+
}());
|
|
155
|
+
export default PaletteColor;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Dataset from "../Dataset";
|
|
2
|
+
declare class PixelData {
|
|
3
|
+
static get(dataset: Dataset, frame?: number): Promise<DataView>;
|
|
4
|
+
private static _getixelDataViews;
|
|
5
|
+
private static _encapsulatePixelDatas;
|
|
6
|
+
private static _concatArrayBuffers;
|
|
7
|
+
private static _makeBasicOffsetTable;
|
|
8
|
+
private static _makeBasicOfsetTableForJPEGImages;
|
|
9
|
+
private static _isJPEG;
|
|
10
|
+
private static _isJPEG2000;
|
|
11
|
+
private static _makeFragments;
|
|
12
|
+
private static bitToByte;
|
|
13
|
+
}
|
|
14
|
+
export default PixelData;
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
+
function step(op) {
|
|
15
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
+
switch (op[0]) {
|
|
20
|
+
case 0: case 1: t = op; break;
|
|
21
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
+
default:
|
|
25
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
+
if (t[2]) _.ops.pop();
|
|
30
|
+
_.trys.pop(); continue;
|
|
31
|
+
}
|
|
32
|
+
op = body.call(thisArg, _);
|
|
33
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var PixelData = /** @class */ (function () {
|
|
38
|
+
function PixelData() {
|
|
39
|
+
}
|
|
40
|
+
Object.defineProperty(PixelData, "get", {
|
|
41
|
+
enumerable: false,
|
|
42
|
+
configurable: true,
|
|
43
|
+
writable: true,
|
|
44
|
+
value: function (dataset_1) {
|
|
45
|
+
return __awaiter(this, arguments, void 0, function (dataset, frame) {
|
|
46
|
+
var pixelData;
|
|
47
|
+
if (frame === void 0) { frame = 0; }
|
|
48
|
+
return __generator(this, function (_a) {
|
|
49
|
+
pixelData = PixelData._getixelDataViews(dataset, frame);
|
|
50
|
+
return [2 /*return*/, pixelData];
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
Object.defineProperty(PixelData, "_getixelDataViews", {
|
|
56
|
+
enumerable: false,
|
|
57
|
+
configurable: true,
|
|
58
|
+
writable: true,
|
|
59
|
+
value: function (dataset, frameIndex) {
|
|
60
|
+
var _a;
|
|
61
|
+
var pixelDataElement = dataset.tags['0x7FE00010'] || dataset.tags['0x7FE00008'] || dataset.tags['0x7FE00009'];
|
|
62
|
+
if (!pixelDataElement) {
|
|
63
|
+
throw new Error("dicom has not pixels");
|
|
64
|
+
}
|
|
65
|
+
var numberOfFrames = dataset.pixelModule.numberOfFrames || 1;
|
|
66
|
+
if (pixelDataElement.valueLength === 0xFFFFFFFF) {
|
|
67
|
+
return PixelData._encapsulatePixelDatas(dataset, pixelDataElement, frameIndex);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
var _b = dataset === null || dataset === void 0 ? void 0 : dataset.pixelModule, columns = _b.columns, rows = _b.rows, samplesPerPixel = _b.samplesPerPixel, bitsAllocated = _b.bitsAllocated;
|
|
71
|
+
var frameLen = 0;
|
|
72
|
+
if ((_a = dataset.pixelModule) === null || _a === void 0 ? void 0 : _a.numberOfFrames) {
|
|
73
|
+
frameLen = pixelDataElement.valueLength / numberOfFrames;
|
|
74
|
+
}
|
|
75
|
+
else if (columns && rows && samplesPerPixel && bitsAllocated) {
|
|
76
|
+
var bytesAllocated = PixelData.bitToByte(bitsAllocated);
|
|
77
|
+
frameLen = rows * columns * bytesAllocated * samplesPerPixel;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
frameLen = pixelDataElement.valueLength / numberOfFrames;
|
|
81
|
+
}
|
|
82
|
+
frameLen = Math.min(frameLen, pixelDataElement.valueLength);
|
|
83
|
+
var offset = pixelDataElement.offset + (frameLen * frameIndex);
|
|
84
|
+
return new DataView(dataset.dataView.buffer.slice(offset, offset + frameLen));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
Object.defineProperty(PixelData, "_encapsulatePixelDatas", {
|
|
89
|
+
enumerable: false,
|
|
90
|
+
configurable: true,
|
|
91
|
+
writable: true,
|
|
92
|
+
value: function (dataset, pixelDataElement, frameIndex) {
|
|
93
|
+
if (!dataset.basicOffsetTable) {
|
|
94
|
+
dataset.basicOffsetTable = PixelData._makeBasicOffsetTable(dataset, pixelDataElement);
|
|
95
|
+
}
|
|
96
|
+
if (!dataset.basicOffsetTable || dataset.basicOffsetTable.length - 1 < frameIndex) {
|
|
97
|
+
throw new Error("not frame index found.");
|
|
98
|
+
}
|
|
99
|
+
var offset = dataset.basicOffsetTable[frameIndex];
|
|
100
|
+
var nextFrameOffset = dataset.basicOffsetTable.length > frameIndex + 1 ? dataset.basicOffsetTable[frameIndex + 1] : -1;
|
|
101
|
+
var fragments = [];
|
|
102
|
+
while (true) {
|
|
103
|
+
if (nextFrameOffset > 0 && offset >= nextFrameOffset) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
var group = dataset.dataView.getUint16(offset, dataset.littleEndian);
|
|
107
|
+
offset += 2;
|
|
108
|
+
var element = dataset.dataView.getUint16(offset, dataset.littleEndian);
|
|
109
|
+
offset += 2;
|
|
110
|
+
if (group !== 0xFFFE || element !== 0xE000) {
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
var len = dataset.dataView.getUint32(offset, dataset.littleEndian);
|
|
114
|
+
offset += 4;
|
|
115
|
+
fragments.push(dataset.dataView.buffer.slice(offset, offset + len));
|
|
116
|
+
offset += len;
|
|
117
|
+
}
|
|
118
|
+
if (fragments.length < 1) {
|
|
119
|
+
throw new Error("image not created");
|
|
120
|
+
}
|
|
121
|
+
var buffer = fragments[0];
|
|
122
|
+
for (var i = 1; i < fragments.length; i++) {
|
|
123
|
+
buffer = PixelData._concatArrayBuffers(buffer, fragments[i]);
|
|
124
|
+
}
|
|
125
|
+
return new DataView(buffer);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
Object.defineProperty(PixelData, "_concatArrayBuffers", {
|
|
129
|
+
enumerable: false,
|
|
130
|
+
configurable: true,
|
|
131
|
+
writable: true,
|
|
132
|
+
value: function (buffer1, buffer2) {
|
|
133
|
+
var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
|
|
134
|
+
tmp.set(new Uint8Array(buffer1), 0);
|
|
135
|
+
tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
|
|
136
|
+
return tmp.buffer;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
;
|
|
140
|
+
Object.defineProperty(PixelData, "_makeBasicOffsetTable", {
|
|
141
|
+
enumerable: false,
|
|
142
|
+
configurable: true,
|
|
143
|
+
writable: true,
|
|
144
|
+
value: function (dataset, pixelDataElement) {
|
|
145
|
+
var offset = pixelDataElement.offset;
|
|
146
|
+
var group = dataset.dataView.getUint16(offset, dataset.littleEndian);
|
|
147
|
+
offset += 2;
|
|
148
|
+
var element = dataset.dataView.getUint16(offset, dataset.littleEndian);
|
|
149
|
+
offset += 2;
|
|
150
|
+
if (group !== 0xFFFE && element !== 0xE000) {
|
|
151
|
+
throw new Error("is not basic table");
|
|
152
|
+
}
|
|
153
|
+
var len = dataset.dataView.getUint32(offset, dataset.littleEndian);
|
|
154
|
+
offset += 4;
|
|
155
|
+
var basicOffsetTable = [];
|
|
156
|
+
var basicOffsetIndex = offset + len;
|
|
157
|
+
if (len > 0) {
|
|
158
|
+
for (var i = 0; i < len; i += 4) {
|
|
159
|
+
basicOffsetTable.push(basicOffsetIndex + dataset.dataView.getUint16(offset, dataset.littleEndian));
|
|
160
|
+
offset += 4;
|
|
161
|
+
}
|
|
162
|
+
return basicOffsetTable;
|
|
163
|
+
}
|
|
164
|
+
var basicOffsetTableElement = dataset.tags['0x7FE00001'];
|
|
165
|
+
if (basicOffsetTableElement && basicOffsetTableElement.valueLength > 0) {
|
|
166
|
+
for (var i = 0; i < len; i += 4) {
|
|
167
|
+
offset = basicOffsetTableElement.offset;
|
|
168
|
+
basicOffsetTable.push(basicOffsetIndex + dataset.dataView.getUint16(offset, dataset.littleEndian));
|
|
169
|
+
offset += 4;
|
|
170
|
+
}
|
|
171
|
+
return basicOffsetTable;
|
|
172
|
+
}
|
|
173
|
+
var numberOfFrames = dataset.pixelModule.numberOfFrames || 1;
|
|
174
|
+
if (numberOfFrames === 1) {
|
|
175
|
+
return [basicOffsetIndex];
|
|
176
|
+
}
|
|
177
|
+
var fragments = this._makeFragments(dataset, basicOffsetIndex);
|
|
178
|
+
if (fragments.length === numberOfFrames) {
|
|
179
|
+
return fragments.map(function (fragment) { return fragment.offset; });
|
|
180
|
+
}
|
|
181
|
+
return PixelData._makeBasicOfsetTableForJPEGImages(dataset, fragments);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
Object.defineProperty(PixelData, "_makeBasicOfsetTableForJPEGImages", {
|
|
185
|
+
enumerable: false,
|
|
186
|
+
configurable: true,
|
|
187
|
+
writable: true,
|
|
188
|
+
value: function (dataset, fragments) {
|
|
189
|
+
var basicOffsetTable = [];
|
|
190
|
+
for (var i = 0; i < fragments.length; i++) {
|
|
191
|
+
var fragment = fragments[i];
|
|
192
|
+
if (PixelData._isJPEG(fragment.offset + 8, dataset.dataView)
|
|
193
|
+
|| PixelData._isJPEG2000(fragment.offset + 8, dataset.dataView)) {
|
|
194
|
+
basicOffsetTable.push(fragment.offset);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return basicOffsetTable;
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
Object.defineProperty(PixelData, "_isJPEG", {
|
|
201
|
+
enumerable: false,
|
|
202
|
+
configurable: true,
|
|
203
|
+
writable: true,
|
|
204
|
+
value: function (position, dataView) {
|
|
205
|
+
var magic1 = dataView.getUint8(position);
|
|
206
|
+
var magic2 = dataView.getUint8(position + 1);
|
|
207
|
+
if (magic1 === 0xFF && magic2 === 0xD8) {
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
Object.defineProperty(PixelData, "_isJPEG2000", {
|
|
214
|
+
enumerable: false,
|
|
215
|
+
configurable: true,
|
|
216
|
+
writable: true,
|
|
217
|
+
value: function (position, dataView) {
|
|
218
|
+
var magics2 = [0xFF, 0x4F, 0xFF, 0x51];
|
|
219
|
+
for (var i = 0; i < magics2.length; i++) {
|
|
220
|
+
var finded = dataView.getUint8(position + i);
|
|
221
|
+
if (finded !== magics2[i]) {
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
else if (i === magics2.length - 1) {
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
var magics = [0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A];
|
|
229
|
+
for (var i = 0; i < magics.length; i++) {
|
|
230
|
+
var finded = dataView.getInt8(position + i);
|
|
231
|
+
if (finded !== magics[i]) {
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
else if (i === magics2.length - 1) {
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
Object.defineProperty(PixelData, "_makeFragments", {
|
|
242
|
+
enumerable: false,
|
|
243
|
+
configurable: true,
|
|
244
|
+
writable: true,
|
|
245
|
+
value: function (dataset, basicOffsetIndex) {
|
|
246
|
+
var fragments = [];
|
|
247
|
+
var offset = basicOffsetIndex;
|
|
248
|
+
var dataView = dataset.dataView;
|
|
249
|
+
while (true) {
|
|
250
|
+
if (offset >= dataView.byteLength) {
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
var group = dataset.dataView.getUint16(offset, dataset.littleEndian);
|
|
254
|
+
offset += 2;
|
|
255
|
+
var element = dataset.dataView.getUint16(offset, dataset.littleEndian);
|
|
256
|
+
offset += 2;
|
|
257
|
+
if (group !== 0xFFFE || element !== 0xE000) {
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
var len = dataset.dataView.getUint16(offset, dataset.littleEndian);
|
|
261
|
+
offset += 4;
|
|
262
|
+
var fragment = {
|
|
263
|
+
offset: offset - 8,
|
|
264
|
+
len: len,
|
|
265
|
+
};
|
|
266
|
+
fragments.push(fragment);
|
|
267
|
+
offset += len;
|
|
268
|
+
}
|
|
269
|
+
return fragments;
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
Object.defineProperty(PixelData, "bitToByte", {
|
|
273
|
+
enumerable: false,
|
|
274
|
+
configurable: true,
|
|
275
|
+
writable: true,
|
|
276
|
+
value: function (bit) {
|
|
277
|
+
if (bit <= 8) {
|
|
278
|
+
return bit / 8;
|
|
279
|
+
}
|
|
280
|
+
return Math.ceil(bit / 8);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
return PixelData;
|
|
284
|
+
}());
|
|
285
|
+
export default PixelData;
|