dcmjs 0.23.1 → 0.24.2
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 +167 -80
- package/build/dcmjs.es.js.map +1 -1
- package/build/dcmjs.js +167 -80
- package/build/dcmjs.js.map +1 -1
- package/package.json +1 -1
- package/test/data-options.test.js +237 -0
- package/test/data.test.js +96 -50
- package/test/untilTag.test.js +0 -44
package/build/dcmjs.es.js
CHANGED
|
@@ -1069,8 +1069,19 @@ var BufferStream = /*#__PURE__*/function () {
|
|
|
1069
1069
|
value: function checkSize(step) {
|
|
1070
1070
|
if (this.offset + step > this.buffer.byteLength) {
|
|
1071
1071
|
//throw new Error("Writing exceeded the size of buffer");
|
|
1072
|
-
//
|
|
1073
|
-
|
|
1072
|
+
//
|
|
1073
|
+
// Resize the buffer.
|
|
1074
|
+
// The idea is that when it is necessary to increase the buffer size,
|
|
1075
|
+
// there will likely be more bytes which need to be written to the
|
|
1076
|
+
// buffer in the future. Buffer allocation is costly.
|
|
1077
|
+
// So we increase the buffer size right now
|
|
1078
|
+
// by a larger amount than necessary, to reserve space for later
|
|
1079
|
+
// writes which then can be done much faster. The current size of
|
|
1080
|
+
// the buffer is the best estimate of the scale by which the size
|
|
1081
|
+
// should increase.
|
|
1082
|
+
// So approximately doubling the size of the buffer
|
|
1083
|
+
// (while ensuring it fits the new data) is a simple but effective strategy.
|
|
1084
|
+
var dstSize = this.offset + step + this.buffer.byteLength;
|
|
1074
1085
|
var dst = new ArrayBuffer(dstSize);
|
|
1075
1086
|
new Uint8Array(dst).set(new Uint8Array(this.buffer));
|
|
1076
1087
|
this.buffer = dst;
|
|
@@ -1127,7 +1138,10 @@ var BufferStream = /*#__PURE__*/function () {
|
|
|
1127
1138
|
throw new Error("Request more than currently allocated buffer");
|
|
1128
1139
|
}
|
|
1129
1140
|
|
|
1130
|
-
var newBuf = new ReadBufferStream(this.buffer, null,
|
|
1141
|
+
var newBuf = new ReadBufferStream(this.buffer, null, {
|
|
1142
|
+
start: this.offset,
|
|
1143
|
+
stop: this.offset + length
|
|
1144
|
+
});
|
|
1131
1145
|
this.increment(length);
|
|
1132
1146
|
return newBuf;
|
|
1133
1147
|
}
|
|
@@ -1157,20 +1171,41 @@ var ReadBufferStream = /*#__PURE__*/function (_BufferStream) {
|
|
|
1157
1171
|
|
|
1158
1172
|
var _super = _createSuper(ReadBufferStream);
|
|
1159
1173
|
|
|
1160
|
-
function ReadBufferStream(buffer, littleEndian
|
|
1174
|
+
function ReadBufferStream(buffer, littleEndian) {
|
|
1161
1175
|
var _this;
|
|
1162
1176
|
|
|
1177
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
1178
|
+
start: null,
|
|
1179
|
+
stop: null,
|
|
1180
|
+
noCopy: false
|
|
1181
|
+
};
|
|
1182
|
+
|
|
1163
1183
|
_classCallCheck(this, ReadBufferStream);
|
|
1164
1184
|
|
|
1165
1185
|
_this = _super.call(this, buffer, littleEndian);
|
|
1166
|
-
_this.offset = start || 0;
|
|
1167
|
-
_this.size =
|
|
1186
|
+
_this.offset = options.start || 0;
|
|
1187
|
+
_this.size = options.stop || _this.buffer.byteLength;
|
|
1188
|
+
_this.noCopy = options.noCopy;
|
|
1168
1189
|
_this.startOffset = _this.offset;
|
|
1169
1190
|
_this.endOffset = _this.size;
|
|
1170
1191
|
return _this;
|
|
1171
1192
|
}
|
|
1172
1193
|
|
|
1173
1194
|
_createClass(ReadBufferStream, [{
|
|
1195
|
+
key: "getBuffer",
|
|
1196
|
+
value: function getBuffer(start, end) {
|
|
1197
|
+
if (this.noCopy) {
|
|
1198
|
+
return new Uint8Array(this.buffer, start, end - start);
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
if (!start && !end) {
|
|
1202
|
+
start = 0;
|
|
1203
|
+
end = this.size;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
return this.buffer.slice(start, end);
|
|
1207
|
+
}
|
|
1208
|
+
}, {
|
|
1174
1209
|
key: "readString",
|
|
1175
1210
|
value: function readString(length) {
|
|
1176
1211
|
var chars = [];
|
|
@@ -1292,25 +1327,10 @@ var WriteBufferStream = /*#__PURE__*/function (_BufferStream2) {
|
|
|
1292
1327
|
return _createClass(WriteBufferStream);
|
|
1293
1328
|
}(BufferStream);
|
|
1294
1329
|
|
|
1295
|
-
function paddingLeft(paddingValue, string) {
|
|
1296
|
-
return String(paddingValue + string).slice(-paddingValue.length);
|
|
1297
|
-
}
|
|
1298
|
-
|
|
1299
1330
|
function rtrim(str) {
|
|
1300
1331
|
return str.replace(/\s*$/g, "");
|
|
1301
1332
|
}
|
|
1302
1333
|
|
|
1303
|
-
function tagFromNumbers(group, element) {
|
|
1304
|
-
return new Tag((group << 16 | element) >>> 0);
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
function readTag(stream) {
|
|
1308
|
-
var group = stream.readUint16(),
|
|
1309
|
-
element = stream.readUint16();
|
|
1310
|
-
var tag = tagFromNumbers(group, element);
|
|
1311
|
-
return tag;
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
1334
|
function toWindows(inputArray, size) {
|
|
1315
1335
|
return Array.from({
|
|
1316
1336
|
length: inputArray.length - (size - 1)
|
|
@@ -1655,17 +1675,28 @@ var BinaryRepresentation = /*#__PURE__*/function (_ValueRepresentation2) {
|
|
|
1655
1675
|
offsets = [];
|
|
1656
1676
|
}
|
|
1657
1677
|
|
|
1658
|
-
var
|
|
1678
|
+
var SequenceItemTag = 0xfffee000;
|
|
1679
|
+
var SequenceDelimiterTag = 0xfffee0dd;
|
|
1680
|
+
|
|
1681
|
+
var getNextSequenceItemData = function getNextSequenceItemData(stream) {
|
|
1659
1682
|
var nextTag = Tag.readTag(stream);
|
|
1660
1683
|
|
|
1661
|
-
if (
|
|
1662
|
-
|
|
1684
|
+
if (nextTag.is(SequenceItemTag)) {
|
|
1685
|
+
var _itemLength = stream.readUint32();
|
|
1686
|
+
|
|
1687
|
+
var buffer = stream.getBuffer(stream.offset, stream.offset + _itemLength);
|
|
1688
|
+
stream.increment(_itemLength);
|
|
1689
|
+
return buffer;
|
|
1690
|
+
} else if (nextTag.is(SequenceDelimiterTag)) {
|
|
1691
|
+
// Read SequenceDelimiterItem value for the SequenceDelimiterTag
|
|
1692
|
+
if (stream.readUint32() !== 0) {
|
|
1693
|
+
throw Error("SequenceDelimiterItem tag value was not zero");
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
return null;
|
|
1663
1697
|
}
|
|
1664
1698
|
|
|
1665
|
-
|
|
1666
|
-
var buffer = stream.getBuffer(stream.offset, stream.offset + frameOrFragmentItemLength);
|
|
1667
|
-
stream.increment(frameOrFragmentItemLength);
|
|
1668
|
-
return [buffer, false];
|
|
1699
|
+
throw Error("Invalid tag in sequence");
|
|
1669
1700
|
}; // If there is an offset table, use that to loop through pixel data sequence
|
|
1670
1701
|
|
|
1671
1702
|
|
|
@@ -1684,33 +1715,40 @@ var BinaryRepresentation = /*#__PURE__*/function (_ValueRepresentation2) {
|
|
|
1684
1715
|
stop = _range[1]; // create a new readable stream based on the range
|
|
1685
1716
|
|
|
1686
1717
|
|
|
1687
|
-
var
|
|
1718
|
+
var rangeStream = new ReadBufferStream(stream.buffer, stream.isLittleEndian, {
|
|
1719
|
+
start: start,
|
|
1720
|
+
stop: stop,
|
|
1721
|
+
noCopy: stream.noCopy
|
|
1722
|
+
});
|
|
1723
|
+
var frameSize = 0;
|
|
1688
1724
|
|
|
1689
|
-
while (!
|
|
1690
|
-
var
|
|
1691
|
-
_getFrameOrFragement2 = _slicedToArray(_getFrameOrFragement, 2),
|
|
1692
|
-
buf = _getFrameOrFragement2[0],
|
|
1693
|
-
done = _getFrameOrFragement2[1];
|
|
1725
|
+
while (!rangeStream.end()) {
|
|
1726
|
+
var buf = getNextSequenceItemData(rangeStream);
|
|
1694
1727
|
|
|
1695
|
-
if (
|
|
1728
|
+
if (buf === null) {
|
|
1696
1729
|
break;
|
|
1697
1730
|
}
|
|
1698
1731
|
|
|
1699
1732
|
fragments.push(buf);
|
|
1700
|
-
|
|
1733
|
+
frameSize += buf.byteLength;
|
|
1734
|
+
} // Ensure the parent stream's offset is kept up to date
|
|
1701
1735
|
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
if (fragments.length
|
|
1736
|
+
|
|
1737
|
+
stream.offset = rangeStream.offset; // If there's only one buffer thne just return it directly
|
|
1738
|
+
|
|
1739
|
+
if (fragments.length === 1) {
|
|
1706
1740
|
return fragments[0];
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
if (rangeStream.noCopy) {
|
|
1744
|
+
// return the fragments for downstream application to process
|
|
1745
|
+
return fragments;
|
|
1707
1746
|
} else {
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
var mergedFrame = new Uint8Array(frameSize);
|
|
1747
|
+
// Allocate a final ArrayBuffer and concat all buffers into it
|
|
1748
|
+
var mergedFrame = new ArrayBuffer(frameSize);
|
|
1749
|
+
var u8Data = new Uint8Array(mergedFrame);
|
|
1712
1750
|
fragments.reduce(function (offset, buffer) {
|
|
1713
|
-
|
|
1751
|
+
u8Data.set(new Uint8Array(buffer), offset);
|
|
1714
1752
|
return offset + buffer.byteLength;
|
|
1715
1753
|
}, 0);
|
|
1716
1754
|
return mergedFrame;
|
|
@@ -1718,22 +1756,15 @@ var BinaryRepresentation = /*#__PURE__*/function (_ValueRepresentation2) {
|
|
|
1718
1756
|
});
|
|
1719
1757
|
} // If no offset table, loop through remainder of stream looking for termination tag
|
|
1720
1758
|
else {
|
|
1721
|
-
while (stream.
|
|
1722
|
-
var
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1759
|
+
while (!stream.end()) {
|
|
1760
|
+
var buffer = getNextSequenceItemData(stream);
|
|
1761
|
+
|
|
1762
|
+
if (buffer === null) {
|
|
1763
|
+
break;
|
|
1764
|
+
}
|
|
1726
1765
|
|
|
1727
|
-
if (done) break;
|
|
1728
1766
|
frames.push(buffer);
|
|
1729
1767
|
}
|
|
1730
|
-
} // Read SequenceDelimitationItem Tag
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
stream.readUint32(); // Read SequenceDelimitationItem value.
|
|
1734
|
-
|
|
1735
|
-
if (stream.size - stream.offset >= 4) {
|
|
1736
|
-
stream.readUint32();
|
|
1737
1768
|
}
|
|
1738
1769
|
} else {
|
|
1739
1770
|
throw new Error("Item tag not found after undefined binary length");
|
|
@@ -1854,9 +1885,7 @@ var AttributeTag = /*#__PURE__*/function (_ValueRepresentation3) {
|
|
|
1854
1885
|
_createClass(AttributeTag, [{
|
|
1855
1886
|
key: "readBytes",
|
|
1856
1887
|
value: function readBytes(stream) {
|
|
1857
|
-
|
|
1858
|
-
element = stream.readUint16();
|
|
1859
|
-
return tagFromNumbers(group, element).value;
|
|
1888
|
+
return Tag.readTag(stream).value;
|
|
1860
1889
|
}
|
|
1861
1890
|
}, {
|
|
1862
1891
|
key: "writeBytes",
|
|
@@ -2293,7 +2322,7 @@ var SequenceOfItems = /*#__PURE__*/function (_ValueRepresentation7) {
|
|
|
2293
2322
|
/* eslint-disable-next-line no-constant-condition */
|
|
2294
2323
|
|
|
2295
2324
|
while (true) {
|
|
2296
|
-
var tag = readTag(stream),
|
|
2325
|
+
var tag = Tag.readTag(stream),
|
|
2297
2326
|
length = null;
|
|
2298
2327
|
read += 4;
|
|
2299
2328
|
|
|
@@ -2364,7 +2393,9 @@ var SequenceOfItems = /*#__PURE__*/function (_ValueRepresentation7) {
|
|
|
2364
2393
|
|
|
2365
2394
|
read += toRead;
|
|
2366
2395
|
if (undef) stream.increment(8);
|
|
2367
|
-
|
|
2396
|
+
|
|
2397
|
+
var items = DicomMessage._read(itemStream, syntax);
|
|
2398
|
+
|
|
2368
2399
|
elements.push(items);
|
|
2369
2400
|
}
|
|
2370
2401
|
|
|
@@ -2644,7 +2675,23 @@ var UniqueIdentifier = /*#__PURE__*/function (_StringRepresentation16) {
|
|
|
2644
2675
|
_createClass(UniqueIdentifier, [{
|
|
2645
2676
|
key: "readBytes",
|
|
2646
2677
|
value: function readBytes(stream, length) {
|
|
2647
|
-
|
|
2678
|
+
var result = this.readNullPaddedString(stream, length);
|
|
2679
|
+
var BACKSLASH = String.fromCharCode(0x5c);
|
|
2680
|
+
var uidRegExp = /[^0-9.]/g; // Treat backslashes as a delimiter for multiple UIDs, in which case an
|
|
2681
|
+
// array of UIDs is returned. This is used by DICOM Q&R to support
|
|
2682
|
+
// querying and matching multiple items on a UID field in a single
|
|
2683
|
+
// query. For more details see:
|
|
2684
|
+
//
|
|
2685
|
+
// https://dicom.nema.org/medical/dicom/current/output/chtml/part04/sect_C.2.2.2.2.html
|
|
2686
|
+
// https://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_6.4.html
|
|
2687
|
+
|
|
2688
|
+
if (result.indexOf(BACKSLASH) === -1) {
|
|
2689
|
+
return result.replace(uidRegExp, "");
|
|
2690
|
+
} else {
|
|
2691
|
+
return result.split(BACKSLASH).map(function (uid) {
|
|
2692
|
+
return uid.replace(uidRegExp, "");
|
|
2693
|
+
});
|
|
2694
|
+
}
|
|
2648
2695
|
}
|
|
2649
2696
|
}]);
|
|
2650
2697
|
|
|
@@ -2780,6 +2827,10 @@ var OtherFloatString = /*#__PURE__*/function (_BinaryRepresentation5) {
|
|
|
2780
2827
|
var IMPLICIT_LITTLE_ENDIAN = "1.2.840.10008.1.2";
|
|
2781
2828
|
var EXPLICIT_LITTLE_ENDIAN = "1.2.840.10008.1.2.1";
|
|
2782
2829
|
|
|
2830
|
+
function paddingLeft(paddingValue, string) {
|
|
2831
|
+
return String(paddingValue + string).slice(-paddingValue.length);
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2783
2834
|
var Tag = /*#__PURE__*/function () {
|
|
2784
2835
|
function Tag(value) {
|
|
2785
2836
|
_classCallCheck(this, Tag);
|
|
@@ -3349,11 +3400,40 @@ var DicomMessage = /*#__PURE__*/function () {
|
|
|
3349
3400
|
value: function read(bufferStream, syntax, ignoreErrors) {
|
|
3350
3401
|
var untilTag = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
3351
3402
|
var includeUntilTagValue = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
3403
|
+
console.warn("DicomMessage.read to be deprecated after dcmjs 0.24.x");
|
|
3404
|
+
return this._read(bufferStream, syntax, {
|
|
3405
|
+
ignoreErrors: ignoreErrors,
|
|
3406
|
+
untilTag: untilTag,
|
|
3407
|
+
includeUntilTagValue: includeUntilTagValue
|
|
3408
|
+
});
|
|
3409
|
+
}
|
|
3410
|
+
}, {
|
|
3411
|
+
key: "readTag",
|
|
3412
|
+
value: function readTag(bufferStream, syntax) {
|
|
3413
|
+
var untilTag = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
3414
|
+
var includeUntilTagValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
3415
|
+
console.warn("DicomMessage.readTag to be deprecated after dcmjs 0.24.x");
|
|
3416
|
+
return this._readTag(bufferStream, syntax, {
|
|
3417
|
+
untilTag: untilTag,
|
|
3418
|
+
includeUntilTagValue: includeUntilTagValue
|
|
3419
|
+
});
|
|
3420
|
+
}
|
|
3421
|
+
}, {
|
|
3422
|
+
key: "_read",
|
|
3423
|
+
value: function _read(bufferStream, syntax) {
|
|
3424
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
3425
|
+
ignoreErrors: false,
|
|
3426
|
+
untilTag: null,
|
|
3427
|
+
includeUntilTagValue: false
|
|
3428
|
+
};
|
|
3429
|
+
var ignoreErrors = options.ignoreErrors,
|
|
3430
|
+
untilTag = options.untilTag;
|
|
3352
3431
|
var dict = {};
|
|
3353
3432
|
|
|
3354
3433
|
try {
|
|
3355
3434
|
while (!bufferStream.end()) {
|
|
3356
|
-
var readInfo = DicomMessage.
|
|
3435
|
+
var readInfo = DicomMessage._readTag(bufferStream, syntax, options);
|
|
3436
|
+
|
|
3357
3437
|
var cleanTagString = readInfo.tag.toCleanString();
|
|
3358
3438
|
dict[cleanTagString] = {
|
|
3359
3439
|
vr: readInfo.vr.type,
|
|
@@ -3395,12 +3475,12 @@ var DicomMessage = /*#__PURE__*/function () {
|
|
|
3395
3475
|
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
3396
3476
|
ignoreErrors: false,
|
|
3397
3477
|
untilTag: null,
|
|
3398
|
-
includeUntilTagValue: false
|
|
3478
|
+
includeUntilTagValue: false,
|
|
3479
|
+
noCopy: false
|
|
3399
3480
|
};
|
|
3400
|
-
var
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
var stream = new ReadBufferStream(buffer),
|
|
3481
|
+
var stream = new ReadBufferStream(buffer, null, {
|
|
3482
|
+
noCopy: options.noCopy
|
|
3483
|
+
}),
|
|
3404
3484
|
useSyntax = EXPLICIT_LITTLE_ENDIAN$1;
|
|
3405
3485
|
stream.reset();
|
|
3406
3486
|
stream.increment(128);
|
|
@@ -3409,15 +3489,20 @@ var DicomMessage = /*#__PURE__*/function () {
|
|
|
3409
3489
|
throw new Error("Invalid a dicom file");
|
|
3410
3490
|
}
|
|
3411
3491
|
|
|
3412
|
-
var el = DicomMessage.
|
|
3492
|
+
var el = DicomMessage._readTag(stream, useSyntax),
|
|
3413
3493
|
metaLength = el.values[0]; //read header buffer
|
|
3414
3494
|
|
|
3495
|
+
|
|
3415
3496
|
var metaStream = stream.more(metaLength);
|
|
3416
|
-
|
|
3497
|
+
|
|
3498
|
+
var metaHeader = DicomMessage._read(metaStream, useSyntax, options); //get the syntax
|
|
3499
|
+
|
|
3417
3500
|
|
|
3418
3501
|
var mainSyntax = metaHeader["00020010"].Value[0];
|
|
3419
3502
|
mainSyntax = DicomMessage._normalizeSyntax(mainSyntax);
|
|
3420
|
-
|
|
3503
|
+
|
|
3504
|
+
var objects = DicomMessage._read(stream, mainSyntax, options);
|
|
3505
|
+
|
|
3421
3506
|
var dicomDict = new DicomDict(metaHeader);
|
|
3422
3507
|
dicomDict.dict = objects;
|
|
3423
3508
|
return dicomDict;
|
|
@@ -3443,17 +3528,19 @@ var DicomMessage = /*#__PURE__*/function () {
|
|
|
3443
3528
|
return written;
|
|
3444
3529
|
}
|
|
3445
3530
|
}, {
|
|
3446
|
-
key: "
|
|
3447
|
-
value: function
|
|
3448
|
-
var
|
|
3449
|
-
|
|
3531
|
+
key: "_readTag",
|
|
3532
|
+
value: function _readTag(stream, syntax) {
|
|
3533
|
+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
|
|
3534
|
+
untilTag: null,
|
|
3535
|
+
includeUntilTagValue: false
|
|
3536
|
+
};
|
|
3537
|
+
var untilTag = options.untilTag,
|
|
3538
|
+
includeUntilTagValue = options.includeUntilTagValue;
|
|
3450
3539
|
var implicit = syntax == IMPLICIT_LITTLE_ENDIAN$1 ? true : false,
|
|
3451
3540
|
isLittleEndian = syntax == IMPLICIT_LITTLE_ENDIAN$1 || syntax == EXPLICIT_LITTLE_ENDIAN$1 ? true : false;
|
|
3452
3541
|
var oldEndian = stream.isLittleEndian;
|
|
3453
3542
|
stream.setEndian(isLittleEndian);
|
|
3454
|
-
var
|
|
3455
|
-
element = stream.readUint16(),
|
|
3456
|
-
tag = tagFromNumbers(group, element);
|
|
3543
|
+
var tag = Tag.readTag(stream);
|
|
3457
3544
|
|
|
3458
3545
|
if (untilTag === tag.toCleanString() && untilTag !== null) {
|
|
3459
3546
|
if (!includeUntilTagValue) {
|