dcmjs 0.48.0 → 0.49.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/build/dcmjs.es.js +1834 -178
- package/build/dcmjs.es.js.map +1 -1
- package/build/dcmjs.js +1835 -177
- package/build/dcmjs.js.map +1 -1
- package/build/dcmjs.min.js +2 -2
- package/build/dcmjs.min.js.map +1 -1
- package/docs/ArrayBufferExpanderListener.md +303 -0
- package/docs/AsyncDicomReader-skill.md +730 -0
- package/package.json +1 -1
- package/test/ArrayBufferExpanderListener.test.js +365 -0
- package/test/async-data.test.js +470 -7
- package/test/information-filter.test.js +165 -0
- package/test/odd-frame-bit-data.js +138 -0
- package/test/sample-op.lei +0 -0
- package/test/video-test-dict.js +40 -0
package/build/dcmjs.es.js
CHANGED
|
@@ -7951,14 +7951,14 @@ var Inflate_1$1 = Inflate$1;
|
|
|
7951
7951
|
var inflate_2 = inflate$1;
|
|
7952
7952
|
var inflateRaw_1$1 = inflateRaw$1;
|
|
7953
7953
|
var ungzip$1 = inflate$1;
|
|
7954
|
-
var constants = constants$2;
|
|
7954
|
+
var constants$3 = constants$2;
|
|
7955
7955
|
|
|
7956
7956
|
var inflate_1$1 = {
|
|
7957
7957
|
Inflate: Inflate_1$1,
|
|
7958
7958
|
inflate: inflate_2,
|
|
7959
7959
|
inflateRaw: inflateRaw_1$1,
|
|
7960
7960
|
ungzip: ungzip$1,
|
|
7961
|
-
constants: constants
|
|
7961
|
+
constants: constants$3
|
|
7962
7962
|
};
|
|
7963
7963
|
|
|
7964
7964
|
const { Deflate, deflate, deflateRaw, gzip } = deflate_1$1;
|
|
@@ -8024,26 +8024,28 @@ var SplitDataView = /*#__PURE__*/function () {
|
|
|
8024
8024
|
_createClass(SplitDataView, [{
|
|
8025
8025
|
key: "consume",
|
|
8026
8026
|
value: function consume(offset) {
|
|
8027
|
-
var _this$consumeListener;
|
|
8028
8027
|
this.consumeOffset = Math.max(offset, this.consumeOffset);
|
|
8029
8028
|
if (!this.consumed || !this.offsets.length) {
|
|
8030
8029
|
return;
|
|
8031
8030
|
}
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8035
|
-
|
|
8036
|
-
|
|
8037
|
-
|
|
8038
|
-
|
|
8039
|
-
|
|
8040
|
-
|
|
8031
|
+
while (true) {
|
|
8032
|
+
var _this$consumeListener;
|
|
8033
|
+
var nextOffset = this.offsets[this.consumed.length];
|
|
8034
|
+
var nextLength = this.lengths[this.consumed.length];
|
|
8035
|
+
if (nextOffset === undefined || nextLength === undefined) {
|
|
8036
|
+
return;
|
|
8037
|
+
}
|
|
8038
|
+
var currentEnd = nextOffset + nextLength;
|
|
8039
|
+
if (this.consumeOffset < currentEnd) {
|
|
8040
|
+
// Haven't finished consuming all the data in the current block
|
|
8041
|
+
return;
|
|
8042
|
+
}
|
|
8043
|
+
// Consume the entire buffer for now
|
|
8044
|
+
this.consumed.push((_this$consumeListener = this.consumeListener) === null || _this$consumeListener === void 0 ? void 0 : _this$consumeListener.call(this, this.buffers, 0, Math.min(this.buffers.length, nextOffset - this.consumeOffset)));
|
|
8045
|
+
this.buffers[this.consumed.length - 1] = null;
|
|
8046
|
+
this.views[this.consumed.length - 1] = null;
|
|
8047
|
+
// Continue loop to check if there are more buffers to consume
|
|
8041
8048
|
}
|
|
8042
|
-
// Consume the entire buffer for now
|
|
8043
|
-
this.consumed.push((_this$consumeListener = this.consumeListener) === null || _this$consumeListener === void 0 ? void 0 : _this$consumeListener.call(this, this.buffers, 0, Math.min(this.buffers.length, nextOffset - this.consumeOffset)));
|
|
8044
|
-
this.buffers[this.consumed.length - 1] = null;
|
|
8045
|
-
this.views[this.consumed.length - 1] = null;
|
|
8046
|
-
this.consume(offset);
|
|
8047
8049
|
}
|
|
8048
8050
|
|
|
8049
8051
|
/**
|
|
@@ -8386,6 +8388,52 @@ var SplitDataView = /*#__PURE__*/function () {
|
|
|
8386
8388
|
this.writeCommit(view, offset);
|
|
8387
8389
|
}
|
|
8388
8390
|
}
|
|
8391
|
+
|
|
8392
|
+
/**
|
|
8393
|
+
* Reports on the amount of memory held by the buffers in the view.
|
|
8394
|
+
* @param {number} consumeOffset - The current consume offset (typically from BufferStream.offset)
|
|
8395
|
+
* @returns {Object} An object containing:
|
|
8396
|
+
* - bufferCount: Number of buffers still held (not null)
|
|
8397
|
+
* - totalSize: Total size of all buffers in bytes
|
|
8398
|
+
* - consumeOffset: The current consume offset
|
|
8399
|
+
* - buffersBeforeOffset: Number of buffers before the consume offset
|
|
8400
|
+
* - bytesBeforeOffset: Total bytes before the consume offset
|
|
8401
|
+
*/
|
|
8402
|
+
}, {
|
|
8403
|
+
key: "getBufferMemoryInfo",
|
|
8404
|
+
value: function getBufferMemoryInfo(consumeOffset) {
|
|
8405
|
+
var bufferCount = 0;
|
|
8406
|
+
var totalSize = 0;
|
|
8407
|
+
var buffersBeforeOffset = 0;
|
|
8408
|
+
var bytesBeforeOffset = 0;
|
|
8409
|
+
var currentConsumeOffset = consumeOffset !== null && consumeOffset !== void 0 ? consumeOffset : this.consumeOffset;
|
|
8410
|
+
for (var i = 0; i < this.buffers.length; i++) {
|
|
8411
|
+
var buffer = this.buffers[i];
|
|
8412
|
+
if (buffer !== null && buffer !== undefined) {
|
|
8413
|
+
bufferCount++;
|
|
8414
|
+
totalSize += buffer.byteLength;
|
|
8415
|
+
|
|
8416
|
+
// Count buffers and bytes that are before the consume offset
|
|
8417
|
+
var bufferStart = this.offsets[i];
|
|
8418
|
+
var bufferEnd = bufferStart + this.lengths[i];
|
|
8419
|
+
if (bufferEnd <= currentConsumeOffset) {
|
|
8420
|
+
// Buffer is completely before the offset
|
|
8421
|
+
buffersBeforeOffset++;
|
|
8422
|
+
bytesBeforeOffset += buffer.byteLength;
|
|
8423
|
+
} else if (bufferStart < currentConsumeOffset) {
|
|
8424
|
+
// Buffer spans the offset, count the portion before it
|
|
8425
|
+
bytesBeforeOffset += currentConsumeOffset - bufferStart;
|
|
8426
|
+
}
|
|
8427
|
+
}
|
|
8428
|
+
}
|
|
8429
|
+
return {
|
|
8430
|
+
bufferCount: bufferCount,
|
|
8431
|
+
totalSize: totalSize,
|
|
8432
|
+
consumeOffset: currentConsumeOffset,
|
|
8433
|
+
buffersBeforeOffset: buffersBeforeOffset,
|
|
8434
|
+
bytesBeforeOffset: bytesBeforeOffset
|
|
8435
|
+
};
|
|
8436
|
+
}
|
|
8389
8437
|
}]);
|
|
8390
8438
|
return SplitDataView;
|
|
8391
8439
|
}();
|
|
@@ -8948,6 +8996,20 @@ var BufferStream = /*#__PURE__*/function () {
|
|
|
8948
8996
|
value: function toEnd() {
|
|
8949
8997
|
this.offset = this.view.byteLength;
|
|
8950
8998
|
}
|
|
8999
|
+
|
|
9000
|
+
/**
|
|
9001
|
+
* Reports on the amount of memory held by the buffers in the view.
|
|
9002
|
+
* @returns {Object} An object containing:
|
|
9003
|
+
* - bufferCount: Number of buffers still held (not null)
|
|
9004
|
+
* - totalSize: Total size of all buffers in bytes
|
|
9005
|
+
* - consumeOffset: The current consume offset
|
|
9006
|
+
* - buffersBeforeOffset: Number of buffers before the consume offset
|
|
9007
|
+
*/
|
|
9008
|
+
}, {
|
|
9009
|
+
key: "getBufferMemoryInfo",
|
|
9010
|
+
value: function getBufferMemoryInfo() {
|
|
9011
|
+
return this.view.getBufferMemoryInfo(this.offset);
|
|
9012
|
+
}
|
|
8951
9013
|
}]);
|
|
8952
9014
|
return BufferStream;
|
|
8953
9015
|
}();
|
|
@@ -9110,6 +9172,15 @@ var EXPLICIT_BIG_ENDIAN = "1.2.840.10008.1.2.2";
|
|
|
9110
9172
|
* canonical UNDEFINED_LENGTH_FIX value of -1 instead
|
|
9111
9173
|
*/
|
|
9112
9174
|
var UNDEFINED_LENGTH = 0xffffffff;
|
|
9175
|
+
/**
|
|
9176
|
+
* Use a -1 value for the undefined length being fixed as this is consistent
|
|
9177
|
+
* with other usage and can't be confused with a real length.
|
|
9178
|
+
*/
|
|
9179
|
+
var UNDEFINED_LENGTH_FIX = -1;
|
|
9180
|
+
var ITEM_DELIMITATION_LENGTH = 0x00000000;
|
|
9181
|
+
|
|
9182
|
+
// Delimitation Value
|
|
9183
|
+
var SEQUENCE_DELIMITATION_VALUE = 0x00000000;
|
|
9113
9184
|
|
|
9114
9185
|
// Value multiplicity and padding
|
|
9115
9186
|
var VM_DELIMITER = 0x5c;
|
|
@@ -9130,6 +9201,53 @@ var unencapsulatedTransferSyntaxes = {
|
|
|
9130
9201
|
EXPLICIT_LITTLE_ENDIAN: true
|
|
9131
9202
|
};
|
|
9132
9203
|
|
|
9204
|
+
/**
|
|
9205
|
+
* Video transfer syntax UIDs (MPEG2, H.264, H.265)
|
|
9206
|
+
* These transfer syntaxes treat the entire pixel data stream as a single frame
|
|
9207
|
+
* regardless of the number of fragments.
|
|
9208
|
+
*/
|
|
9209
|
+
var videoTransferSyntaxUIDs = new Set(["1.2.840.10008.1.2.4.100",
|
|
9210
|
+
// MPEG2 Main Profile @ Main Level
|
|
9211
|
+
"1.2.840.10008.1.2.4.100.1",
|
|
9212
|
+
// MPEG2 Main Profile @ Main Level (retired)
|
|
9213
|
+
"1.2.840.10008.1.2.4.101",
|
|
9214
|
+
// MPEG2 Main Profile @ High Level
|
|
9215
|
+
"1.2.840.10008.1.2.4.101.1",
|
|
9216
|
+
// MPEG2 Main Profile @ High Level (retired)
|
|
9217
|
+
"1.2.840.10008.1.2.4.102",
|
|
9218
|
+
// MPEG-4 AVC/H.264 High Profile / Level 4.1
|
|
9219
|
+
"1.2.840.10008.1.2.4.102.1",
|
|
9220
|
+
// MPEG-4 AVC/H.264 High Profile / Level 4.1 (retired)
|
|
9221
|
+
"1.2.840.10008.1.2.4.103",
|
|
9222
|
+
// MPEG-4 AVC/H.264 BD-compatible High Profile / Level 4.1
|
|
9223
|
+
"1.2.840.10008.1.2.4.103.1",
|
|
9224
|
+
// MPEG-4 AVC/H.264 BD-compatible High Profile / Level 4.1 (retired)
|
|
9225
|
+
"1.2.840.10008.1.2.4.104",
|
|
9226
|
+
// MPEG-4 AVC/H.264 High Profile / Level 4.2 For 2D Video
|
|
9227
|
+
"1.2.840.10008.1.2.4.104.1",
|
|
9228
|
+
// MPEG-4 AVC/H.264 High Profile / Level 4.2 For 2D Video (retired)
|
|
9229
|
+
"1.2.840.10008.1.2.4.105",
|
|
9230
|
+
// MPEG-4 AVC/H.264 High Profile / Level 4.2 For 3D Video
|
|
9231
|
+
"1.2.840.10008.1.2.4.105.1",
|
|
9232
|
+
// MPEG-4 AVC/H.264 High Profile / Level 4.2 For 3D Video (retired)
|
|
9233
|
+
"1.2.840.10008.1.2.4.106",
|
|
9234
|
+
// MPEG-4 AVC/H.264 Stereo High Profile / Level 4.2
|
|
9235
|
+
"1.2.840.10008.1.2.4.106.1",
|
|
9236
|
+
// MPEG-4 AVC/H.264 Stereo High Profile / Level 4.2 (retired)
|
|
9237
|
+
"1.2.840.10008.1.2.4.107",
|
|
9238
|
+
// HEVC/H.265 Main Profile / Level 5.1
|
|
9239
|
+
"1.2.840.10008.1.2.4.108" // HEVC/H.265 Main 10 Profile / Level 5.1
|
|
9240
|
+
]);
|
|
9241
|
+
|
|
9242
|
+
/**
|
|
9243
|
+
* Checks if a transfer syntax UID is a video transfer syntax
|
|
9244
|
+
* @param {string} uid - Transfer syntax UID to check
|
|
9245
|
+
* @returns {boolean} - True if the UID is a video transfer syntax
|
|
9246
|
+
*/
|
|
9247
|
+
function isVideoTransferSyntax(uid) {
|
|
9248
|
+
return uid && videoTransferSyntaxUIDs.has(uid);
|
|
9249
|
+
}
|
|
9250
|
+
|
|
9133
9251
|
/**
|
|
9134
9252
|
* This is an enumeration of some HEX values for the tag strings, used to replace
|
|
9135
9253
|
* constants in a few places.
|
|
@@ -9148,7 +9266,13 @@ var TagHex = {
|
|
|
9148
9266
|
NumberOfFrames: "00280008",
|
|
9149
9267
|
SpecificCharacterSet: "00080005",
|
|
9150
9268
|
PixelRepresentation: "00280103",
|
|
9151
|
-
DataSetTrailingPadding: "FFFCFFFC"
|
|
9269
|
+
DataSetTrailingPadding: "FFFCFFFC",
|
|
9270
|
+
StudyInstanceUID: "0020000D",
|
|
9271
|
+
SeriesInstanceUID: "0020000E",
|
|
9272
|
+
SOPInstanceUID: "00080018",
|
|
9273
|
+
TimezoneOffsetFromUTC: "00080201",
|
|
9274
|
+
AvailableTransferSyntaxUID: "00083002",
|
|
9275
|
+
MediaStorageSOPInstanceUID: "00020003"
|
|
9152
9276
|
};
|
|
9153
9277
|
var encodingMapping = {
|
|
9154
9278
|
"": "iso-8859-1",
|
|
@@ -9187,6 +9311,202 @@ var encodingMapping = {
|
|
|
9187
9311
|
gbk: "gbk"
|
|
9188
9312
|
};
|
|
9189
9313
|
|
|
9314
|
+
/**
|
|
9315
|
+
* Maps DICOM tag hex strings to their normalized lower camelCase names
|
|
9316
|
+
* for use in listener.information tracking
|
|
9317
|
+
*/
|
|
9318
|
+
var TAG_NAME_MAP = {
|
|
9319
|
+
"0020000D": "studyInstanceUid",
|
|
9320
|
+
"0020000E": "seriesInstanceUid",
|
|
9321
|
+
"00080018": "sopInstanceUid",
|
|
9322
|
+
"00020010": "transferSyntaxUid",
|
|
9323
|
+
"00083002": "availableTransferSyntaxUid",
|
|
9324
|
+
"00080201": "timezoneOffsetFromUtc",
|
|
9325
|
+
"00080005": "specificCharacterSet",
|
|
9326
|
+
"00280008": "numberOfFrames",
|
|
9327
|
+
"00280010": "rows",
|
|
9328
|
+
"00280011": "columns",
|
|
9329
|
+
"00280002": "samplesPerPixel",
|
|
9330
|
+
"00280100": "bitsAllocated",
|
|
9331
|
+
"00280103": "pixelRepresentation"
|
|
9332
|
+
};
|
|
9333
|
+
|
|
9334
|
+
/**
|
|
9335
|
+
* Default tags to track in listener.information
|
|
9336
|
+
*/
|
|
9337
|
+
var DEFAULT_INFORMATION_TAGS = new Set(["0020000D",
|
|
9338
|
+
// StudyInstanceUID
|
|
9339
|
+
"0020000E",
|
|
9340
|
+
// SeriesInstanceUID
|
|
9341
|
+
"00080018",
|
|
9342
|
+
// SOPInstanceUID
|
|
9343
|
+
"00020010",
|
|
9344
|
+
// TransferSyntaxUID
|
|
9345
|
+
"00083002",
|
|
9346
|
+
// AvailableTransferSyntaxUID
|
|
9347
|
+
"00080201",
|
|
9348
|
+
// TimezoneOffsetFromUTC
|
|
9349
|
+
"00080005",
|
|
9350
|
+
// SpecificCharacterSet
|
|
9351
|
+
"00280008",
|
|
9352
|
+
// NumberOfFrames
|
|
9353
|
+
"00280010",
|
|
9354
|
+
// Rows
|
|
9355
|
+
"00280011",
|
|
9356
|
+
// Columns
|
|
9357
|
+
"00280002",
|
|
9358
|
+
// SamplesPerPixel
|
|
9359
|
+
"00280100",
|
|
9360
|
+
// BitsAllocated
|
|
9361
|
+
"00280103" // PixelRepresentation
|
|
9362
|
+
]);
|
|
9363
|
+
|
|
9364
|
+
/**
|
|
9365
|
+
* All valid DICOM VR (Value Representation) codes
|
|
9366
|
+
*/
|
|
9367
|
+
var VALID_VRS = new Set(["AE",
|
|
9368
|
+
// Application Entity
|
|
9369
|
+
"AS",
|
|
9370
|
+
// Age String
|
|
9371
|
+
"AT",
|
|
9372
|
+
// Attribute Tag
|
|
9373
|
+
"CS",
|
|
9374
|
+
// Code String
|
|
9375
|
+
"DA",
|
|
9376
|
+
// Date
|
|
9377
|
+
"DS",
|
|
9378
|
+
// Decimal String
|
|
9379
|
+
"DT",
|
|
9380
|
+
// Date Time
|
|
9381
|
+
"FL",
|
|
9382
|
+
// Floating Point Single
|
|
9383
|
+
"FD",
|
|
9384
|
+
// Floating Point Double
|
|
9385
|
+
"IS",
|
|
9386
|
+
// Integer String
|
|
9387
|
+
"LO",
|
|
9388
|
+
// Long String
|
|
9389
|
+
"LT",
|
|
9390
|
+
// Long Text
|
|
9391
|
+
"OB",
|
|
9392
|
+
// Other Byte
|
|
9393
|
+
"OD",
|
|
9394
|
+
// Other Double
|
|
9395
|
+
"OF",
|
|
9396
|
+
// Other Float
|
|
9397
|
+
"OL",
|
|
9398
|
+
// Other Long
|
|
9399
|
+
"OV",
|
|
9400
|
+
// Other 64-bit Very Long
|
|
9401
|
+
"OW",
|
|
9402
|
+
// Other Word
|
|
9403
|
+
"PN",
|
|
9404
|
+
// Person Name
|
|
9405
|
+
"SH",
|
|
9406
|
+
// Short String
|
|
9407
|
+
"SL",
|
|
9408
|
+
// Signed Long
|
|
9409
|
+
"SQ",
|
|
9410
|
+
// Sequence of Items
|
|
9411
|
+
"SS",
|
|
9412
|
+
// Signed Short
|
|
9413
|
+
"ST",
|
|
9414
|
+
// Short Text
|
|
9415
|
+
"SV",
|
|
9416
|
+
// Signed 64-bit Very Long
|
|
9417
|
+
"TM",
|
|
9418
|
+
// Time
|
|
9419
|
+
"UC",
|
|
9420
|
+
// Unlimited Characters
|
|
9421
|
+
"UI",
|
|
9422
|
+
// Unique Identifier
|
|
9423
|
+
"UL",
|
|
9424
|
+
// Unsigned Long
|
|
9425
|
+
"UN",
|
|
9426
|
+
// Unknown
|
|
9427
|
+
"UR",
|
|
9428
|
+
// Universal Resource
|
|
9429
|
+
"US",
|
|
9430
|
+
// Unsigned Short
|
|
9431
|
+
"UT",
|
|
9432
|
+
// Unlimited Text
|
|
9433
|
+
"UV" // Unsigned 64-bit Very Long
|
|
9434
|
+
]);
|
|
9435
|
+
|
|
9436
|
+
/**
|
|
9437
|
+
* DICOM VR (Value Representation) types that are allowed for bulkdata encoding
|
|
9438
|
+
* According to DICOMweb specification
|
|
9439
|
+
*/
|
|
9440
|
+
var BULKDATA_VRS = new Set(["DS",
|
|
9441
|
+
// Decimal String
|
|
9442
|
+
"FL",
|
|
9443
|
+
// Floating Point Single
|
|
9444
|
+
"FD",
|
|
9445
|
+
// Floating Point Double
|
|
9446
|
+
"IS",
|
|
9447
|
+
// Integer String
|
|
9448
|
+
"LT",
|
|
9449
|
+
// Long Text
|
|
9450
|
+
"OB",
|
|
9451
|
+
// Other Byte
|
|
9452
|
+
"OD",
|
|
9453
|
+
// Other Double
|
|
9454
|
+
"OF",
|
|
9455
|
+
// Other Float
|
|
9456
|
+
"OL",
|
|
9457
|
+
// Other Long
|
|
9458
|
+
"OV",
|
|
9459
|
+
// Other 64-bit Very Long
|
|
9460
|
+
"OW",
|
|
9461
|
+
// Other Word
|
|
9462
|
+
"SL",
|
|
9463
|
+
// Signed Long
|
|
9464
|
+
"SS",
|
|
9465
|
+
// Signed Short
|
|
9466
|
+
"ST",
|
|
9467
|
+
// Short Text
|
|
9468
|
+
"SV",
|
|
9469
|
+
// Signed 64-bit Very Long
|
|
9470
|
+
"UC",
|
|
9471
|
+
// Unlimited Characters
|
|
9472
|
+
"UL",
|
|
9473
|
+
// Unsigned Long
|
|
9474
|
+
"UN",
|
|
9475
|
+
// Unknown
|
|
9476
|
+
"US",
|
|
9477
|
+
// Unsigned Short
|
|
9478
|
+
"UT",
|
|
9479
|
+
// Unlimited Text
|
|
9480
|
+
"UV" // Unsigned 64-bit Very Long
|
|
9481
|
+
]);
|
|
9482
|
+
|
|
9483
|
+
var constants = /*#__PURE__*/Object.freeze({
|
|
9484
|
+
__proto__: null,
|
|
9485
|
+
BULKDATA_VRS: BULKDATA_VRS,
|
|
9486
|
+
DEFAULT_INFORMATION_TAGS: DEFAULT_INFORMATION_TAGS,
|
|
9487
|
+
DEFLATED_EXPLICIT_LITTLE_ENDIAN: DEFLATED_EXPLICIT_LITTLE_ENDIAN,
|
|
9488
|
+
EXPLICIT_BIG_ENDIAN: EXPLICIT_BIG_ENDIAN,
|
|
9489
|
+
EXPLICIT_LITTLE_ENDIAN: EXPLICIT_LITTLE_ENDIAN$1,
|
|
9490
|
+
IMPLICIT_LITTLE_ENDIAN: IMPLICIT_LITTLE_ENDIAN,
|
|
9491
|
+
ITEM_DELIMITATION_LENGTH: ITEM_DELIMITATION_LENGTH,
|
|
9492
|
+
PADDING_NULL: PADDING_NULL,
|
|
9493
|
+
PADDING_SPACE: PADDING_SPACE,
|
|
9494
|
+
PN_COMPONENT_DELIMITER: PN_COMPONENT_DELIMITER,
|
|
9495
|
+
SEQUENCE_DELIMITATION_VALUE: SEQUENCE_DELIMITATION_VALUE,
|
|
9496
|
+
SEQUENCE_DELIMITER_TAG: SEQUENCE_DELIMITER_TAG,
|
|
9497
|
+
SEQUENCE_ITEM_TAG: SEQUENCE_ITEM_TAG,
|
|
9498
|
+
TAG_NAME_MAP: TAG_NAME_MAP,
|
|
9499
|
+
TagHex: TagHex,
|
|
9500
|
+
UNDEFINED_LENGTH: UNDEFINED_LENGTH,
|
|
9501
|
+
UNDEFINED_LENGTH_FIX: UNDEFINED_LENGTH_FIX,
|
|
9502
|
+
VALID_VRS: VALID_VRS,
|
|
9503
|
+
VM_DELIMITER: VM_DELIMITER,
|
|
9504
|
+
encodingMapping: encodingMapping,
|
|
9505
|
+
isVideoTransferSyntax: isVideoTransferSyntax,
|
|
9506
|
+
unencapsulatedTransferSyntaxes: unencapsulatedTransferSyntaxes,
|
|
9507
|
+
videoTransferSyntaxUIDs: videoTransferSyntaxUIDs
|
|
9508
|
+
});
|
|
9509
|
+
|
|
9190
9510
|
/**
|
|
9191
9511
|
* Converts a PN string to the dicom+json equivalent, or returns the
|
|
9192
9512
|
* original object
|
|
@@ -11156,7 +11476,8 @@ var DicomMetaDictionary = /*#__PURE__*/function () {
|
|
|
11156
11476
|
return namedDataset;
|
|
11157
11477
|
}
|
|
11158
11478
|
|
|
11159
|
-
/**
|
|
11479
|
+
/**
|
|
11480
|
+
* converts from DICOM JSON Model dataset to a natural dataset
|
|
11160
11481
|
* - sequences become lists
|
|
11161
11482
|
* - single element lists are replaced by their first element,
|
|
11162
11483
|
* with single element lists remaining lists, but being a
|
|
@@ -12166,80 +12487,1426 @@ var Colors = /*#__PURE__*/function () {
|
|
|
12166
12487
|
} else {
|
|
12167
12488
|
return Math.pow((n + 0.055) / 1.055, 2.4);
|
|
12168
12489
|
}
|
|
12169
|
-
}
|
|
12170
|
-
}, {
|
|
12171
|
-
key: "rgb2XYZ",
|
|
12172
|
-
value: function rgb2XYZ(rgb) {
|
|
12173
|
-
var R = Colors.invGammaCorrection(rgb[0]);
|
|
12174
|
-
var G = Colors.invGammaCorrection(rgb[1]);
|
|
12175
|
-
var B = Colors.invGammaCorrection(rgb[2]);
|
|
12176
|
-
return [0.4123955889674142161 * R + 0.3575834307637148171 * G + 0.1804926473817015735 * B, 0.2125862307855955516 * R + 0.7151703037034108499 * G + 0.07220049864333622685 * B, 0.01929721549174694484 * R + 0.1191838645808485318 * G + 0.950497125131579766 * B];
|
|
12177
|
-
}
|
|
12490
|
+
}
|
|
12491
|
+
}, {
|
|
12492
|
+
key: "rgb2XYZ",
|
|
12493
|
+
value: function rgb2XYZ(rgb) {
|
|
12494
|
+
var R = Colors.invGammaCorrection(rgb[0]);
|
|
12495
|
+
var G = Colors.invGammaCorrection(rgb[1]);
|
|
12496
|
+
var B = Colors.invGammaCorrection(rgb[2]);
|
|
12497
|
+
return [0.4123955889674142161 * R + 0.3575834307637148171 * G + 0.1804926473817015735 * B, 0.2125862307855955516 * R + 0.7151703037034108499 * G + 0.07220049864333622685 * B, 0.01929721549174694484 * R + 0.1191838645808485318 * G + 0.950497125131579766 * B];
|
|
12498
|
+
}
|
|
12499
|
+
}, {
|
|
12500
|
+
key: "xyz2LAB",
|
|
12501
|
+
value: function xyz2LAB(xyz) {
|
|
12502
|
+
var whitePoint = Colors.d65WhitePointXYZ();
|
|
12503
|
+
var X = xyz[0] / whitePoint[0];
|
|
12504
|
+
var Y = xyz[1] / whitePoint[1];
|
|
12505
|
+
var Z = xyz[2] / whitePoint[2];
|
|
12506
|
+
X = Colors.labf(X);
|
|
12507
|
+
Y = Colors.labf(Y);
|
|
12508
|
+
Z = Colors.labf(Z);
|
|
12509
|
+
return [116 * Y - 16, 500 * (X - Y), 200 * (Y - Z)];
|
|
12510
|
+
}
|
|
12511
|
+
}, {
|
|
12512
|
+
key: "lab2RGB",
|
|
12513
|
+
value: function lab2RGB(lab) {
|
|
12514
|
+
return Colors.xyz2RGB(Colors.lab2XYZ(lab));
|
|
12515
|
+
}
|
|
12516
|
+
}, {
|
|
12517
|
+
key: "lab2XYZ",
|
|
12518
|
+
value: function lab2XYZ(lab) {
|
|
12519
|
+
var L = (lab[0] + 16) / 116;
|
|
12520
|
+
var a = L + lab[1] / 500;
|
|
12521
|
+
var b = L - lab[2] / 200;
|
|
12522
|
+
var whitePoint = Colors.d65WhitePointXYZ();
|
|
12523
|
+
return [whitePoint[0] * Colors.labfInv(a), whitePoint[1] * Colors.labfInv(L), whitePoint[2] * Colors.labfInv(b)];
|
|
12524
|
+
}
|
|
12525
|
+
}, {
|
|
12526
|
+
key: "xyz2RGB",
|
|
12527
|
+
value: function xyz2RGB(xyz) {
|
|
12528
|
+
var R1 = 3.2406 * xyz[0] - 1.5372 * xyz[1] - 0.4986 * xyz[2];
|
|
12529
|
+
var G1 = -0.9689 * xyz[0] + 1.8758 * xyz[1] + 0.0415 * xyz[2];
|
|
12530
|
+
var B1 = 0.0557 * xyz[0] - 0.204 * xyz[1] + 1.057 * xyz[2];
|
|
12531
|
+
|
|
12532
|
+
/* Force nonnegative values so that gamma correction is well-defined. */
|
|
12533
|
+
var minimumComponent = Math.min(R1, G1);
|
|
12534
|
+
minimumComponent = Math.min(minimumComponent, B1);
|
|
12535
|
+
if (minimumComponent < 0) {
|
|
12536
|
+
R1 -= minimumComponent;
|
|
12537
|
+
G1 -= minimumComponent;
|
|
12538
|
+
B1 -= minimumComponent;
|
|
12539
|
+
}
|
|
12540
|
+
|
|
12541
|
+
/* Transform from RGB to R'G'B' */
|
|
12542
|
+
return [Colors.gammaCorrection(R1), Colors.gammaCorrection(G1), Colors.gammaCorrection(B1)];
|
|
12543
|
+
}
|
|
12544
|
+
}, {
|
|
12545
|
+
key: "labf",
|
|
12546
|
+
value: function labf(n) {
|
|
12547
|
+
if (n >= 8.85645167903563082e-3) {
|
|
12548
|
+
return Math.pow(n, 0.333333333333333);
|
|
12549
|
+
} else {
|
|
12550
|
+
return 841.0 / 108.0 * n + 4.0 / 29.0;
|
|
12551
|
+
}
|
|
12552
|
+
}
|
|
12553
|
+
}, {
|
|
12554
|
+
key: "labfInv",
|
|
12555
|
+
value: function labfInv(n) {
|
|
12556
|
+
if (n >= 0.206896551724137931) {
|
|
12557
|
+
return n * n * n;
|
|
12558
|
+
} else {
|
|
12559
|
+
return 108.0 / 841.0 * (n - 4.0 / 29.0);
|
|
12560
|
+
}
|
|
12561
|
+
}
|
|
12562
|
+
}]);
|
|
12563
|
+
return Colors;
|
|
12564
|
+
}();
|
|
12565
|
+
|
|
12566
|
+
/**
|
|
12567
|
+
* Creates an information filter that tracks top-level DICOM attributes.
|
|
12568
|
+
*
|
|
12569
|
+
* @param {Set<string>} tags - Optional set of tag hex strings to track.
|
|
12570
|
+
* If not provided, uses DEFAULT_INFORMATION_TAGS.
|
|
12571
|
+
* @returns {Object} A filter object that adds listener.information attribute
|
|
12572
|
+
*/
|
|
12573
|
+
function createInformationFilter() {
|
|
12574
|
+
var tags = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_INFORMATION_TAGS;
|
|
12575
|
+
var filter = {
|
|
12576
|
+
information: null,
|
|
12577
|
+
/**
|
|
12578
|
+
* Initializes the filter, synchronizing the information object with the parent listener
|
|
12579
|
+
*/
|
|
12580
|
+
_init: function _init(options) {
|
|
12581
|
+
filter.information = (options === null || options === void 0 ? void 0 : options.information) || {};
|
|
12582
|
+
this.information = filter.information;
|
|
12583
|
+
},
|
|
12584
|
+
/**
|
|
12585
|
+
* Intercepts addTag calls to track top-level attributes in listener.information
|
|
12586
|
+
*/
|
|
12587
|
+
addTag: function addTag(next, tag, tagInfo) {
|
|
12588
|
+
var _this$current;
|
|
12589
|
+
// Check if this is a top-level tag (level 0) and is in our tracked set
|
|
12590
|
+
if (((_this$current = this.current) === null || _this$current === void 0 ? void 0 : _this$current.level) === 0 && tags.has(tag)) {
|
|
12591
|
+
// Store a reference to track this tag for value updates
|
|
12592
|
+
var normalizedName = TAG_NAME_MAP[tag] || tag;
|
|
12593
|
+
this.information[normalizedName] = null;
|
|
12594
|
+
|
|
12595
|
+
// Mark this tag for tracking
|
|
12596
|
+
var result = next(tag, tagInfo);
|
|
12597
|
+
this.current._trackInformation = normalizedName;
|
|
12598
|
+
return result;
|
|
12599
|
+
}
|
|
12600
|
+
return next(tag, tagInfo);
|
|
12601
|
+
},
|
|
12602
|
+
/**
|
|
12603
|
+
* Intercepts value calls to populate information values
|
|
12604
|
+
*/
|
|
12605
|
+
value: function value(next, v) {
|
|
12606
|
+
var _this$current2;
|
|
12607
|
+
// If current context is tracking information, store the first value
|
|
12608
|
+
if ((_this$current2 = this.current) !== null && _this$current2 !== void 0 && _this$current2._trackInformation) {
|
|
12609
|
+
var name = this.current._trackInformation;
|
|
12610
|
+
this.information[name] = v;
|
|
12611
|
+
this.current._trackInformation = null;
|
|
12612
|
+
}
|
|
12613
|
+
return next(v);
|
|
12614
|
+
}
|
|
12615
|
+
};
|
|
12616
|
+
return filter;
|
|
12617
|
+
}
|
|
12618
|
+
|
|
12619
|
+
/**
|
|
12620
|
+
* A DICOM Metadata listener implements the basic listener for creating a dicom
|
|
12621
|
+
* metadata instance from a stream of notification events.
|
|
12622
|
+
*
|
|
12623
|
+
* There are additional listeners defined in @cornerstonejs/metadata as well as
|
|
12624
|
+
* other event sources in that package.
|
|
12625
|
+
*
|
|
12626
|
+
* **Important behaviors:**
|
|
12627
|
+
* - Each frame is ALWAYS delivered as an array (ArrayBuffer[]), even for single frames
|
|
12628
|
+
* - Video transfer syntaxes are handled as though they were a single frame
|
|
12629
|
+
* - Binary data can be delivered fragmented - a single frame may be split across multiple ArrayBuffer fragments
|
|
12630
|
+
* - Multiple fragments are combined into one array per frame
|
|
12631
|
+
*
|
|
12632
|
+
* **WARNING** This class is still under development, do not count on the API
|
|
12633
|
+
* not changing a bit over the next few dcmjs releases.
|
|
12634
|
+
*/
|
|
12635
|
+
var DicomMetadataListener = /*#__PURE__*/function () {
|
|
12636
|
+
/**
|
|
12637
|
+
* Creates a new DicomMetadataListener instance.
|
|
12638
|
+
*
|
|
12639
|
+
* @param {Object} options - Configuration options
|
|
12640
|
+
* @param {Object} options.informationFilter - Optional information filter to use.
|
|
12641
|
+
* If not provided, creates one automatically.
|
|
12642
|
+
* @param {Set<string>} options.informationTags - Optional set of tag hex strings
|
|
12643
|
+
* to track in listener.information. If not provided, uses default tags.
|
|
12644
|
+
* @param {...Object} filters - Optional filter objects that can intercept
|
|
12645
|
+
* method calls. Each filter can have methods like addTag, startObject,
|
|
12646
|
+
* pop, or value. Each filter method receives a 'next'
|
|
12647
|
+
* function as the first argument, followed by the same arguments as
|
|
12648
|
+
* the original method.
|
|
12649
|
+
*
|
|
12650
|
+
* @example
|
|
12651
|
+
* const listener = new DicomMetadataListener();
|
|
12652
|
+
*
|
|
12653
|
+
* @example
|
|
12654
|
+
* const listener = new DicomMetadataListener(
|
|
12655
|
+
* { informationTags: new Set(['0020000D', '0020000E']) }
|
|
12656
|
+
* );
|
|
12657
|
+
*
|
|
12658
|
+
* @example
|
|
12659
|
+
* const listener = new DicomMetadataListener(
|
|
12660
|
+
* {},
|
|
12661
|
+
* {
|
|
12662
|
+
* addTag(next, tag, tagInfo) {
|
|
12663
|
+
* console.log('Adding tag:', tag);
|
|
12664
|
+
* return next(tag, tagInfo);
|
|
12665
|
+
* }
|
|
12666
|
+
* }
|
|
12667
|
+
* );
|
|
12668
|
+
*/
|
|
12669
|
+
function DicomMetadataListener() {
|
|
12670
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
12671
|
+
for (var _len = arguments.length, filters = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
12672
|
+
filters[_key - 1] = arguments[_key];
|
|
12673
|
+
}
|
|
12674
|
+
_classCallCheck(this, DicomMetadataListener);
|
|
12675
|
+
_defineProperty(this, "current", null);
|
|
12676
|
+
_defineProperty(this, "fmi", null);
|
|
12677
|
+
_defineProperty(this, "dict", null);
|
|
12678
|
+
_defineProperty(this, "filters", []);
|
|
12679
|
+
_defineProperty(this, "information", null);
|
|
12680
|
+
// Handle legacy constructor format where first arg might be a filter
|
|
12681
|
+
if (typeof options.addTag === "function" || typeof options.startObject === "function" || typeof options.pop === "function" || typeof options.value === "function") {
|
|
12682
|
+
// Legacy format: all arguments are filters
|
|
12683
|
+
filters = [options].concat(_toConsumableArray(filters));
|
|
12684
|
+
options = {};
|
|
12685
|
+
}
|
|
12686
|
+
|
|
12687
|
+
// Information filter should always be first so it can track tags
|
|
12688
|
+
// Use the provided informationFilter or create a new one
|
|
12689
|
+
var informationFilter = options.informationFilter || createInformationFilter(options.informationTags);
|
|
12690
|
+
this.filters = [informationFilter].concat(_toConsumableArray(filters));
|
|
12691
|
+
this._createMethodChains();
|
|
12692
|
+
|
|
12693
|
+
// Initialize filters to synchronize state
|
|
12694
|
+
this.init(options);
|
|
12695
|
+
}
|
|
12696
|
+
|
|
12697
|
+
/**
|
|
12698
|
+
* Initializes state, allowing it to be re-used.
|
|
12699
|
+
* @param {Object} options - Optional options to pass to the filters to re-initialize them
|
|
12700
|
+
* @param {Object} options.information - Optional information to pass to the filters
|
|
12701
|
+
* @returns {void}
|
|
12702
|
+
*/
|
|
12703
|
+
_createClass(DicomMetadataListener, [{
|
|
12704
|
+
key: "init",
|
|
12705
|
+
value: function init() {
|
|
12706
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
|
|
12707
|
+
this.current = null;
|
|
12708
|
+
this.fmi = null;
|
|
12709
|
+
this.dict = null;
|
|
12710
|
+
this.information = null;
|
|
12711
|
+
var _iterator = _createForOfIteratorHelper(this.filters),
|
|
12712
|
+
_step;
|
|
12713
|
+
try {
|
|
12714
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
12715
|
+
var _filter$_init;
|
|
12716
|
+
var filter = _step.value;
|
|
12717
|
+
(_filter$_init = filter._init) === null || _filter$_init === void 0 || _filter$_init.call(this, options);
|
|
12718
|
+
}
|
|
12719
|
+
} catch (err) {
|
|
12720
|
+
_iterator.e(err);
|
|
12721
|
+
} finally {
|
|
12722
|
+
_iterator.f();
|
|
12723
|
+
}
|
|
12724
|
+
}
|
|
12725
|
+
|
|
12726
|
+
/**
|
|
12727
|
+
* Creates method chains for each method that can be filtered.
|
|
12728
|
+
* @private
|
|
12729
|
+
*/
|
|
12730
|
+
}, {
|
|
12731
|
+
key: "_createMethodChains",
|
|
12732
|
+
value: function _createMethodChains() {
|
|
12733
|
+
var _this = this;
|
|
12734
|
+
var methods = ["addTag", "startObject", "pop", "value"];
|
|
12735
|
+
for (var _i = 0, _methods = methods; _i < _methods.length; _i++) {
|
|
12736
|
+
var methodName = _methods[_i];
|
|
12737
|
+
var baseMethod = this["_base".concat(methodName.charAt(0).toUpperCase() + methodName.slice(1))].bind(this);
|
|
12738
|
+
|
|
12739
|
+
// Build the chain by wrapping each filter
|
|
12740
|
+
// Start with the base implementation
|
|
12741
|
+
var chain = baseMethod;
|
|
12742
|
+
|
|
12743
|
+
// Apply filters in reverse order so they execute in forward order
|
|
12744
|
+
var _loop = function _loop() {
|
|
12745
|
+
var filter = _this.filters[i];
|
|
12746
|
+
if (filter && typeof filter[methodName] === "function") {
|
|
12747
|
+
var filterFn = filter[methodName];
|
|
12748
|
+
var next = chain;
|
|
12749
|
+
chain = function chain() {
|
|
12750
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
12751
|
+
args[_key2] = arguments[_key2];
|
|
12752
|
+
}
|
|
12753
|
+
return filterFn.call.apply(filterFn, [_this, next].concat(args));
|
|
12754
|
+
};
|
|
12755
|
+
}
|
|
12756
|
+
};
|
|
12757
|
+
for (var i = this.filters.length - 1; i >= 0; i--) {
|
|
12758
|
+
_loop();
|
|
12759
|
+
}
|
|
12760
|
+
|
|
12761
|
+
// Replace the method with the chained version
|
|
12762
|
+
this[methodName] = chain;
|
|
12763
|
+
}
|
|
12764
|
+
}
|
|
12765
|
+
|
|
12766
|
+
/**
|
|
12767
|
+
* Base implementation: Adds a new tag value
|
|
12768
|
+
* @private
|
|
12769
|
+
*/
|
|
12770
|
+
}, {
|
|
12771
|
+
key: "_baseAddTag",
|
|
12772
|
+
value: function _baseAddTag(tag, tagInfo) {
|
|
12773
|
+
var _this$current$level;
|
|
12774
|
+
var dest = {
|
|
12775
|
+
vr: tagInfo === null || tagInfo === void 0 ? void 0 : tagInfo.vr,
|
|
12776
|
+
Value: null
|
|
12777
|
+
};
|
|
12778
|
+
if (this.current && this.current.dest) {
|
|
12779
|
+
this.current.dest[tag] = dest;
|
|
12780
|
+
}
|
|
12781
|
+
// Tags are at the same level as their parent (they're properties, not nested structures)
|
|
12782
|
+
var level = this.current ? (_this$current$level = this.current.level) !== null && _this$current$level !== void 0 ? _this$current$level : 0 : 0;
|
|
12783
|
+
this.current = {
|
|
12784
|
+
parent: this.current,
|
|
12785
|
+
dest: dest,
|
|
12786
|
+
type: tag,
|
|
12787
|
+
tag: tag,
|
|
12788
|
+
vr: tagInfo === null || tagInfo === void 0 ? void 0 : tagInfo.vr,
|
|
12789
|
+
level: level,
|
|
12790
|
+
length: tagInfo === null || tagInfo === void 0 ? void 0 : tagInfo.length
|
|
12791
|
+
};
|
|
12792
|
+
}
|
|
12793
|
+
|
|
12794
|
+
/**
|
|
12795
|
+
* Base implementation: Starts a new object, using the provided value
|
|
12796
|
+
* @private
|
|
12797
|
+
*/
|
|
12798
|
+
}, {
|
|
12799
|
+
key: "_baseStartObject",
|
|
12800
|
+
value: function _baseStartObject() {
|
|
12801
|
+
var _this$current$level2;
|
|
12802
|
+
var dest = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
12803
|
+
// Objects/sequences are nested structures, so they increment the level
|
|
12804
|
+
// Root object is at level 0, nested objects are one level deeper
|
|
12805
|
+
var level = this.current ? ((_this$current$level2 = this.current.level) !== null && _this$current$level2 !== void 0 ? _this$current$level2 : 0) + 1 : 0;
|
|
12806
|
+
if (this.current) {
|
|
12807
|
+
this.value(dest);
|
|
12808
|
+
}
|
|
12809
|
+
this.current = {
|
|
12810
|
+
parent: this.current,
|
|
12811
|
+
dest: dest,
|
|
12812
|
+
type: "object",
|
|
12813
|
+
level: level
|
|
12814
|
+
};
|
|
12815
|
+
}
|
|
12816
|
+
|
|
12817
|
+
/**
|
|
12818
|
+
* Base implementation: Pops the current value being created off the stack.
|
|
12819
|
+
* @private
|
|
12820
|
+
*/
|
|
12821
|
+
}, {
|
|
12822
|
+
key: "_basePop",
|
|
12823
|
+
value: function _basePop() {
|
|
12824
|
+
var _this$current$pop, _this$current$pop2, _this$current3, _result$Value;
|
|
12825
|
+
var result = (_this$current$pop = (_this$current$pop2 = (_this$current3 = this.current).pop) === null || _this$current$pop2 === void 0 ? void 0 : _this$current$pop2.call(_this$current3)) !== null && _this$current$pop !== void 0 ? _this$current$pop : this.current.dest;
|
|
12826
|
+
if (result.InlineBinary) {
|
|
12827
|
+
console.log("********* InlineBinary already set", result, this.current);
|
|
12828
|
+
}
|
|
12829
|
+
if (result.Value === null) {
|
|
12830
|
+
result.Value = [];
|
|
12831
|
+
} else if (((_result$Value = result.Value) === null || _result$Value === void 0 ? void 0 : _result$Value.length) === 1 && (result.Value[0] === null || result.Value[0] === undefined)) {
|
|
12832
|
+
result.Value = [];
|
|
12833
|
+
}
|
|
12834
|
+
this.current = this.current.parent;
|
|
12835
|
+
return result;
|
|
12836
|
+
}
|
|
12837
|
+
|
|
12838
|
+
/**
|
|
12839
|
+
* Base implementation: Registers a new value for the current destination being created.
|
|
12840
|
+
*
|
|
12841
|
+
* Note: Binary data (ArrayBuffer) can be delivered fragmented across multiple calls.
|
|
12842
|
+
* Multiple fragments are combined into arrays. Each frame is always delivered as an array.
|
|
12843
|
+
*
|
|
12844
|
+
* @private
|
|
12845
|
+
*/
|
|
12846
|
+
}, {
|
|
12847
|
+
key: "_baseValue",
|
|
12848
|
+
value: function _baseValue(v) {
|
|
12849
|
+
var _this$current$dest;
|
|
12850
|
+
if (Array.isArray(this.current.dest)) {
|
|
12851
|
+
this.current.dest.push(v);
|
|
12852
|
+
return;
|
|
12853
|
+
}
|
|
12854
|
+
(_this$current$dest = this.current.dest).Value || (_this$current$dest.Value = []);
|
|
12855
|
+
this.current.dest.Value.push(v);
|
|
12856
|
+
}
|
|
12857
|
+
|
|
12858
|
+
/**
|
|
12859
|
+
* Gets the Transfer Syntax UID from the File Meta Information (FMI)
|
|
12860
|
+
* @returns {string|undefined} - Transfer syntax UID or undefined if not available
|
|
12861
|
+
*/
|
|
12862
|
+
}, {
|
|
12863
|
+
key: "getTransferSyntaxUID",
|
|
12864
|
+
value: function getTransferSyntaxUID() {
|
|
12865
|
+
var _this$fmi$transferSyn;
|
|
12866
|
+
if (!this.fmi) {
|
|
12867
|
+
return undefined;
|
|
12868
|
+
}
|
|
12869
|
+
var transferSyntaxTag = "00020010"; // TransferSyntaxUID tag
|
|
12870
|
+
if ((_this$fmi$transferSyn = this.fmi[transferSyntaxTag]) !== null && _this$fmi$transferSyn !== void 0 && _this$fmi$transferSyn.Value && Array.isArray(this.fmi[transferSyntaxTag].Value) && this.fmi[transferSyntaxTag].Value.length > 0) {
|
|
12871
|
+
return this.fmi[transferSyntaxTag].Value[0];
|
|
12872
|
+
}
|
|
12873
|
+
return undefined;
|
|
12874
|
+
}
|
|
12875
|
+
}]);
|
|
12876
|
+
return DicomMetadataListener;
|
|
12877
|
+
}();
|
|
12878
|
+
|
|
12879
|
+
/**
|
|
12880
|
+
* This is an asynchronous binary DICOM reader.
|
|
12881
|
+
*
|
|
12882
|
+
* Assume this is still preliminary as to the exact interface as it is
|
|
12883
|
+
* initially being released for testing purposes only.
|
|
12884
|
+
*
|
|
12885
|
+
* There is no support for compressed streams.
|
|
12886
|
+
*/
|
|
12887
|
+
var AsyncDicomReader = /*#__PURE__*/function () {
|
|
12888
|
+
function AsyncDicomReader() {
|
|
12889
|
+
var _options$maxFragmentS;
|
|
12890
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
12891
|
+
_classCallCheck(this, AsyncDicomReader);
|
|
12892
|
+
_defineProperty(this, "syntax", EXPLICIT_LITTLE_ENDIAN$1);
|
|
12893
|
+
this.isLittleEndian = options === null || options === void 0 ? void 0 : options.isLittleEndian;
|
|
12894
|
+
// Default maxFragmentSize is 128 MB (128 * 1024 * 1024 bytes)
|
|
12895
|
+
this.maxFragmentSize = (_options$maxFragmentS = options === null || options === void 0 ? void 0 : options.maxFragmentSize) !== null && _options$maxFragmentS !== void 0 ? _options$maxFragmentS : 128 * 1024 * 1024;
|
|
12896
|
+
this.stream = new ReadBufferStream(null, this.isLittleEndian, _objectSpread2({
|
|
12897
|
+
clearBuffers: true
|
|
12898
|
+
}, options));
|
|
12899
|
+
}
|
|
12900
|
+
|
|
12901
|
+
/**
|
|
12902
|
+
* Reads the preamble and checks for the DICM marker.
|
|
12903
|
+
* Returns true if found/read, leaving the stream past the
|
|
12904
|
+
* marker, or false, having not found the marker.
|
|
12905
|
+
*
|
|
12906
|
+
* If no preamble is found, attempts to detect raw LEI/LEE encoding
|
|
12907
|
+
* by examining the first tag structure.
|
|
12908
|
+
*/
|
|
12909
|
+
_createClass(AsyncDicomReader, [{
|
|
12910
|
+
key: "readPreamble",
|
|
12911
|
+
value: (function () {
|
|
12912
|
+
var _readPreamble = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
12913
|
+
var stream;
|
|
12914
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
12915
|
+
while (1) switch (_context.prev = _context.next) {
|
|
12916
|
+
case 0:
|
|
12917
|
+
stream = this.stream;
|
|
12918
|
+
_context.next = 3;
|
|
12919
|
+
return stream.ensureAvailable();
|
|
12920
|
+
case 3:
|
|
12921
|
+
stream.reset();
|
|
12922
|
+
stream.increment(128);
|
|
12923
|
+
if (!(stream.readAsciiString(4) !== "DICM")) {
|
|
12924
|
+
_context.next = 10;
|
|
12925
|
+
break;
|
|
12926
|
+
}
|
|
12927
|
+
stream.reset();
|
|
12928
|
+
// No preamble found - try to detect raw dataset encoding
|
|
12929
|
+
_context.next = 9;
|
|
12930
|
+
return this.detectRawEncoding();
|
|
12931
|
+
case 9:
|
|
12932
|
+
return _context.abrupt("return", false);
|
|
12933
|
+
case 10:
|
|
12934
|
+
return _context.abrupt("return", true);
|
|
12935
|
+
case 11:
|
|
12936
|
+
case "end":
|
|
12937
|
+
return _context.stop();
|
|
12938
|
+
}
|
|
12939
|
+
}, _callee, this);
|
|
12940
|
+
}));
|
|
12941
|
+
function readPreamble() {
|
|
12942
|
+
return _readPreamble.apply(this, arguments);
|
|
12943
|
+
}
|
|
12944
|
+
return readPreamble;
|
|
12945
|
+
}()
|
|
12946
|
+
/**
|
|
12947
|
+
* Detects whether a raw dataset (no Part 10 preamble) is LEI or LEE encoded.
|
|
12948
|
+
* This is done by examining the first tag structure:
|
|
12949
|
+
* - LEI: Tag (4 bytes) + Length (4 bytes) - no VR
|
|
12950
|
+
* - LEE: Tag (4 bytes) + VR (2 bytes ASCII) + Length (2 or 4 bytes)
|
|
12951
|
+
*
|
|
12952
|
+
* We check if bytes 4-5 look like a valid DICOM VR (2 ASCII letters that
|
|
12953
|
+
* match known VR codes). If a valid VR is detected, we use LEE, otherwise LEI.
|
|
12954
|
+
*/
|
|
12955
|
+
)
|
|
12956
|
+
}, {
|
|
12957
|
+
key: "detectRawEncoding",
|
|
12958
|
+
value: (function () {
|
|
12959
|
+
var _detectRawEncoding = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
|
12960
|
+
var stream, group, byte4, byte5, potentialLength, isASCIILetter, vrCandidate;
|
|
12961
|
+
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
12962
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
12963
|
+
case 0:
|
|
12964
|
+
stream = this.stream;
|
|
12965
|
+
_context2.next = 3;
|
|
12966
|
+
return stream.ensureAvailable(8);
|
|
12967
|
+
case 3:
|
|
12968
|
+
// Need at least 8 bytes (tag + length) to detect
|
|
12969
|
+
|
|
12970
|
+
stream.reset();
|
|
12971
|
+
stream.setEndian(true); // Little endian for both LEI and LEE
|
|
12972
|
+
|
|
12973
|
+
// Read the tag (first 4 bytes)
|
|
12974
|
+
group = stream.readUint16();
|
|
12975
|
+
stream.readUint16();
|
|
12976
|
+
|
|
12977
|
+
// Verify this looks like a DICOM file - first tag should be in group 0008
|
|
12978
|
+
if (!(group !== 0x0008)) {
|
|
12979
|
+
_context2.next = 9;
|
|
12980
|
+
break;
|
|
12981
|
+
}
|
|
12982
|
+
throw new Error("Invalid DICOM file: expected first tag group to be 0x0008, found 0x".concat(group.toString(16).padStart(4, "0")));
|
|
12983
|
+
case 9:
|
|
12984
|
+
// Check if bytes 4-5 (after tag) look like a valid VR (2 ASCII letters)
|
|
12985
|
+
byte4 = stream.peekUint8(0);
|
|
12986
|
+
byte5 = stream.peekUint8(1); // If we're going to assume LEI, check the length is even (DICOM requirement)
|
|
12987
|
+
// Read the length value (4 bytes after tag in LEI format) as little-endian uint32
|
|
12988
|
+
_context2.next = 13;
|
|
12989
|
+
return stream.ensureAvailable(8);
|
|
12990
|
+
case 13:
|
|
12991
|
+
// Need at least 8 bytes (tag + length)
|
|
12992
|
+
potentialLength = stream.view.getUint32(stream.offset, true); // true = little endian
|
|
12993
|
+
isASCIILetter = function isASCIILetter(byte) {
|
|
12994
|
+
return byte >= 0x41 && byte <= 0x5a ||
|
|
12995
|
+
// A-Z
|
|
12996
|
+
byte >= 0x61 && byte <= 0x7a; // a-z
|
|
12997
|
+
};
|
|
12998
|
+
if (!(isASCIILetter(byte4) && isASCIILetter(byte5))) {
|
|
12999
|
+
_context2.next = 26;
|
|
13000
|
+
break;
|
|
13001
|
+
}
|
|
13002
|
+
// Check if it's a valid VR code
|
|
13003
|
+
vrCandidate = String.fromCharCode(byte4, byte5).toUpperCase();
|
|
13004
|
+
if (!VALID_VRS.has(vrCandidate)) {
|
|
13005
|
+
_context2.next = 21;
|
|
13006
|
+
break;
|
|
13007
|
+
}
|
|
13008
|
+
// Valid VR detected - this is LEE (Explicit Little Endian)
|
|
13009
|
+
this.syntax = EXPLICIT_LITTLE_ENDIAN$1;
|
|
13010
|
+
_context2.next = 24;
|
|
13011
|
+
break;
|
|
13012
|
+
case 21:
|
|
13013
|
+
if (!(potentialLength % 2 !== 0)) {
|
|
13014
|
+
_context2.next = 23;
|
|
13015
|
+
break;
|
|
13016
|
+
}
|
|
13017
|
+
throw new Error("Invalid DICOM file: detected LEI encoding but length is odd (".concat(potentialLength, "), which is not allowed in DICOM"));
|
|
13018
|
+
case 23:
|
|
13019
|
+
this.syntax = IMPLICIT_LITTLE_ENDIAN;
|
|
13020
|
+
case 24:
|
|
13021
|
+
_context2.next = 29;
|
|
13022
|
+
break;
|
|
13023
|
+
case 26:
|
|
13024
|
+
if (!(potentialLength % 2 !== 0)) {
|
|
13025
|
+
_context2.next = 28;
|
|
13026
|
+
break;
|
|
13027
|
+
}
|
|
13028
|
+
throw new Error("Invalid DICOM file: detected LEI encoding but length is odd (".concat(potentialLength, "), which is not allowed in DICOM"));
|
|
13029
|
+
case 28:
|
|
13030
|
+
this.syntax = IMPLICIT_LITTLE_ENDIAN;
|
|
13031
|
+
case 29:
|
|
13032
|
+
// Reset stream to beginning for reading
|
|
13033
|
+
stream.reset();
|
|
13034
|
+
case 30:
|
|
13035
|
+
case "end":
|
|
13036
|
+
return _context2.stop();
|
|
13037
|
+
}
|
|
13038
|
+
}, _callee2, this);
|
|
13039
|
+
}));
|
|
13040
|
+
function detectRawEncoding() {
|
|
13041
|
+
return _detectRawEncoding.apply(this, arguments);
|
|
13042
|
+
}
|
|
13043
|
+
return detectRawEncoding;
|
|
13044
|
+
}())
|
|
13045
|
+
}, {
|
|
13046
|
+
key: "readFile",
|
|
13047
|
+
value: function () {
|
|
13048
|
+
var _readFile = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
|
|
13049
|
+
var options,
|
|
13050
|
+
hasPreamble,
|
|
13051
|
+
_listener,
|
|
13052
|
+
information,
|
|
13053
|
+
listener,
|
|
13054
|
+
_this$meta,
|
|
13055
|
+
_information,
|
|
13056
|
+
_args3 = arguments;
|
|
13057
|
+
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
13058
|
+
while (1) switch (_context3.prev = _context3.next) {
|
|
13059
|
+
case 0:
|
|
13060
|
+
options = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : undefined;
|
|
13061
|
+
_context3.next = 3;
|
|
13062
|
+
return this.readPreamble();
|
|
13063
|
+
case 3:
|
|
13064
|
+
hasPreamble = _context3.sent;
|
|
13065
|
+
if (hasPreamble) {
|
|
13066
|
+
_context3.next = 14;
|
|
13067
|
+
break;
|
|
13068
|
+
}
|
|
13069
|
+
// Handle raw dataset (no Part 10 preamble)
|
|
13070
|
+
// Encoding should already be detected in readPreamble()
|
|
13071
|
+
this.meta = {}; // No meta header for raw datasets
|
|
13072
|
+
_listener = (options === null || options === void 0 ? void 0 : options.listener) || new DicomMetadataListener();
|
|
13073
|
+
if (_listener.information) {
|
|
13074
|
+
information = _listener.information;
|
|
13075
|
+
information.transferSyntaxUid = this.syntax;
|
|
13076
|
+
}
|
|
13077
|
+
this.dict || (this.dict = {});
|
|
13078
|
+
_listener.startObject(this.dict);
|
|
13079
|
+
_context3.next = 12;
|
|
13080
|
+
return this.read(_listener, options);
|
|
13081
|
+
case 12:
|
|
13082
|
+
this.dict = _context3.sent;
|
|
13083
|
+
return _context3.abrupt("return", this);
|
|
13084
|
+
case 14:
|
|
13085
|
+
_context3.next = 16;
|
|
13086
|
+
return this.readMeta(options);
|
|
13087
|
+
case 16:
|
|
13088
|
+
this.meta = _context3.sent;
|
|
13089
|
+
listener = (options === null || options === void 0 ? void 0 : options.listener) || new DicomMetadataListener();
|
|
13090
|
+
if (listener.information) {
|
|
13091
|
+
_information = listener.information;
|
|
13092
|
+
_information.transferSyntaxUid = this.syntax;
|
|
13093
|
+
_information.sopInstanceUid = (_this$meta = this.meta) === null || _this$meta === void 0 || (_this$meta = _this$meta[TagHex.MediaStoreSOPInstanceUID]) === null || _this$meta === void 0 ? void 0 : _this$meta.Value[0];
|
|
13094
|
+
}
|
|
13095
|
+
this.dict || (this.dict = {});
|
|
13096
|
+
listener.startObject(this.dict);
|
|
13097
|
+
_context3.next = 23;
|
|
13098
|
+
return this.read(listener, options);
|
|
13099
|
+
case 23:
|
|
13100
|
+
this.dict = _context3.sent;
|
|
13101
|
+
return _context3.abrupt("return", this);
|
|
13102
|
+
case 25:
|
|
13103
|
+
case "end":
|
|
13104
|
+
return _context3.stop();
|
|
13105
|
+
}
|
|
13106
|
+
}, _callee3, this);
|
|
13107
|
+
}));
|
|
13108
|
+
function readFile() {
|
|
13109
|
+
return _readFile.apply(this, arguments);
|
|
13110
|
+
}
|
|
13111
|
+
return readFile;
|
|
13112
|
+
}()
|
|
13113
|
+
/**
|
|
13114
|
+
* Reads the file meta information.
|
|
13115
|
+
*
|
|
13116
|
+
* @param options.maxSizeMeta - maximum number of bytes for reading the meta
|
|
13117
|
+
* header when it isn't in a group length section.
|
|
13118
|
+
* @param options.ignoreErrors - allow reading past some errors.
|
|
13119
|
+
* In this case, reading a meta section not inside a group length.
|
|
13120
|
+
*/
|
|
13121
|
+
}, {
|
|
13122
|
+
key: "readMeta",
|
|
13123
|
+
value: (function () {
|
|
13124
|
+
var _readMeta = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
|
|
13125
|
+
var options,
|
|
13126
|
+
stream,
|
|
13127
|
+
metaStartPos,
|
|
13128
|
+
el,
|
|
13129
|
+
metaLength,
|
|
13130
|
+
metaStream,
|
|
13131
|
+
_args4 = arguments;
|
|
13132
|
+
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
13133
|
+
while (1) switch (_context4.prev = _context4.next) {
|
|
13134
|
+
case 0:
|
|
13135
|
+
options = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : undefined;
|
|
13136
|
+
stream = this.stream;
|
|
13137
|
+
_context4.next = 4;
|
|
13138
|
+
return stream.ensureAvailable();
|
|
13139
|
+
case 4:
|
|
13140
|
+
metaStartPos = stream.offset;
|
|
13141
|
+
el = this.readTagHeader();
|
|
13142
|
+
if (!(el.tag !== TagHex.FileMetaInformationGroupLength)) {
|
|
13143
|
+
_context4.next = 15;
|
|
13144
|
+
break;
|
|
13145
|
+
}
|
|
13146
|
+
if (options !== null && options !== void 0 && options.ignoreErrors) {
|
|
13147
|
+
_context4.next = 9;
|
|
13148
|
+
break;
|
|
13149
|
+
}
|
|
13150
|
+
throw new Error("Invalid DICOM file, meta length tag is malformed or not present.");
|
|
13151
|
+
case 9:
|
|
13152
|
+
// reset stream to the position where we started reading tags
|
|
13153
|
+
stream.offset = metaStartPos;
|
|
13154
|
+
// Wait for at least 10k to be available to make sure there is enough
|
|
13155
|
+
// data to read the entire Meta header
|
|
13156
|
+
_context4.next = 12;
|
|
13157
|
+
return stream.ensureAvailable((options === null || options === void 0 ? void 0 : options.maxSizeMeta) || 1024 * 10);
|
|
13158
|
+
case 12:
|
|
13159
|
+
// read meta header elements sequentially
|
|
13160
|
+
this.meta = DicomMessage._read(stream, EXPLICIT_LITTLE_ENDIAN$1, {
|
|
13161
|
+
untilTag: "00030000",
|
|
13162
|
+
stopOnGreaterTag: true,
|
|
13163
|
+
ignoreErrors: true
|
|
13164
|
+
});
|
|
13165
|
+
_context4.next = 20;
|
|
13166
|
+
break;
|
|
13167
|
+
case 15:
|
|
13168
|
+
// meta length tag is present
|
|
13169
|
+
metaLength = el.vrObj.readBytes(stream);
|
|
13170
|
+
_context4.next = 18;
|
|
13171
|
+
return stream.ensureAvailable(metaLength);
|
|
13172
|
+
case 18:
|
|
13173
|
+
// read header buffer using the specified meta length
|
|
13174
|
+
metaStream = stream.more(metaLength);
|
|
13175
|
+
this.meta = DicomMessage._read(metaStream, EXPLICIT_LITTLE_ENDIAN$1, {});
|
|
13176
|
+
case 20:
|
|
13177
|
+
this.syntax = this.meta[TagHex.TransferSyntaxUID].Value[0];
|
|
13178
|
+
return _context4.abrupt("return", this.meta);
|
|
13179
|
+
case 22:
|
|
13180
|
+
case "end":
|
|
13181
|
+
return _context4.stop();
|
|
13182
|
+
}
|
|
13183
|
+
}, _callee4, this);
|
|
13184
|
+
}));
|
|
13185
|
+
function readMeta() {
|
|
13186
|
+
return _readMeta.apply(this, arguments);
|
|
13187
|
+
}
|
|
13188
|
+
return readMeta;
|
|
13189
|
+
}())
|
|
13190
|
+
}, {
|
|
13191
|
+
key: "read",
|
|
13192
|
+
value: function () {
|
|
13193
|
+
var _read = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee5(listener, options) {
|
|
13194
|
+
var untilOffset, stream, tagInfo, tag, tagObj, length, addTagResult;
|
|
13195
|
+
return _regeneratorRuntime().wrap(function _callee5$(_context5) {
|
|
13196
|
+
while (1) switch (_context5.prev = _context5.next) {
|
|
13197
|
+
case 0:
|
|
13198
|
+
untilOffset = (options === null || options === void 0 ? void 0 : options.untilOffset) || Number.MAX_SAFE_INTEGER;
|
|
13199
|
+
this.listener = listener;
|
|
13200
|
+
stream = this.stream;
|
|
13201
|
+
_context5.next = 5;
|
|
13202
|
+
return stream.ensureAvailable();
|
|
13203
|
+
case 5:
|
|
13204
|
+
if (!(stream.offset < untilOffset && stream.isAvailable(1, false))) {
|
|
13205
|
+
_context5.next = 43;
|
|
13206
|
+
break;
|
|
13207
|
+
}
|
|
13208
|
+
// Consume before reading the tag so that data before the
|
|
13209
|
+
// current tag can be cleared.
|
|
13210
|
+
stream.consume();
|
|
13211
|
+
tagInfo = this.readTagHeader(options);
|
|
13212
|
+
tag = tagInfo.tag, tagObj = tagInfo.tagObj, length = tagInfo.length;
|
|
13213
|
+
if (!(tag === TagHex.ItemDelimitationEnd)) {
|
|
13214
|
+
_context5.next = 11;
|
|
13215
|
+
break;
|
|
13216
|
+
}
|
|
13217
|
+
return _context5.abrupt("return", listener.pop());
|
|
13218
|
+
case 11:
|
|
13219
|
+
if (!tagObj.isInstruction()) {
|
|
13220
|
+
_context5.next = 13;
|
|
13221
|
+
break;
|
|
13222
|
+
}
|
|
13223
|
+
return _context5.abrupt("continue", 5);
|
|
13224
|
+
case 13:
|
|
13225
|
+
if (!(tagObj.group() === 0 || tag === TagHex.DataSetTrailingPadding)) {
|
|
13226
|
+
_context5.next = 16;
|
|
13227
|
+
break;
|
|
13228
|
+
}
|
|
13229
|
+
// Group length
|
|
13230
|
+
stream.increment(tagObj.length);
|
|
13231
|
+
return _context5.abrupt("continue", 5);
|
|
13232
|
+
case 16:
|
|
13233
|
+
addTagResult = listener.addTag(tag, tagInfo);
|
|
13234
|
+
if (!this.isSequence(tagInfo)) {
|
|
13235
|
+
_context5.next = 22;
|
|
13236
|
+
break;
|
|
13237
|
+
}
|
|
13238
|
+
_context5.next = 20;
|
|
13239
|
+
return this.readSequence(listener, tagInfo, options);
|
|
13240
|
+
case 20:
|
|
13241
|
+
_context5.next = 38;
|
|
13242
|
+
break;
|
|
13243
|
+
case 22:
|
|
13244
|
+
if (!tagObj.isPixelDataTag()) {
|
|
13245
|
+
_context5.next = 27;
|
|
13246
|
+
break;
|
|
13247
|
+
}
|
|
13248
|
+
_context5.next = 25;
|
|
13249
|
+
return this.readPixelData(tagInfo);
|
|
13250
|
+
case 25:
|
|
13251
|
+
_context5.next = 38;
|
|
13252
|
+
break;
|
|
13253
|
+
case 27:
|
|
13254
|
+
if (!(length === UNDEFINED_LENGTH_FIX)) {
|
|
13255
|
+
_context5.next = 31;
|
|
13256
|
+
break;
|
|
13257
|
+
}
|
|
13258
|
+
throw new Error("Can't handle tag ".concat(tagInfo.tag, " with -1 length and not sequence"));
|
|
13259
|
+
case 31:
|
|
13260
|
+
if (!((addTagResult === null || addTagResult === void 0 ? void 0 : addTagResult.expectsRaw) === true && length > 0)) {
|
|
13261
|
+
_context5.next = 36;
|
|
13262
|
+
break;
|
|
13263
|
+
}
|
|
13264
|
+
_context5.next = 34;
|
|
13265
|
+
return this.readRawBinary(tagInfo);
|
|
13266
|
+
case 34:
|
|
13267
|
+
_context5.next = 38;
|
|
13268
|
+
break;
|
|
13269
|
+
case 36:
|
|
13270
|
+
_context5.next = 38;
|
|
13271
|
+
return this.readSingle(tagInfo, listener, options);
|
|
13272
|
+
case 38:
|
|
13273
|
+
listener.pop();
|
|
13274
|
+
_context5.next = 41;
|
|
13275
|
+
return this.stream.ensureAvailable();
|
|
13276
|
+
case 41:
|
|
13277
|
+
_context5.next = 5;
|
|
13278
|
+
break;
|
|
13279
|
+
case 43:
|
|
13280
|
+
return _context5.abrupt("return", listener.pop());
|
|
13281
|
+
case 44:
|
|
13282
|
+
case "end":
|
|
13283
|
+
return _context5.stop();
|
|
13284
|
+
}
|
|
13285
|
+
}, _callee5, this);
|
|
13286
|
+
}));
|
|
13287
|
+
function read(_x, _x2) {
|
|
13288
|
+
return _read.apply(this, arguments);
|
|
13289
|
+
}
|
|
13290
|
+
return read;
|
|
13291
|
+
}()
|
|
13292
|
+
}, {
|
|
13293
|
+
key: "readSequence",
|
|
13294
|
+
value: function () {
|
|
13295
|
+
var _readSequence = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee6(listener, sqTagInfo, options) {
|
|
13296
|
+
var length, stream, syntax, endOffset, tagInfo, tag;
|
|
13297
|
+
return _regeneratorRuntime().wrap(function _callee6$(_context6) {
|
|
13298
|
+
while (1) switch (_context6.prev = _context6.next) {
|
|
13299
|
+
case 0:
|
|
13300
|
+
length = sqTagInfo.length;
|
|
13301
|
+
stream = this.stream, syntax = this.syntax;
|
|
13302
|
+
endOffset = length === UNDEFINED_LENGTH_FIX ? Number.MAX_SAFE_INTEGER : stream.offset + length;
|
|
13303
|
+
case 3:
|
|
13304
|
+
_context6.t0 = stream.offset < endOffset;
|
|
13305
|
+
if (!_context6.t0) {
|
|
13306
|
+
_context6.next = 8;
|
|
13307
|
+
break;
|
|
13308
|
+
}
|
|
13309
|
+
_context6.next = 7;
|
|
13310
|
+
return stream.ensureAvailable();
|
|
13311
|
+
case 7:
|
|
13312
|
+
_context6.t0 = _context6.sent;
|
|
13313
|
+
case 8:
|
|
13314
|
+
if (!_context6.t0) {
|
|
13315
|
+
_context6.next = 25;
|
|
13316
|
+
break;
|
|
13317
|
+
}
|
|
13318
|
+
tagInfo = this.readTagHeader(syntax, options);
|
|
13319
|
+
tag = tagInfo.tag;
|
|
13320
|
+
if (!(tag === TagHex.Item)) {
|
|
13321
|
+
_context6.next = 17;
|
|
13322
|
+
break;
|
|
13323
|
+
}
|
|
13324
|
+
listener.startObject();
|
|
13325
|
+
_context6.next = 15;
|
|
13326
|
+
return this.read(listener, _objectSpread2(_objectSpread2({}, options), {}, {
|
|
13327
|
+
untilOffset: endOffset
|
|
13328
|
+
}));
|
|
13329
|
+
case 15:
|
|
13330
|
+
_context6.next = 23;
|
|
13331
|
+
break;
|
|
13332
|
+
case 17:
|
|
13333
|
+
if (!(tag === TagHex.SequenceDelimitationEnd)) {
|
|
13334
|
+
_context6.next = 21;
|
|
13335
|
+
break;
|
|
13336
|
+
}
|
|
13337
|
+
return _context6.abrupt("return");
|
|
13338
|
+
case 21:
|
|
13339
|
+
console.warn("Unknown tag info", length, tagInfo);
|
|
13340
|
+
throw new Error();
|
|
13341
|
+
case 23:
|
|
13342
|
+
_context6.next = 3;
|
|
13343
|
+
break;
|
|
13344
|
+
case 25:
|
|
13345
|
+
case "end":
|
|
13346
|
+
return _context6.stop();
|
|
13347
|
+
}
|
|
13348
|
+
}, _callee6, this);
|
|
13349
|
+
}));
|
|
13350
|
+
function readSequence(_x3, _x4, _x5) {
|
|
13351
|
+
return _readSequence.apply(this, arguments);
|
|
13352
|
+
}
|
|
13353
|
+
return readSequence;
|
|
13354
|
+
}()
|
|
13355
|
+
}, {
|
|
13356
|
+
key: "readPixelData",
|
|
13357
|
+
value: function readPixelData(tagInfo) {
|
|
13358
|
+
if (tagInfo.length === -1) {
|
|
13359
|
+
return this.readCompressed(tagInfo);
|
|
13360
|
+
}
|
|
13361
|
+
return this.readUncompressed(tagInfo);
|
|
13362
|
+
}
|
|
13363
|
+
|
|
13364
|
+
/**
|
|
13365
|
+
* Emits one or more listener.value() calls for a fragment, splitting if needed.
|
|
13366
|
+
* This does NOT start/pop any array contexts; callers control the surrounding structure.
|
|
13367
|
+
*/
|
|
13368
|
+
}, {
|
|
13369
|
+
key: "_emitSplitValues",
|
|
13370
|
+
value: (function () {
|
|
13371
|
+
var _emitSplitValues2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee7(length) {
|
|
13372
|
+
var stream, listener, maxFragmentSize, offset, chunkSize, buffer;
|
|
13373
|
+
return _regeneratorRuntime().wrap(function _callee7$(_context7) {
|
|
13374
|
+
while (1) switch (_context7.prev = _context7.next) {
|
|
13375
|
+
case 0:
|
|
13376
|
+
stream = this.stream, listener = this.listener;
|
|
13377
|
+
maxFragmentSize = this.maxFragmentSize;
|
|
13378
|
+
offset = 0;
|
|
13379
|
+
case 3:
|
|
13380
|
+
if (!(offset < length)) {
|
|
13381
|
+
_context7.next = 13;
|
|
13382
|
+
break;
|
|
13383
|
+
}
|
|
13384
|
+
chunkSize = Math.min(maxFragmentSize, length - offset);
|
|
13385
|
+
_context7.next = 7;
|
|
13386
|
+
return stream.ensureAvailable(chunkSize);
|
|
13387
|
+
case 7:
|
|
13388
|
+
buffer = stream.readArrayBuffer(chunkSize);
|
|
13389
|
+
listener.value(buffer);
|
|
13390
|
+
offset += chunkSize;
|
|
13391
|
+
stream.consume();
|
|
13392
|
+
_context7.next = 3;
|
|
13393
|
+
break;
|
|
13394
|
+
case 13:
|
|
13395
|
+
case "end":
|
|
13396
|
+
return _context7.stop();
|
|
13397
|
+
}
|
|
13398
|
+
}, _callee7, this);
|
|
13399
|
+
}));
|
|
13400
|
+
function _emitSplitValues(_x6) {
|
|
13401
|
+
return _emitSplitValues2.apply(this, arguments);
|
|
13402
|
+
}
|
|
13403
|
+
return _emitSplitValues;
|
|
13404
|
+
}()
|
|
13405
|
+
/**
|
|
13406
|
+
* Reads compressed streams.
|
|
13407
|
+
*/
|
|
13408
|
+
)
|
|
13409
|
+
}, {
|
|
13410
|
+
key: "readCompressed",
|
|
13411
|
+
value: (function () {
|
|
13412
|
+
var _readCompressed = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee8(_tagInfo) {
|
|
13413
|
+
var _listener$information;
|
|
13414
|
+
var stream, listener, transferSyntaxUid, isVideo, numberOfFrames, isSingleFrame, offsets, singleArray, startOffset, frameNumber, lastFrame, frameTag, length;
|
|
13415
|
+
return _regeneratorRuntime().wrap(function _callee8$(_context8) {
|
|
13416
|
+
while (1) switch (_context8.prev = _context8.next) {
|
|
13417
|
+
case 0:
|
|
13418
|
+
stream = this.stream, listener = this.listener;
|
|
13419
|
+
transferSyntaxUid = this.syntax;
|
|
13420
|
+
_context8.next = 4;
|
|
13421
|
+
return stream.ensureAvailable();
|
|
13422
|
+
case 4:
|
|
13423
|
+
// Check if this is a video transfer syntax
|
|
13424
|
+
isVideo = isVideoTransferSyntax(transferSyntaxUid); // Check number of frames - only use video logic for single frame (or undefined)
|
|
13425
|
+
numberOfFrames = (_listener$information = listener.information) === null || _listener$information === void 0 ? void 0 : _listener$information.numberOfFrames;
|
|
13426
|
+
isSingleFrame = !numberOfFrames || parseInt(numberOfFrames) <= 1;
|
|
13427
|
+
_context8.next = 9;
|
|
13428
|
+
return this.readOffsets();
|
|
13429
|
+
case 9:
|
|
13430
|
+
offsets = _context8.sent;
|
|
13431
|
+
singleArray = isVideo || isSingleFrame;
|
|
13432
|
+
if (singleArray && !offsets) {
|
|
13433
|
+
offsets = [0];
|
|
13434
|
+
}
|
|
13435
|
+
if (offsets) {
|
|
13436
|
+
// Last frame ends when the sequence ends, so merge the frame data
|
|
13437
|
+
offsets.push(Number.MAX_SAFE_INTEGER / 2);
|
|
13438
|
+
}
|
|
13439
|
+
startOffset = stream.offset;
|
|
13440
|
+
frameNumber = 0;
|
|
13441
|
+
lastFrame = null;
|
|
13442
|
+
case 16:
|
|
13443
|
+
stream.consume();
|
|
13444
|
+
_context8.next = 20;
|
|
13445
|
+
return stream.ensureAvailable();
|
|
13446
|
+
case 20:
|
|
13447
|
+
frameTag = this.readTagHeader();
|
|
13448
|
+
if (!(frameTag.tag === TagHex.SequenceDelimitationEnd)) {
|
|
13449
|
+
_context8.next = 24;
|
|
13450
|
+
break;
|
|
13451
|
+
}
|
|
13452
|
+
if (lastFrame) {
|
|
13453
|
+
// Always deliver frames as arrays, using streaming splitFrame
|
|
13454
|
+
listener.pop();
|
|
13455
|
+
}
|
|
13456
|
+
return _context8.abrupt("return");
|
|
13457
|
+
case 24:
|
|
13458
|
+
if (!(frameTag.tag !== TagHex.Item)) {
|
|
13459
|
+
_context8.next = 26;
|
|
13460
|
+
break;
|
|
13461
|
+
}
|
|
13462
|
+
throw new Error("frame tag isn't item: ".concat(frameTag.tag));
|
|
13463
|
+
case 26:
|
|
13464
|
+
length = frameTag.length;
|
|
13465
|
+
if (!lastFrame) {
|
|
13466
|
+
lastFrame = [];
|
|
13467
|
+
listener.startObject(lastFrame);
|
|
13468
|
+
}
|
|
13469
|
+
_context8.next = 30;
|
|
13470
|
+
return this._emitSplitValues(length);
|
|
13471
|
+
case 30:
|
|
13472
|
+
if (!offsets || stream.offset >= offsets[frameNumber + 1] + startOffset) {
|
|
13473
|
+
lastFrame = null;
|
|
13474
|
+
listener.pop();
|
|
13475
|
+
frameNumber++;
|
|
13476
|
+
}
|
|
13477
|
+
_context8.next = 16;
|
|
13478
|
+
break;
|
|
13479
|
+
case 33:
|
|
13480
|
+
case "end":
|
|
13481
|
+
return _context8.stop();
|
|
13482
|
+
}
|
|
13483
|
+
}, _callee8, this);
|
|
13484
|
+
}));
|
|
13485
|
+
function readCompressed(_x7) {
|
|
13486
|
+
return _readCompressed.apply(this, arguments);
|
|
13487
|
+
}
|
|
13488
|
+
return readCompressed;
|
|
13489
|
+
}())
|
|
13490
|
+
}, {
|
|
13491
|
+
key: "readOffsets",
|
|
13492
|
+
value: function () {
|
|
13493
|
+
var _readOffsets = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee9() {
|
|
13494
|
+
var tagInfo, offsets, numOfFrames, i;
|
|
13495
|
+
return _regeneratorRuntime().wrap(function _callee9$(_context9) {
|
|
13496
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
13497
|
+
case 0:
|
|
13498
|
+
tagInfo = this.readTagHeader();
|
|
13499
|
+
if (!(tagInfo.tag !== TagHex.Item)) {
|
|
13500
|
+
_context9.next = 3;
|
|
13501
|
+
break;
|
|
13502
|
+
}
|
|
13503
|
+
throw new Error("Offsets tag is missing: ".concat(tagInfo.tag));
|
|
13504
|
+
case 3:
|
|
13505
|
+
if (!(tagInfo.length === 0)) {
|
|
13506
|
+
_context9.next = 5;
|
|
13507
|
+
break;
|
|
13508
|
+
}
|
|
13509
|
+
return _context9.abrupt("return");
|
|
13510
|
+
case 5:
|
|
13511
|
+
offsets = [];
|
|
13512
|
+
numOfFrames = tagInfo.length / 4;
|
|
13513
|
+
_context9.next = 9;
|
|
13514
|
+
return this.stream.ensureAvailable(tagInfo.length);
|
|
13515
|
+
case 9:
|
|
13516
|
+
for (i = 0; i < numOfFrames; i++) {
|
|
13517
|
+
offsets.push(this.stream.readUint32());
|
|
13518
|
+
}
|
|
13519
|
+
return _context9.abrupt("return", offsets);
|
|
13520
|
+
case 11:
|
|
13521
|
+
case "end":
|
|
13522
|
+
return _context9.stop();
|
|
13523
|
+
}
|
|
13524
|
+
}, _callee9, this);
|
|
13525
|
+
}));
|
|
13526
|
+
function readOffsets() {
|
|
13527
|
+
return _readOffsets.apply(this, arguments);
|
|
13528
|
+
}
|
|
13529
|
+
return readOffsets;
|
|
13530
|
+
}()
|
|
13531
|
+
/**
|
|
13532
|
+
* Reads uncompressed pixel data, delivering it to the listener streaming it.
|
|
13533
|
+
*/
|
|
13534
|
+
}, {
|
|
13535
|
+
key: "readUncompressed",
|
|
13536
|
+
value: (function () {
|
|
13537
|
+
var _readUncompressed = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee0(tagInfo) {
|
|
13538
|
+
var _listener$information2;
|
|
13539
|
+
var length, listener, numberOfFrames, frameLength, _listener$information3, _listener$information4, _listener$information5, _listener$information6, rows, cols, samplesPerPixel, bitsAllocated, bitsPerFrame, frameNumber;
|
|
13540
|
+
return _regeneratorRuntime().wrap(function _callee0$(_context0) {
|
|
13541
|
+
while (1) switch (_context0.prev = _context0.next) {
|
|
13542
|
+
case 0:
|
|
13543
|
+
length = tagInfo.length;
|
|
13544
|
+
listener = this.listener;
|
|
13545
|
+
numberOfFrames = parseInt(((_listener$information2 = listener.information) === null || _listener$information2 === void 0 ? void 0 : _listener$information2.numberOfFrames) || 1);
|
|
13546
|
+
frameLength = length;
|
|
13547
|
+
if (!(numberOfFrames > 1)) {
|
|
13548
|
+
_context0.next = 17;
|
|
13549
|
+
break;
|
|
13550
|
+
}
|
|
13551
|
+
rows = (_listener$information3 = listener.information) === null || _listener$information3 === void 0 ? void 0 : _listener$information3.rows;
|
|
13552
|
+
cols = (_listener$information4 = listener.information) === null || _listener$information4 === void 0 ? void 0 : _listener$information4.columns;
|
|
13553
|
+
samplesPerPixel = (_listener$information5 = listener.information) === null || _listener$information5 === void 0 ? void 0 : _listener$information5.samplesPerPixel;
|
|
13554
|
+
bitsAllocated = (_listener$information6 = listener.information) === null || _listener$information6 === void 0 ? void 0 : _listener$information6.bitsAllocated;
|
|
13555
|
+
bitsPerFrame = rows * cols * samplesPerPixel * bitsAllocated;
|
|
13556
|
+
if (!(bitsPerFrame % 8 !== 0)) {
|
|
13557
|
+
_context0.next = 16;
|
|
13558
|
+
break;
|
|
13559
|
+
}
|
|
13560
|
+
if (!(bitsAllocated === 1)) {
|
|
13561
|
+
_context0.next = 15;
|
|
13562
|
+
break;
|
|
13563
|
+
}
|
|
13564
|
+
_context0.next = 14;
|
|
13565
|
+
return this.readUncompressedBitFrame(tagInfo);
|
|
13566
|
+
case 14:
|
|
13567
|
+
return _context0.abrupt("return", _context0.sent);
|
|
13568
|
+
case 15:
|
|
13569
|
+
throw new Error("Odd frame length must be single bit: ".concat(rows, ",").concat(cols, " ").concat(samplesPerPixel, " ").concat(bitsAllocated));
|
|
13570
|
+
case 16:
|
|
13571
|
+
frameLength = bitsPerFrame / 8;
|
|
13572
|
+
case 17:
|
|
13573
|
+
frameNumber = 0;
|
|
13574
|
+
case 18:
|
|
13575
|
+
if (!(frameNumber < numberOfFrames)) {
|
|
13576
|
+
_context0.next = 26;
|
|
13577
|
+
break;
|
|
13578
|
+
}
|
|
13579
|
+
listener.startObject([]);
|
|
13580
|
+
_context0.next = 22;
|
|
13581
|
+
return this._emitSplitValues(frameLength);
|
|
13582
|
+
case 22:
|
|
13583
|
+
listener.pop();
|
|
13584
|
+
// console.log(stream.getBufferMemoryInfo());
|
|
13585
|
+
case 23:
|
|
13586
|
+
frameNumber++;
|
|
13587
|
+
_context0.next = 18;
|
|
13588
|
+
break;
|
|
13589
|
+
case 26:
|
|
13590
|
+
case "end":
|
|
13591
|
+
return _context0.stop();
|
|
13592
|
+
}
|
|
13593
|
+
}, _callee0, this);
|
|
13594
|
+
}));
|
|
13595
|
+
function readUncompressed(_x8) {
|
|
13596
|
+
return _readUncompressed.apply(this, arguments);
|
|
13597
|
+
}
|
|
13598
|
+
return readUncompressed;
|
|
13599
|
+
}()
|
|
13600
|
+
/**
|
|
13601
|
+
* Reads uncompressed pixel data with support for odd frame lengths (in bits).
|
|
13602
|
+
* This method handles cases where frames are packed sequentially bit-by-bit,
|
|
13603
|
+
* without restarting at byte boundaries. Each frame is unpacked starting at byte 0.
|
|
13604
|
+
*
|
|
13605
|
+
* For odd-length bit frames:
|
|
13606
|
+
* - bitsAllocated is always 1 (single bit per pixel)
|
|
13607
|
+
* - rows * cols * samplesPerPixel is not a multiple of 8
|
|
13608
|
+
* - Frames are packed sequentially into bits without byte alignment
|
|
13609
|
+
* - Each frame is unpacked to start at byte 0
|
|
13610
|
+
*
|
|
13611
|
+
* @param {Object} tagInfo - Tag information containing length and other metadata
|
|
13612
|
+
*/
|
|
13613
|
+
)
|
|
12178
13614
|
}, {
|
|
12179
|
-
key: "
|
|
12180
|
-
value: function
|
|
12181
|
-
var
|
|
12182
|
-
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12188
|
-
|
|
12189
|
-
|
|
13615
|
+
key: "readUncompressedBitFrame",
|
|
13616
|
+
value: (function () {
|
|
13617
|
+
var _readUncompressedBitFrame = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee1(tagInfo) {
|
|
13618
|
+
var _listener$information7, _listener$information8, _listener$information9, _listener$information0, _listener$information1;
|
|
13619
|
+
var length, listener, stream, numberOfFrames, rows, cols, samplesPerPixel, bitsAllocated, bitsPerFrame, bytesPerFrame, totalBits, totalBytes, allPixelData, frameNumber, bitOffset, frameBuffer, frameView, sourceView, bitIndex, globalBitIndex, sourceByteIndex, sourceBitIndex, targetByteIndex, targetBitIndex, sourceByte, bitValue;
|
|
13620
|
+
return _regeneratorRuntime().wrap(function _callee1$(_context1) {
|
|
13621
|
+
while (1) switch (_context1.prev = _context1.next) {
|
|
13622
|
+
case 0:
|
|
13623
|
+
length = tagInfo.length;
|
|
13624
|
+
listener = this.listener, stream = this.stream;
|
|
13625
|
+
numberOfFrames = parseInt(((_listener$information7 = listener.information) === null || _listener$information7 === void 0 ? void 0 : _listener$information7.numberOfFrames) || 1);
|
|
13626
|
+
rows = (_listener$information8 = listener.information) === null || _listener$information8 === void 0 ? void 0 : _listener$information8.rows;
|
|
13627
|
+
cols = (_listener$information9 = listener.information) === null || _listener$information9 === void 0 ? void 0 : _listener$information9.columns;
|
|
13628
|
+
samplesPerPixel = ((_listener$information0 = listener.information) === null || _listener$information0 === void 0 ? void 0 : _listener$information0.samplesPerPixel) || 1;
|
|
13629
|
+
bitsAllocated = (_listener$information1 = listener.information) === null || _listener$information1 === void 0 ? void 0 : _listener$information1.bitsAllocated;
|
|
13630
|
+
if (!(!rows || !cols || !bitsAllocated)) {
|
|
13631
|
+
_context1.next = 9;
|
|
13632
|
+
break;
|
|
13633
|
+
}
|
|
13634
|
+
throw new Error("Missing required pixel data information: rows, columns, or bitsAllocated");
|
|
13635
|
+
case 9:
|
|
13636
|
+
if (!(bitsAllocated !== 1)) {
|
|
13637
|
+
_context1.next = 11;
|
|
13638
|
+
break;
|
|
13639
|
+
}
|
|
13640
|
+
throw new Error("Odd-length bit frames require bitsAllocated=1, got ".concat(bitsAllocated));
|
|
13641
|
+
case 11:
|
|
13642
|
+
bitsPerFrame = rows * cols * samplesPerPixel * bitsAllocated;
|
|
13643
|
+
bytesPerFrame = Math.ceil(bitsPerFrame / 8);
|
|
13644
|
+
totalBits = bitsPerFrame * numberOfFrames;
|
|
13645
|
+
totalBytes = Math.ceil(totalBits / 8);
|
|
13646
|
+
if (!(totalBytes !== length)) {
|
|
13647
|
+
_context1.next = 17;
|
|
13648
|
+
break;
|
|
13649
|
+
}
|
|
13650
|
+
throw new Error("The calculated length ".concat(totalBytes, " does not match the actual length ").concat(length));
|
|
13651
|
+
case 17:
|
|
13652
|
+
_context1.next = 19;
|
|
13653
|
+
return stream.ensureAvailable(length);
|
|
13654
|
+
case 19:
|
|
13655
|
+
allPixelData = stream.readArrayBuffer(totalBytes);
|
|
13656
|
+
stream.consume();
|
|
13657
|
+
|
|
13658
|
+
// Extract each frame, unpacking bits so each frame starts at byte 0
|
|
13659
|
+
for (frameNumber = 0; frameNumber < numberOfFrames; frameNumber++) {
|
|
13660
|
+
listener.startObject([]);
|
|
13661
|
+
|
|
13662
|
+
// Calculate the bit offset for this frame in the packed data
|
|
13663
|
+
bitOffset = frameNumber * bitsPerFrame; // Create a buffer for this frame (starting at byte 0)
|
|
13664
|
+
frameBuffer = new ArrayBuffer(bytesPerFrame);
|
|
13665
|
+
frameView = new Uint8Array(frameBuffer);
|
|
13666
|
+
sourceView = new Uint8Array(allPixelData); // Extract bits for this frame
|
|
13667
|
+
for (bitIndex = 0; bitIndex < bitsPerFrame; bitIndex++) {
|
|
13668
|
+
globalBitIndex = bitOffset + bitIndex;
|
|
13669
|
+
sourceByteIndex = Math.floor(globalBitIndex / 8);
|
|
13670
|
+
sourceBitIndex = globalBitIndex % 8;
|
|
13671
|
+
targetByteIndex = Math.floor(bitIndex / 8);
|
|
13672
|
+
targetBitIndex = bitIndex % 8; // Read the bit from source
|
|
13673
|
+
sourceByte = sourceView[sourceByteIndex];
|
|
13674
|
+
bitValue = sourceByte >> 7 - sourceBitIndex & 1; // Write the bit to target (starting at byte 0)
|
|
13675
|
+
if (bitValue) {
|
|
13676
|
+
frameView[targetByteIndex] |= 1 << 7 - targetBitIndex;
|
|
13677
|
+
}
|
|
13678
|
+
}
|
|
13679
|
+
|
|
13680
|
+
// Deliver the frame buffer
|
|
13681
|
+
listener.value(frameBuffer);
|
|
13682
|
+
listener.pop();
|
|
13683
|
+
}
|
|
13684
|
+
case 22:
|
|
13685
|
+
case "end":
|
|
13686
|
+
return _context1.stop();
|
|
13687
|
+
}
|
|
13688
|
+
}, _callee1, this);
|
|
13689
|
+
}));
|
|
13690
|
+
function readUncompressedBitFrame(_x9) {
|
|
13691
|
+
return _readUncompressedBitFrame.apply(this, arguments);
|
|
13692
|
+
}
|
|
13693
|
+
return readUncompressedBitFrame;
|
|
13694
|
+
}()
|
|
13695
|
+
/**
|
|
13696
|
+
* Reads raw binary data in chunks and delivers it to the listener.
|
|
13697
|
+
* This method reads data in 64KB chunks to manage memory efficiently.
|
|
13698
|
+
*/
|
|
13699
|
+
)
|
|
12190
13700
|
}, {
|
|
12191
|
-
key: "
|
|
12192
|
-
value: function
|
|
12193
|
-
|
|
12194
|
-
|
|
13701
|
+
key: "readRawBinary",
|
|
13702
|
+
value: (function () {
|
|
13703
|
+
var _readRawBinary = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee10(tagInfo) {
|
|
13704
|
+
var length;
|
|
13705
|
+
return _regeneratorRuntime().wrap(function _callee10$(_context10) {
|
|
13706
|
+
while (1) switch (_context10.prev = _context10.next) {
|
|
13707
|
+
case 0:
|
|
13708
|
+
length = tagInfo.length;
|
|
13709
|
+
this._emitSplitValues(length);
|
|
13710
|
+
case 2:
|
|
13711
|
+
case "end":
|
|
13712
|
+
return _context10.stop();
|
|
13713
|
+
}
|
|
13714
|
+
}, _callee10, this);
|
|
13715
|
+
}));
|
|
13716
|
+
function readRawBinary(_x0) {
|
|
13717
|
+
return _readRawBinary.apply(this, arguments);
|
|
13718
|
+
}
|
|
13719
|
+
return readRawBinary;
|
|
13720
|
+
}())
|
|
12195
13721
|
}, {
|
|
12196
|
-
key: "
|
|
12197
|
-
value: function
|
|
12198
|
-
var
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
var whitePoint = Colors.d65WhitePointXYZ();
|
|
12202
|
-
return [whitePoint[0] * Colors.labfInv(a), whitePoint[1] * Colors.labfInv(L), whitePoint[2] * Colors.labfInv(b)];
|
|
13722
|
+
key: "isSequence",
|
|
13723
|
+
value: function isSequence(tagInfo) {
|
|
13724
|
+
var vr = tagInfo.vr,
|
|
13725
|
+
length = tagInfo.length;
|
|
13726
|
+
return vr === "SQ" || vr === "UN" && length === UNDEFINED_LENGTH_FIX;
|
|
12203
13727
|
}
|
|
12204
|
-
}, {
|
|
12205
|
-
key: "xyz2RGB",
|
|
12206
|
-
value: function xyz2RGB(xyz) {
|
|
12207
|
-
var R1 = 3.2406 * xyz[0] - 1.5372 * xyz[1] - 0.4986 * xyz[2];
|
|
12208
|
-
var G1 = -0.9689 * xyz[0] + 1.8758 * xyz[1] + 0.0415 * xyz[2];
|
|
12209
|
-
var B1 = 0.0557 * xyz[0] - 0.204 * xyz[1] + 1.057 * xyz[2];
|
|
12210
|
-
|
|
12211
|
-
/* Force nonnegative values so that gamma correction is well-defined. */
|
|
12212
|
-
var minimumComponent = Math.min(R1, G1);
|
|
12213
|
-
minimumComponent = Math.min(minimumComponent, B1);
|
|
12214
|
-
if (minimumComponent < 0) {
|
|
12215
|
-
R1 -= minimumComponent;
|
|
12216
|
-
G1 -= minimumComponent;
|
|
12217
|
-
B1 -= minimumComponent;
|
|
12218
|
-
}
|
|
12219
13728
|
|
|
12220
|
-
|
|
12221
|
-
|
|
12222
|
-
|
|
13729
|
+
/**
|
|
13730
|
+
* Reads a tag header.
|
|
13731
|
+
*/
|
|
12223
13732
|
}, {
|
|
12224
|
-
key: "
|
|
12225
|
-
value: function
|
|
12226
|
-
|
|
12227
|
-
|
|
13733
|
+
key: "readTagHeader",
|
|
13734
|
+
value: function readTagHeader() {
|
|
13735
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
|
|
13736
|
+
untilTag: null,
|
|
13737
|
+
includeUntilTagValue: false
|
|
13738
|
+
};
|
|
13739
|
+
var stream = this.stream,
|
|
13740
|
+
syntax = this.syntax;
|
|
13741
|
+
var untilTag = options.untilTag,
|
|
13742
|
+
includeUntilTagValue = options.includeUntilTagValue;
|
|
13743
|
+
var implicit = syntax == IMPLICIT_LITTLE_ENDIAN;
|
|
13744
|
+
var isLittleEndian = syntax !== EXPLICIT_BIG_ENDIAN;
|
|
13745
|
+
stream.setEndian(isLittleEndian);
|
|
13746
|
+
var tagObj = Tag.readTag(stream);
|
|
13747
|
+
var tag = tagObj.cleanString;
|
|
13748
|
+
if (untilTag && untilTag === tag) {
|
|
13749
|
+
if (!includeUntilTagValue) {
|
|
13750
|
+
return {
|
|
13751
|
+
tag: tag,
|
|
13752
|
+
tagObj: tagObj,
|
|
13753
|
+
vr: 0,
|
|
13754
|
+
values: 0,
|
|
13755
|
+
untilTag: true
|
|
13756
|
+
};
|
|
13757
|
+
}
|
|
13758
|
+
}
|
|
13759
|
+
var length = null;
|
|
13760
|
+
var vr = null;
|
|
13761
|
+
var vrType;
|
|
13762
|
+
var isCommand = tagObj.group() === 0;
|
|
13763
|
+
if (tagObj.isInstruction()) {
|
|
13764
|
+
length = stream.readUint32();
|
|
13765
|
+
vr = ValueRepresentation.createByTypeString("UN");
|
|
13766
|
+
} else if (implicit && !isCommand) {
|
|
13767
|
+
length = stream.readUint32();
|
|
13768
|
+
var elementData = DicomMessage.lookupTag(tagObj);
|
|
13769
|
+
if (elementData) {
|
|
13770
|
+
vrType = elementData.vr;
|
|
13771
|
+
} else {
|
|
13772
|
+
//unknown tag
|
|
13773
|
+
if (length == UNDEFINED_LENGTH) {
|
|
13774
|
+
vrType = "SQ";
|
|
13775
|
+
} else if (tagObj.isPixelDataTag()) {
|
|
13776
|
+
vrType = "OW";
|
|
13777
|
+
} else if (vrType == "xs") {
|
|
13778
|
+
var _this$listener$inform;
|
|
13779
|
+
// This should work for any tag after PixelRepresentation,
|
|
13780
|
+
// which is all but 2 of the xs code values.
|
|
13781
|
+
var signed = ((_this$listener$inform = this.listener.information) === null || _this$listener$inform === void 0 ? void 0 : _this$listener$inform.pixelRepresentation) === 0;
|
|
13782
|
+
vrType = signed ? "SS" : "US";
|
|
13783
|
+
} else if (tagObj.isPrivateCreator()) {
|
|
13784
|
+
vrType = "LO";
|
|
13785
|
+
} else {
|
|
13786
|
+
vrType = "UN";
|
|
13787
|
+
}
|
|
13788
|
+
}
|
|
13789
|
+
vr = ValueRepresentation.createByTypeString(vrType);
|
|
12228
13790
|
} else {
|
|
12229
|
-
|
|
13791
|
+
var _DicomMessage$lookupT;
|
|
13792
|
+
vrType = stream.readVR();
|
|
13793
|
+
if (vrType === "UN" && (_DicomMessage$lookupT = DicomMessage.lookupTag(tagObj)) !== null && _DicomMessage$lookupT !== void 0 && _DicomMessage$lookupT.vr) {
|
|
13794
|
+
vrType = DicomMessage.lookupTag(tagObj).vr;
|
|
13795
|
+
vr = ValueRepresentation.parseUnknownVr(vrType);
|
|
13796
|
+
} else {
|
|
13797
|
+
vr = ValueRepresentation.createByTypeString(vrType);
|
|
13798
|
+
}
|
|
13799
|
+
if (vr.isLength32()) {
|
|
13800
|
+
stream.increment(2);
|
|
13801
|
+
length = stream.readUint32();
|
|
13802
|
+
} else {
|
|
13803
|
+
length = stream.readUint16();
|
|
13804
|
+
}
|
|
12230
13805
|
}
|
|
13806
|
+
var punctuatedTag = DicomMetaDictionary.punctuateTag(tag);
|
|
13807
|
+
var entry = DicomMetaDictionary.dictionary[punctuatedTag];
|
|
13808
|
+
|
|
13809
|
+
// Include both the string and object values for vr and tag
|
|
13810
|
+
var header = {
|
|
13811
|
+
vrObj: vr,
|
|
13812
|
+
vr: vr.type,
|
|
13813
|
+
tag: tag,
|
|
13814
|
+
tagObj: tagObj,
|
|
13815
|
+
vm: entry === null || entry === void 0 ? void 0 : entry.vm,
|
|
13816
|
+
name: entry === null || entry === void 0 ? void 0 : entry.name,
|
|
13817
|
+
length: length === UNDEFINED_LENGTH ? -1 : length
|
|
13818
|
+
};
|
|
13819
|
+
return header;
|
|
12231
13820
|
}
|
|
13821
|
+
|
|
13822
|
+
/**
|
|
13823
|
+
* Reads a single tag values and delivers them to the listener.
|
|
13824
|
+
*
|
|
13825
|
+
* If the tag is specific character set, will assign the decoder to that
|
|
13826
|
+
* character set.
|
|
13827
|
+
*/
|
|
12232
13828
|
}, {
|
|
12233
|
-
key: "
|
|
12234
|
-
value: function
|
|
12235
|
-
|
|
12236
|
-
|
|
12237
|
-
|
|
12238
|
-
|
|
13829
|
+
key: "readSingle",
|
|
13830
|
+
value: (function () {
|
|
13831
|
+
var _readSingle = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee11(tagInfo, listener, options) {
|
|
13832
|
+
var length, stream, syntax, vr, values, times, i, _vr$read, value, _vr$read2, _value, delimiterChar, _values, _values2, coding;
|
|
13833
|
+
return _regeneratorRuntime().wrap(function _callee11$(_context11) {
|
|
13834
|
+
while (1) switch (_context11.prev = _context11.next) {
|
|
13835
|
+
case 0:
|
|
13836
|
+
length = tagInfo.length;
|
|
13837
|
+
stream = this.stream, syntax = this.syntax;
|
|
13838
|
+
_context11.next = 4;
|
|
13839
|
+
return this.stream.ensureAvailable(length);
|
|
13840
|
+
case 4:
|
|
13841
|
+
vr = ValueRepresentation.createByTypeString(tagInfo.vr);
|
|
13842
|
+
values = [];
|
|
13843
|
+
if (vr.isBinary() && length > vr.maxLength && !vr.noMultiple) {
|
|
13844
|
+
times = length / vr.maxLength;
|
|
13845
|
+
i = 0;
|
|
13846
|
+
while (i++ < times) {
|
|
13847
|
+
_vr$read = vr.read(stream, vr.maxLength, syntax), value = _vr$read.value;
|
|
13848
|
+
values.push(value);
|
|
13849
|
+
}
|
|
13850
|
+
} else {
|
|
13851
|
+
_value = (_vr$read2 = vr.read(stream, length, syntax)) === null || _vr$read2 === void 0 ? void 0 : _vr$read2.value;
|
|
13852
|
+
if (!vr.isBinary() && singleVRs.indexOf(vr.type) == -1) {
|
|
13853
|
+
values = _value;
|
|
13854
|
+
if (typeof _value === "string") {
|
|
13855
|
+
delimiterChar = String.fromCharCode(VM_DELIMITER);
|
|
13856
|
+
values = vr.dropPadByte(_value.split(delimiterChar));
|
|
13857
|
+
}
|
|
13858
|
+
} else if (vr.type == "OW" || vr.type == "OB") {
|
|
13859
|
+
values = _value;
|
|
13860
|
+
} else {
|
|
13861
|
+
Array.isArray(_value) ? values = _value : values.push(_value);
|
|
13862
|
+
}
|
|
13863
|
+
}
|
|
13864
|
+
if (!(tagInfo.tag === TagHex.SpecificCharacterSet)) {
|
|
13865
|
+
_context11.next = 21;
|
|
13866
|
+
break;
|
|
13867
|
+
}
|
|
13868
|
+
if (!(values.length > 0)) {
|
|
13869
|
+
_context11.next = 21;
|
|
13870
|
+
break;
|
|
13871
|
+
}
|
|
13872
|
+
_values = values, _values2 = _slicedToArray(_values, 1), coding = _values2[0];
|
|
13873
|
+
coding = coding.replace(/[_ ]/g, "-").toLowerCase();
|
|
13874
|
+
if (!(coding in encodingMapping)) {
|
|
13875
|
+
_context11.next = 16;
|
|
13876
|
+
break;
|
|
13877
|
+
}
|
|
13878
|
+
coding = encodingMapping[coding];
|
|
13879
|
+
this.stream.setDecoder(new TextDecoder(coding));
|
|
13880
|
+
_context11.next = 21;
|
|
13881
|
+
break;
|
|
13882
|
+
case 16:
|
|
13883
|
+
if (!(options !== null && options !== void 0 && options.ignoreErrors)) {
|
|
13884
|
+
_context11.next = 20;
|
|
13885
|
+
break;
|
|
13886
|
+
}
|
|
13887
|
+
log.warn("Unsupported character set: ".concat(coding, ", using default character set"));
|
|
13888
|
+
_context11.next = 21;
|
|
13889
|
+
break;
|
|
13890
|
+
case 20:
|
|
13891
|
+
throw Error("Unsupported character set: ".concat(coding));
|
|
13892
|
+
case 21:
|
|
13893
|
+
values.forEach(function (value) {
|
|
13894
|
+
return listener.value(value);
|
|
13895
|
+
});
|
|
13896
|
+
return _context11.abrupt("return", values);
|
|
13897
|
+
case 23:
|
|
13898
|
+
case "end":
|
|
13899
|
+
return _context11.stop();
|
|
13900
|
+
}
|
|
13901
|
+
}, _callee11, this);
|
|
13902
|
+
}));
|
|
13903
|
+
function readSingle(_x1, _x10, _x11) {
|
|
13904
|
+
return _readSingle.apply(this, arguments);
|
|
12239
13905
|
}
|
|
12240
|
-
|
|
13906
|
+
return readSingle;
|
|
13907
|
+
}())
|
|
12241
13908
|
}]);
|
|
12242
|
-
return
|
|
13909
|
+
return AsyncDicomReader;
|
|
12243
13910
|
}();
|
|
12244
13911
|
|
|
12245
13912
|
function datasetToDict(dataset) {
|
|
@@ -22629,106 +24296,86 @@ var message = {
|
|
|
22629
24296
|
};
|
|
22630
24297
|
|
|
22631
24298
|
/**
|
|
22632
|
-
* A
|
|
22633
|
-
*
|
|
24299
|
+
* A filter for DicomMetadataListener that converts ArrayBuffer[] child values
|
|
24300
|
+
* into expanded listener.startObject([]) and value(fragment) calls.
|
|
22634
24301
|
*
|
|
22635
|
-
*
|
|
22636
|
-
*
|
|
24302
|
+
* This is useful when you have compressed or fragmented pixel data delivered
|
|
24303
|
+
* as an array of ArrayBuffers and want to process each fragment individually
|
|
24304
|
+
* through the standard listener sequence pattern.
|
|
22637
24305
|
*
|
|
22638
|
-
*
|
|
22639
|
-
*
|
|
24306
|
+
* @example
|
|
24307
|
+
* // Use as a filter in DicomMetadataListener constructor
|
|
24308
|
+
* const listener = new DicomMetadataListener(ArrayBufferExpanderFilter);
|
|
24309
|
+
* await reader.readFile({ listener });
|
|
24310
|
+
*
|
|
24311
|
+
* @example
|
|
24312
|
+
* // Combine with other filters
|
|
24313
|
+
* const listener = new DicomMetadataListener(
|
|
24314
|
+
* ArrayBufferExpanderFilter,
|
|
24315
|
+
* myCustomFilter
|
|
24316
|
+
* );
|
|
22640
24317
|
*/
|
|
22641
|
-
var
|
|
22642
|
-
|
|
22643
|
-
|
|
22644
|
-
|
|
22645
|
-
|
|
22646
|
-
|
|
22647
|
-
|
|
22648
|
-
|
|
22649
|
-
|
|
22650
|
-
|
|
22651
|
-
|
|
22652
|
-
|
|
22653
|
-
|
|
22654
|
-
|
|
22655
|
-
|
|
22656
|
-
|
|
22657
|
-
|
|
22658
|
-
|
|
22659
|
-
|
|
22660
|
-
|
|
22661
|
-
|
|
22662
|
-
|
|
22663
|
-
|
|
22664
|
-
|
|
22665
|
-
|
|
22666
|
-
|
|
22667
|
-
|
|
22668
|
-
|
|
22669
|
-
|
|
22670
|
-
|
|
22671
|
-
|
|
22672
|
-
|
|
22673
|
-
|
|
22674
|
-
|
|
22675
|
-
|
|
22676
|
-
|
|
22677
|
-
|
|
22678
|
-
|
|
22679
|
-
|
|
22680
|
-
|
|
22681
|
-
|
|
22682
|
-
|
|
22683
|
-
|
|
22684
|
-
* Starts a new array, using the provided value
|
|
22685
|
-
*/
|
|
22686
|
-
}, {
|
|
22687
|
-
key: "startArray",
|
|
22688
|
-
value: function startArray() {
|
|
22689
|
-
var dest = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
22690
|
-
this.current = {
|
|
22691
|
-
parent: this.current,
|
|
22692
|
-
dest: dest,
|
|
22693
|
-
type: "array"
|
|
22694
|
-
};
|
|
22695
|
-
}
|
|
22696
|
-
|
|
22697
|
-
/**
|
|
22698
|
-
* Pops the current value being created off the stack.
|
|
22699
|
-
*/
|
|
22700
|
-
}, {
|
|
22701
|
-
key: "pop",
|
|
22702
|
-
value: function pop() {
|
|
22703
|
-
var _this$current$pop, _this$current$pop2, _this$current;
|
|
22704
|
-
var result = (_this$current$pop = (_this$current$pop2 = (_this$current = this.current).pop) === null || _this$current$pop2 === void 0 ? void 0 : _this$current$pop2.call(_this$current)) !== null && _this$current$pop !== void 0 ? _this$current$pop : this.current.dest;
|
|
22705
|
-
this.current = this.current.parent;
|
|
22706
|
-
return result;
|
|
22707
|
-
}
|
|
24318
|
+
var ArrayBufferExpanderFilter = {
|
|
24319
|
+
/**
|
|
24320
|
+
* Filter method that intercepts value calls to expand ArrayBuffer[] into
|
|
24321
|
+
* individual fragments.
|
|
24322
|
+
*
|
|
24323
|
+
* When the value is an array where every element is an ArrayBuffer:
|
|
24324
|
+
* 1. Saves the current tag context
|
|
24325
|
+
* 2. Calls this.startObject([]) to create a new array context
|
|
24326
|
+
* 3. Calls this.value(fragment) for each ArrayBuffer in the array
|
|
24327
|
+
* 4. Calls this.pop() to get the resulting array
|
|
24328
|
+
* 5. Assigns that array to the tag's Value field
|
|
24329
|
+
*
|
|
24330
|
+
* This is necessary because when AsyncDicomReader delivers ArrayBuffer[]
|
|
24331
|
+
* directly to value(), it does not call startObject/pop around them, so we
|
|
24332
|
+
* must make those calls to properly represent the array structure.
|
|
24333
|
+
*
|
|
24334
|
+
* Otherwise, it passes the value through unchanged to the next filter.
|
|
24335
|
+
*
|
|
24336
|
+
* @param {Function} next - The next function in the filter chain
|
|
24337
|
+
* @param {*} v - The value to process
|
|
24338
|
+
*/
|
|
24339
|
+
value: function value(next, v) {
|
|
24340
|
+
// Check if the value is an array of ArrayBuffers
|
|
24341
|
+
if (Array.isArray(v) && v.length > 0 && v.every(function (item) {
|
|
24342
|
+
return item instanceof ArrayBuffer || ArrayBuffer.isView(item);
|
|
24343
|
+
})) {
|
|
24344
|
+
// Expand the ArrayBuffer[] into the proper sequence
|
|
24345
|
+
// The reader hasn't called startObject for this, so we must
|
|
24346
|
+
|
|
24347
|
+
// Save the current tag context
|
|
24348
|
+
var tagContext = this.current;
|
|
24349
|
+
|
|
24350
|
+
// Call startObject with an array to create a new array context
|
|
24351
|
+
this.startObject([]);
|
|
24352
|
+
|
|
24353
|
+
// Add each fragment
|
|
24354
|
+
var _iterator = _createForOfIteratorHelper(v),
|
|
24355
|
+
_step;
|
|
24356
|
+
try {
|
|
24357
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
24358
|
+
var fragment = _step.value;
|
|
24359
|
+
this.value(fragment);
|
|
24360
|
+
}
|
|
22708
24361
|
|
|
22709
|
-
|
|
22710
|
-
|
|
22711
|
-
|
|
22712
|
-
|
|
22713
|
-
|
|
22714
|
-
|
|
22715
|
-
var
|
|
22716
|
-
(_this$current$dest = this.current.dest).Value || (_this$current$dest.Value = []);
|
|
22717
|
-
this.current.dest.Value.push(v);
|
|
22718
|
-
}
|
|
24362
|
+
// Pop to get the resulting array structure
|
|
24363
|
+
} catch (err) {
|
|
24364
|
+
_iterator.e(err);
|
|
24365
|
+
} finally {
|
|
24366
|
+
_iterator.f();
|
|
24367
|
+
}
|
|
24368
|
+
var arrayResult = this.pop();
|
|
22719
24369
|
|
|
22720
|
-
|
|
22721
|
-
|
|
22722
|
-
|
|
22723
|
-
|
|
22724
|
-
|
|
22725
|
-
|
|
22726
|
-
var _this$current$parent$;
|
|
22727
|
-
return (_this$current$parent$ = this.current.parent[tag]) === null || _this$current$parent$ === void 0 || (_this$current$parent$ = _this$current$parent$.Value) === null || _this$current$parent$ === void 0 ? void 0 : _this$current$parent$[0];
|
|
24370
|
+
// Now we're back in the tag context - assign the array to Value
|
|
24371
|
+
// The arrayResult will have a Value property with the fragments
|
|
24372
|
+
tagContext.dest.Value = arrayResult.Value || arrayResult;
|
|
24373
|
+
} else {
|
|
24374
|
+
// Pass through non-ArrayBuffer[] values unchanged
|
|
24375
|
+
next(v);
|
|
22728
24376
|
}
|
|
22729
|
-
}
|
|
22730
|
-
|
|
22731
|
-
}();
|
|
24377
|
+
}
|
|
24378
|
+
};
|
|
22732
24379
|
|
|
22733
24380
|
var utilities = {
|
|
22734
24381
|
TID1500: TID1500,
|
|
@@ -22738,7 +24385,11 @@ var utilities = {
|
|
|
22738
24385
|
orientation: orientation,
|
|
22739
24386
|
compression: compression,
|
|
22740
24387
|
dicomJson: dicomJson,
|
|
22741
|
-
DicomMetadataListener: DicomMetadataListener
|
|
24388
|
+
DicomMetadataListener: DicomMetadataListener,
|
|
24389
|
+
ArrayBufferExpanderFilter: ArrayBufferExpanderFilter,
|
|
24390
|
+
toFloat: toFloat,
|
|
24391
|
+
toInt: toInt,
|
|
24392
|
+
createInformationFilter: createInformationFilter
|
|
22742
24393
|
};
|
|
22743
24394
|
|
|
22744
24395
|
var _value = Symbol("value");
|
|
@@ -25382,6 +27033,9 @@ var data = {
|
|
|
25382
27033
|
datasetToBuffer: datasetToBuffer,
|
|
25383
27034
|
datasetToBlob: datasetToBlob
|
|
25384
27035
|
};
|
|
27036
|
+
var async = {
|
|
27037
|
+
AsyncDicomReader: AsyncDicomReader
|
|
27038
|
+
};
|
|
25385
27039
|
var derivations = {
|
|
25386
27040
|
DerivedDataset: DerivedDataset,
|
|
25387
27041
|
DerivedPixels: DerivedPixels,
|
|
@@ -25408,18 +27062,20 @@ var anonymizer = {
|
|
|
25408
27062
|
var dcmjs = {
|
|
25409
27063
|
DICOMWEB: DICOMWEB,
|
|
25410
27064
|
adapters: adapters,
|
|
27065
|
+
constants: constants,
|
|
25411
27066
|
data: data,
|
|
25412
27067
|
derivations: derivations,
|
|
25413
27068
|
normalizers: normalizers,
|
|
25414
27069
|
sr: sr,
|
|
25415
27070
|
utilities: utilities,
|
|
25416
27071
|
log: log,
|
|
25417
|
-
anonymizer: anonymizer
|
|
27072
|
+
anonymizer: anonymizer,
|
|
27073
|
+
async: async
|
|
25418
27074
|
};
|
|
25419
27075
|
DicomDict.setDicomMessageClass(DicomMessage);
|
|
25420
27076
|
ValueRepresentation.setDicomMessageClass(DicomMessage);
|
|
25421
27077
|
ValueRepresentation.setTagClass(Tag);
|
|
25422
27078
|
Tag.setDicomMessageClass(DicomMessage);
|
|
25423
27079
|
|
|
25424
|
-
export { DICOMWEB, adapters, anonymizer, data, dcmjs as default, derivations, log, normalizers, sr, utilities };
|
|
27080
|
+
export { DICOMWEB, adapters, anonymizer, async, constants, data, dcmjs as default, derivations, log, normalizers, sr, utilities };
|
|
25425
27081
|
//# sourceMappingURL=dcmjs.es.js.map
|