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 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
- //resize
1073
- var dstSize = this.offset + step;
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, this.offset, this.offset + length);
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, start, end) {
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 = end || _this.buffer.byteLength;
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 getFrameOrFragement = function getFrameOrFragement(stream) {
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 (!nextTag.is(0xfffee000)) {
1662
- return [null, true];
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
- var frameOrFragmentItemLength = stream.readUint32();
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 s = new ReadBufferStream(stream.buffer, stream.isLittleEndian, start, stop);
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 (!s.end()) {
1690
- var _getFrameOrFragement = getFrameOrFragement(s),
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 (done) {
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
- return fragments;
1703
- });
1704
- frames = frames.map(function (fragments) {
1705
- if (fragments.length < 1) {
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
- var frameSize = fragments.reduce(function (size, buffer) {
1709
- return size + buffer.byteLength;
1710
- }, 0);
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
- mergedFrame.set(new Uint8Array(buffer), offset);
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.offset < stream.size) {
1722
- var _getFrameOrFragement3 = getFrameOrFragement(stream),
1723
- _getFrameOrFragement4 = _slicedToArray(_getFrameOrFragement3, 2),
1724
- buffer = _getFrameOrFragement4[0],
1725
- done = _getFrameOrFragement4[1];
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
- var group = stream.readUint16(),
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
- var items = DicomMessage.read(itemStream, syntax);
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
- return this.readNullPaddedString(stream, length).replace(/[^0-9.]/g, "");
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.readTag(bufferStream, syntax, untilTag, includeUntilTagValue);
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 ignoreErrors = options.ignoreErrors,
3401
- untilTag = options.untilTag,
3402
- includeUntilTagValue = options.includeUntilTagValue;
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.readTag(stream, useSyntax),
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
- var metaHeader = DicomMessage.read(metaStream, useSyntax, ignoreErrors); //get the syntax
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
- var objects = DicomMessage.read(stream, mainSyntax, ignoreErrors, untilTag, includeUntilTagValue);
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: "readTag",
3447
- value: function readTag(stream, syntax) {
3448
- var untilTag = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
3449
- var includeUntilTagValue = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
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 group = stream.readUint16(),
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) {