@cosyte/dicom 0.0.17 → 0.0.18
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/CHANGELOG.md +199 -0
- package/README.md +3 -1
- package/dist/index.cjs +135 -91
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +241 -116
- package/dist/index.d.ts +241 -116
- package/dist/index.mjs +135 -92
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -11,7 +11,7 @@ var __export = (target, all) => {
|
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
// src/version.ts
|
|
14
|
-
var VERSION = "0.0.
|
|
14
|
+
var VERSION = "0.0.18";
|
|
15
15
|
|
|
16
16
|
// src/dictionary/index.ts
|
|
17
17
|
var dictionary_exports = {};
|
|
@@ -11668,23 +11668,52 @@ var FATAL_CODES = {
|
|
|
11668
11668
|
UNSUPPORTED_TRANSFER_SYNTAX: "UNSUPPORTED_TRANSFER_SYNTAX",
|
|
11669
11669
|
EMPTY_INPUT: "EMPTY_INPUT"
|
|
11670
11670
|
};
|
|
11671
|
+
var OFFSET_FRAMES = {
|
|
11672
|
+
/**
|
|
11673
|
+
* Byte 0 is byte 0 of the buffer handed to `parseDicom`. The only frame in
|
|
11674
|
+
* which indexing the caller's own input by `byteOffset` is meaningful.
|
|
11675
|
+
*/
|
|
11676
|
+
INPUT: "input",
|
|
11677
|
+
/**
|
|
11678
|
+
* Byte 0 is byte 0 of the inflated Data Set of a Deflated Explicit VR LE
|
|
11679
|
+
* object (`1.2.840.10008.1.2.1.99`). The compressed input holds no such
|
|
11680
|
+
* byte, so the offset does not index it at any scale.
|
|
11681
|
+
*/
|
|
11682
|
+
INFLATED_DATASET: "inflated-dataset",
|
|
11683
|
+
/**
|
|
11684
|
+
* Byte 0 is byte 0 of a slice this parser cut from inside a Value Field: a
|
|
11685
|
+
* defined-length Sequence Item's value, or an `SQ`/`UN` value handed to a
|
|
11686
|
+
* descent. **Where that slice begins is deliberately not published** - see
|
|
11687
|
+
* this table's own note.
|
|
11688
|
+
*/
|
|
11689
|
+
VALUE_SLICE: "value-slice"
|
|
11690
|
+
};
|
|
11671
11691
|
var DicomParseError = class extends Error {
|
|
11672
11692
|
code;
|
|
11673
11693
|
byteOffset;
|
|
11694
|
+
/**
|
|
11695
|
+
* The coordinate system {@link DicomParseError.byteOffset} is counted in.
|
|
11696
|
+
* See {@link OFFSET_FRAMES}.
|
|
11697
|
+
*/
|
|
11698
|
+
offsetFrame;
|
|
11674
11699
|
snippet;
|
|
11675
11700
|
contextPath;
|
|
11676
11701
|
/**
|
|
11677
11702
|
* Construct a new `DicomParseError`. All fields except `contextPath` are
|
|
11678
|
-
* required so every thrower populates positional context per `TOL-02
|
|
11703
|
+
* required so every thrower populates positional context per `TOL-02` - and
|
|
11704
|
+
* `offsetFrame` is required for the same reason `byteOffset` is, because an
|
|
11705
|
+
* offset whose frame is optional is an offset whose frame is usually
|
|
11706
|
+
* missing.
|
|
11679
11707
|
*
|
|
11680
11708
|
* @internal
|
|
11681
11709
|
*/
|
|
11682
|
-
constructor(code, message, byteOffset, snippet, contextPath) {
|
|
11683
|
-
const formatted = `[${code}] ${message} (offset=${String(byteOffset)})` + (contextPath !== void 0 && contextPath.length > 0 ? ` \u2026 in ${contextPath.join("/")}` : "");
|
|
11710
|
+
constructor(code, message, byteOffset, offsetFrame, snippet, contextPath) {
|
|
11711
|
+
const formatted = `[${code}] ${message} (offset=${String(byteOffset)} frame=${offsetFrame})` + (contextPath !== void 0 && contextPath.length > 0 ? ` \u2026 in ${contextPath.join("/")}` : "");
|
|
11684
11712
|
super(formatted);
|
|
11685
11713
|
this.name = "DicomParseError";
|
|
11686
11714
|
this.code = code;
|
|
11687
11715
|
this.byteOffset = byteOffset;
|
|
11716
|
+
this.offsetFrame = offsetFrame;
|
|
11688
11717
|
this.snippet = snippet;
|
|
11689
11718
|
this.contextPath = contextPath;
|
|
11690
11719
|
}
|
|
@@ -11710,7 +11739,12 @@ function makeEmitter(ctx) {
|
|
|
11710
11739
|
w.code,
|
|
11711
11740
|
w.message,
|
|
11712
11741
|
w.position.byteOffset,
|
|
11713
|
-
|
|
11742
|
+
// Both come off the SAME frame object, so an escalation cannot name one
|
|
11743
|
+
// frame and cut its bytes from another. `DicomParseWarning.position`
|
|
11744
|
+
// itself carries no frame - that is `PRE-EXISTING` and stated on
|
|
11745
|
+
// `DicomPosition`, not closed here.
|
|
11746
|
+
ctx.frame.name,
|
|
11747
|
+
buildSnippet(ctx.frame.buffer, w.position.byteOffset),
|
|
11714
11748
|
w.position.contextPath
|
|
11715
11749
|
);
|
|
11716
11750
|
};
|
|
@@ -11836,8 +11870,11 @@ var FATAL_MESSAGES = Object.freeze({
|
|
|
11836
11870
|
message: "File Meta is truncated."
|
|
11837
11871
|
},
|
|
11838
11872
|
// The declared group length is deliberately absent. It is four bytes of the
|
|
11839
|
-
// document read as a 32-bit integer
|
|
11840
|
-
// four bytes are
|
|
11873
|
+
// document read as a 32-bit integer. **NOT because this code fires only when
|
|
11874
|
+
// those four bytes are fabricated** - an honestly truncated file raises it
|
|
11875
|
+
// with a perfectly correct group length, measured - but because they are four
|
|
11876
|
+
// bytes a sender wrote in either reading, and in the other one they are part
|
|
11877
|
+
// of somebody's value.
|
|
11841
11878
|
FILE_META_GROUP_LENGTH_OVERRUNS: {
|
|
11842
11879
|
code: FATAL_CODES.INVALID_FILE_META,
|
|
11843
11880
|
message: "(0002,0000) FileMetaInformationGroupLength declares more bytes than remain in the input. The declared length and the count of bytes that remain are withheld; the byte offset locates the group."
|
|
@@ -11922,88 +11959,89 @@ function renderTransferSyntax(ts) {
|
|
|
11922
11959
|
function renderZlibCode(code) {
|
|
11923
11960
|
return code !== void 0 && ZLIB_CODES.has(code) ? code : WITHHELD;
|
|
11924
11961
|
}
|
|
11925
|
-
function build(key, byteOffset, snippet, tokens = {}) {
|
|
11962
|
+
function build(key, byteOffset, offsetFrame, snippet, tokens = {}) {
|
|
11926
11963
|
const entry = FATAL_MESSAGES[key];
|
|
11927
11964
|
const message = entry.message.replace("{vr}", renderVr(tokens.vr)).replace("{ts}", renderTransferSyntax(tokens.ts)).replace("{zlib}", renderZlibCode(tokens.zlib)).replace("{n}", String(tokens.n ?? 0));
|
|
11928
|
-
return new DicomParseError(entry.code, message, byteOffset, snippet);
|
|
11965
|
+
return new DicomParseError(entry.code, message, byteOffset, offsetFrame, snippet);
|
|
11929
11966
|
}
|
|
11930
|
-
function at(key,
|
|
11931
|
-
return build(key, offset, buildSnippet(buffer, offset), tokens);
|
|
11967
|
+
function at(key, frame, offset, tokens = {}) {
|
|
11968
|
+
return build(key, offset, frame.name, buildSnippet(frame.buffer, offset), tokens);
|
|
11932
11969
|
}
|
|
11933
11970
|
function emptyInput() {
|
|
11934
|
-
return build("EMPTY_INPUT", 0, "");
|
|
11971
|
+
return build("EMPTY_INPUT", 0, OFFSET_FRAMES.INPUT, "");
|
|
11935
11972
|
}
|
|
11936
11973
|
function emptyInputAfterNormalization() {
|
|
11937
|
-
return build("EMPTY_INPUT_AFTER_NORMALIZATION", 0, "");
|
|
11974
|
+
return build("EMPTY_INPUT_AFTER_NORMALIZATION", 0, OFFSET_FRAMES.INPUT, "");
|
|
11938
11975
|
}
|
|
11939
|
-
function notDicomPart10Required(
|
|
11940
|
-
return at("NOT_DICOM_PART_10_REQUIRED",
|
|
11976
|
+
function notDicomPart10Required(frame, offset) {
|
|
11977
|
+
return at("NOT_DICOM_PART_10_REQUIRED", frame, offset);
|
|
11941
11978
|
}
|
|
11942
|
-
function notDicomPart10(
|
|
11943
|
-
return at("NOT_DICOM_PART_10",
|
|
11979
|
+
function notDicomPart10(frame, offset) {
|
|
11980
|
+
return at("NOT_DICOM_PART_10", frame, offset);
|
|
11944
11981
|
}
|
|
11945
|
-
function unsupportedTransferSyntax(
|
|
11982
|
+
function unsupportedTransferSyntax(frame, offset, ts) {
|
|
11946
11983
|
const name = uid(ts)?.name ?? "";
|
|
11947
11984
|
return build(
|
|
11948
11985
|
"UNSUPPORTED_TRANSFER_SYNTAX",
|
|
11949
11986
|
offset,
|
|
11950
|
-
|
|
11987
|
+
frame.name,
|
|
11988
|
+
name.length > 0 ? name : buildSnippet(frame.buffer, offset),
|
|
11951
11989
|
{ ts }
|
|
11952
11990
|
);
|
|
11953
11991
|
}
|
|
11954
|
-
function fileMetaTruncated(
|
|
11955
|
-
return at("FILE_META_TRUNCATED",
|
|
11992
|
+
function fileMetaTruncated(frame, offset) {
|
|
11993
|
+
return at("FILE_META_TRUNCATED", frame, offset);
|
|
11956
11994
|
}
|
|
11957
|
-
function fileMetaGroupLengthOverruns(
|
|
11958
|
-
return at("FILE_META_GROUP_LENGTH_OVERRUNS",
|
|
11995
|
+
function fileMetaGroupLengthOverruns(frame, offset) {
|
|
11996
|
+
return at("FILE_META_GROUP_LENGTH_OVERRUNS", frame, offset);
|
|
11959
11997
|
}
|
|
11960
|
-
function fileMetaTransferSyntaxMissing(
|
|
11961
|
-
return at("FILE_META_TRANSFER_SYNTAX_MISSING",
|
|
11998
|
+
function fileMetaTransferSyntaxMissing(frame, offset) {
|
|
11999
|
+
return at("FILE_META_TRANSFER_SYNTAX_MISSING", frame, offset);
|
|
11962
12000
|
}
|
|
11963
|
-
function truncatedDatasetHeader(
|
|
11964
|
-
return at("TRUNCATED_DATASET_HEADER",
|
|
12001
|
+
function truncatedDatasetHeader(frame, offset) {
|
|
12002
|
+
return at("TRUNCATED_DATASET_HEADER", frame, offset);
|
|
11965
12003
|
}
|
|
11966
|
-
function truncatedFffeHeader(
|
|
11967
|
-
return at("TRUNCATED_FFFE_HEADER",
|
|
12004
|
+
function truncatedFffeHeader(frame, offset) {
|
|
12005
|
+
return at("TRUNCATED_FFFE_HEADER", frame, offset);
|
|
11968
12006
|
}
|
|
11969
|
-
function truncatedExplicitVrHeader(
|
|
11970
|
-
return at("TRUNCATED_EXPLICIT_VR_HEADER",
|
|
12007
|
+
function truncatedExplicitVrHeader(frame, offset) {
|
|
12008
|
+
return at("TRUNCATED_EXPLICIT_VR_HEADER", frame, offset);
|
|
11971
12009
|
}
|
|
11972
|
-
function sqItemHeaderTruncated(
|
|
11973
|
-
return at("SQ_ITEM_HEADER_TRUNCATED",
|
|
12010
|
+
function sqItemHeaderTruncated(frame, offset) {
|
|
12011
|
+
return at("SQ_ITEM_HEADER_TRUNCATED", frame, offset);
|
|
11974
12012
|
}
|
|
11975
|
-
function unexpectedFffeAtDatasetLevel(
|
|
11976
|
-
return at("UNEXPECTED_FFFE_AT_DATASET_LEVEL",
|
|
12013
|
+
function unexpectedFffeAtDatasetLevel(frame, offset) {
|
|
12014
|
+
return at("UNEXPECTED_FFFE_AT_DATASET_LEVEL", frame, offset);
|
|
11977
12015
|
}
|
|
11978
|
-
function unexpectedFffeAtDatasetRoot(
|
|
11979
|
-
return at("UNEXPECTED_FFFE_AT_DATASET_ROOT",
|
|
12016
|
+
function unexpectedFffeAtDatasetRoot(frame, offset) {
|
|
12017
|
+
return at("UNEXPECTED_FFFE_AT_DATASET_ROOT", frame, offset);
|
|
11980
12018
|
}
|
|
11981
|
-
function undefinedLengthOnNonSqExplicit(
|
|
11982
|
-
return at("UNDEFINED_LENGTH_ON_NON_SQ_EXPLICIT",
|
|
12019
|
+
function undefinedLengthOnNonSqExplicit(frame, offset, vr) {
|
|
12020
|
+
return at("UNDEFINED_LENGTH_ON_NON_SQ_EXPLICIT", frame, offset, { vr });
|
|
11983
12021
|
}
|
|
11984
|
-
function undefinedLengthOnNonSqImplicit(
|
|
11985
|
-
return at("UNDEFINED_LENGTH_ON_NON_SQ_IMPLICIT",
|
|
12022
|
+
function undefinedLengthOnNonSqImplicit(frame, offset, vr) {
|
|
12023
|
+
return at("UNDEFINED_LENGTH_ON_NON_SQ_IMPLICIT", frame, offset, { vr });
|
|
11986
12024
|
}
|
|
11987
|
-
function elementLengthExceedsBuffer(
|
|
11988
|
-
return at("ELEMENT_LENGTH_EXCEEDS_BUFFER",
|
|
12025
|
+
function elementLengthExceedsBuffer(frame, offset) {
|
|
12026
|
+
return at("ELEMENT_LENGTH_EXCEEDS_BUFFER", frame, offset);
|
|
11989
12027
|
}
|
|
11990
|
-
function unexpectedTagInsideSequence(
|
|
11991
|
-
return at("UNEXPECTED_TAG_INSIDE_SEQUENCE",
|
|
12028
|
+
function unexpectedTagInsideSequence(frame, offset) {
|
|
12029
|
+
return at("UNEXPECTED_TAG_INSIDE_SEQUENCE", frame, offset);
|
|
11992
12030
|
}
|
|
11993
|
-
function encapsulatedFragmentExceedsBuffer(
|
|
11994
|
-
return at("ENCAPSULATED_FRAGMENT_EXCEEDS_BUFFER",
|
|
12031
|
+
function encapsulatedFragmentExceedsBuffer(frame, offset) {
|
|
12032
|
+
return at("ENCAPSULATED_FRAGMENT_EXCEEDS_BUFFER", frame, offset);
|
|
11995
12033
|
}
|
|
11996
|
-
function itemLengthExceedsBuffer(
|
|
11997
|
-
return at("ITEM_LENGTH_EXCEEDS_BUFFER",
|
|
12034
|
+
function itemLengthExceedsBuffer(frame, offset) {
|
|
12035
|
+
return at("ITEM_LENGTH_EXCEEDS_BUFFER", frame, offset);
|
|
11998
12036
|
}
|
|
11999
|
-
function sqNestingDepthExceeded(
|
|
12000
|
-
return at("SQ_NESTING_DEPTH_EXCEEDED",
|
|
12037
|
+
function sqNestingDepthExceeded(frame, offset, limit) {
|
|
12038
|
+
return at("SQ_NESTING_DEPTH_EXCEEDED", frame, offset, { n: limit });
|
|
12001
12039
|
}
|
|
12002
|
-
function inflatedPayloadExceedsCap(
|
|
12003
|
-
return at("INFLATED_PAYLOAD_EXCEEDS_CAP",
|
|
12040
|
+
function inflatedPayloadExceedsCap(frame, offset, cap) {
|
|
12041
|
+
return at("INFLATED_PAYLOAD_EXCEEDS_CAP", frame, offset, { n: cap });
|
|
12004
12042
|
}
|
|
12005
|
-
function inflateFailed(
|
|
12006
|
-
return at("INFLATE_FAILED",
|
|
12043
|
+
function inflateFailed(frame, offset, code) {
|
|
12044
|
+
return at("INFLATE_FAILED", frame, offset, ...code !== void 0 ? [{ zlib: code }] : []);
|
|
12007
12045
|
}
|
|
12008
12046
|
function copyValueBytes(src) {
|
|
12009
12047
|
const out = buffer.Buffer.allocUnsafeSlow(src.length);
|
|
@@ -12636,7 +12674,7 @@ function parseFileMeta(buffer$1, datasetStart, ctx, emit) {
|
|
|
12636
12674
|
firstElement = readExplicitLeElement(cursor);
|
|
12637
12675
|
} catch (err) {
|
|
12638
12676
|
if (err instanceof RangeError) {
|
|
12639
|
-
throw fileMetaTruncated(
|
|
12677
|
+
throw fileMetaTruncated(ctx.frame, fmStart);
|
|
12640
12678
|
}
|
|
12641
12679
|
throw err;
|
|
12642
12680
|
}
|
|
@@ -12646,7 +12684,7 @@ function parseFileMeta(buffer$1, datasetStart, ctx, emit) {
|
|
|
12646
12684
|
if (firstElement.tag === "00020000" && firstElement.vr === "UL" && firstElement.value.length === 4) {
|
|
12647
12685
|
declaredFmLength = firstElement.value.readUInt32LE(0);
|
|
12648
12686
|
if (cursor.position + declaredFmLength > buffer$1.length) {
|
|
12649
|
-
throw fileMetaGroupLengthOverruns(
|
|
12687
|
+
throw fileMetaGroupLengthOverruns(ctx.frame, fmStart);
|
|
12650
12688
|
}
|
|
12651
12689
|
} else {
|
|
12652
12690
|
emit(fileMetaGroupLengthMissing({ byteOffset: fmStart, fileMeta: true }));
|
|
@@ -12663,7 +12701,7 @@ function parseFileMeta(buffer$1, datasetStart, ctx, emit) {
|
|
|
12663
12701
|
next = readExplicitLeElement(cursor);
|
|
12664
12702
|
} catch (err) {
|
|
12665
12703
|
if (err instanceof RangeError) {
|
|
12666
|
-
throw fileMetaTruncated(
|
|
12704
|
+
throw fileMetaTruncated(ctx.frame, fmStart);
|
|
12667
12705
|
}
|
|
12668
12706
|
throw err;
|
|
12669
12707
|
}
|
|
@@ -12687,7 +12725,7 @@ function parseFileMeta(buffer$1, datasetStart, ctx, emit) {
|
|
|
12687
12725
|
next = readExplicitLeElement(cursor);
|
|
12688
12726
|
} catch (err) {
|
|
12689
12727
|
if (err instanceof RangeError) {
|
|
12690
|
-
throw fileMetaTruncated(
|
|
12728
|
+
throw fileMetaTruncated(ctx.frame, fmStart);
|
|
12691
12729
|
}
|
|
12692
12730
|
throw err;
|
|
12693
12731
|
}
|
|
@@ -12706,7 +12744,7 @@ function parseFileMeta(buffer$1, datasetStart, ctx, emit) {
|
|
|
12706
12744
|
}
|
|
12707
12745
|
const tsElement = fmElements.find((e) => e.tag === "00020010");
|
|
12708
12746
|
if (tsElement === void 0 || tsElement.vr !== "UI") {
|
|
12709
|
-
throw fileMetaTransferSyntaxMissing(
|
|
12747
|
+
throw fileMetaTransferSyntaxMissing(ctx.frame, fmStart);
|
|
12710
12748
|
}
|
|
12711
12749
|
const extraElements = fmElements.filter((e) => !MODELED_FM_TAGS.has(e.tag)).map((e) => Object.freeze({ tag: e.tag, vr: e.vr, value: buffer.Buffer.from(e.value) }));
|
|
12712
12750
|
const fileMeta = {
|
|
@@ -12790,13 +12828,13 @@ function parsePart10Header(buffer, ctx, emit) {
|
|
|
12790
12828
|
return { datasetStart: 132, hadPreamble: true };
|
|
12791
12829
|
}
|
|
12792
12830
|
if (ctx.stripPreamble === "require") {
|
|
12793
|
-
throw notDicomPart10Required(
|
|
12831
|
+
throw notDicomPart10Required(ctx.frame, 0);
|
|
12794
12832
|
}
|
|
12795
12833
|
if (looksLikeFileMetaGroupLengthAtOffsetZero(buffer)) {
|
|
12796
12834
|
emit(missingPreamble({ byteOffset: 0 }));
|
|
12797
12835
|
return { datasetStart: 0, hadPreamble: false };
|
|
12798
12836
|
}
|
|
12799
|
-
throw notDicomPart10(
|
|
12837
|
+
throw notDicomPart10(ctx.frame, 0);
|
|
12800
12838
|
}
|
|
12801
12839
|
function looksLikeFileMetaGroupLengthAtOffsetZero(buffer) {
|
|
12802
12840
|
if (buffer.length < 12) return false;
|
|
@@ -13207,7 +13245,7 @@ function parseSequence(buffer, valueStart, ctx, emit, opts) {
|
|
|
13207
13245
|
ctx.nestingDepth += 1;
|
|
13208
13246
|
if (ctx.nestingDepth > NESTING_DEPTH_LIMIT) {
|
|
13209
13247
|
ctx.nestingDepth -= 1;
|
|
13210
|
-
throw sqNestingDepthExceeded(
|
|
13248
|
+
throw sqNestingDepthExceeded(ctx.frame, valueStart, NESTING_DEPTH_LIMIT);
|
|
13211
13249
|
}
|
|
13212
13250
|
ctx.encodingContextStack.push(
|
|
13213
13251
|
opts.encapsulatedPixelData === true ? "EncapsulatedPixelData" : "SqItem"
|
|
@@ -13243,7 +13281,7 @@ function parseSequence(buffer, valueStart, ctx, emit, opts) {
|
|
|
13243
13281
|
itemLength = cursor.readUInt32();
|
|
13244
13282
|
} catch (err) {
|
|
13245
13283
|
if (err instanceof RangeError) {
|
|
13246
|
-
throw sqItemHeaderTruncated(
|
|
13284
|
+
throw sqItemHeaderTruncated(ctx.frame, itemHeaderStart);
|
|
13247
13285
|
}
|
|
13248
13286
|
throw err;
|
|
13249
13287
|
}
|
|
@@ -13252,7 +13290,7 @@ function parseSequence(buffer, valueStart, ctx, emit, opts) {
|
|
|
13252
13290
|
return { items, endOffset: cursor.position };
|
|
13253
13291
|
}
|
|
13254
13292
|
if (itemTag !== ITEM_TAG) {
|
|
13255
|
-
throw unexpectedTagInsideSequence(
|
|
13293
|
+
throw unexpectedTagInsideSequence(ctx.frame, itemHeaderStart);
|
|
13256
13294
|
}
|
|
13257
13295
|
if (itemLength === 0) {
|
|
13258
13296
|
emit(emptyItemInSequence({ byteOffset: itemHeaderStart }, itemTag));
|
|
@@ -13268,7 +13306,7 @@ function parseSequence(buffer, valueStart, ctx, emit, opts) {
|
|
|
13268
13306
|
}
|
|
13269
13307
|
if (opts.encapsulatedPixelData === true) {
|
|
13270
13308
|
if (cursor.position + itemLength > buffer.length) {
|
|
13271
|
-
throw encapsulatedFragmentExceedsBuffer(
|
|
13309
|
+
throw encapsulatedFragmentExceedsBuffer(ctx.frame, itemHeaderStart);
|
|
13272
13310
|
}
|
|
13273
13311
|
cursor.position += itemLength;
|
|
13274
13312
|
items.push(new Item({ warnings: [], elements: /* @__PURE__ */ new Map(), index: itemIndex }));
|
|
@@ -13288,16 +13326,16 @@ function parseSequence(buffer, valueStart, ctx, emit, opts) {
|
|
|
13288
13326
|
emit(itemCrossesSequenceEnd({ byteOffset: itemHeaderStart }, itemTag));
|
|
13289
13327
|
}
|
|
13290
13328
|
if (cursor.position + itemLength > buffer.length) {
|
|
13291
|
-
throw itemLengthExceedsBuffer(
|
|
13329
|
+
throw itemLengthExceedsBuffer(ctx.frame, itemHeaderStart);
|
|
13292
13330
|
}
|
|
13293
13331
|
const itemSlice = buffer.subarray(cursor.position, cursor.position + itemLength);
|
|
13294
|
-
const enclosingFrame = ctx.
|
|
13332
|
+
const enclosingFrame = ctx.frame;
|
|
13295
13333
|
let inner;
|
|
13296
13334
|
try {
|
|
13297
|
-
ctx.
|
|
13335
|
+
ctx.frame = { buffer: itemSlice, name: OFFSET_FRAMES.VALUE_SLICE };
|
|
13298
13336
|
inner = opts.innerStrategy(itemSlice, 0, ctx, emit);
|
|
13299
13337
|
} finally {
|
|
13300
|
-
ctx.
|
|
13338
|
+
ctx.frame = enclosingFrame;
|
|
13301
13339
|
}
|
|
13302
13340
|
items.push(new Item({ warnings: [], elements: inner.elements, index: itemIndex }));
|
|
13303
13341
|
cursor.position += itemLength;
|
|
@@ -13322,17 +13360,17 @@ function tryParseDefinedLengthSQ(buffer, valueStart, valueLength, ctx, emit, imp
|
|
|
13322
13360
|
const savedWarningsLen = ctx.warnings.length;
|
|
13323
13361
|
try {
|
|
13324
13362
|
const slice = buffer.subarray(valueStart, valueStart + valueLength);
|
|
13325
|
-
const enclosingFrame = ctx.
|
|
13363
|
+
const enclosingFrame = ctx.frame;
|
|
13326
13364
|
let result;
|
|
13327
13365
|
try {
|
|
13328
|
-
ctx.
|
|
13366
|
+
ctx.frame = { buffer: slice, name: OFFSET_FRAMES.VALUE_SLICE };
|
|
13329
13367
|
result = parseSequence(slice, 0, ctx, emit, {
|
|
13330
13368
|
explicitLength: valueLength,
|
|
13331
13369
|
littleEndian: true,
|
|
13332
13370
|
innerStrategy: implicitLeInner
|
|
13333
13371
|
});
|
|
13334
13372
|
} finally {
|
|
13335
|
-
ctx.
|
|
13373
|
+
ctx.frame = enclosingFrame;
|
|
13336
13374
|
}
|
|
13337
13375
|
return { success: true, items: result.items };
|
|
13338
13376
|
} catch (err) {
|
|
@@ -13360,13 +13398,13 @@ function tryParseUnAsSQ(buffer, valueStart, valueLength, ctx, emit, implicitLeIn
|
|
|
13360
13398
|
// CP-246: Implicit VR LE inner per D-30.
|
|
13361
13399
|
innerStrategy: implicitLeInner
|
|
13362
13400
|
};
|
|
13363
|
-
const enclosingFrame = ctx.
|
|
13401
|
+
const enclosingFrame = ctx.frame;
|
|
13364
13402
|
let result;
|
|
13365
13403
|
try {
|
|
13366
|
-
ctx.
|
|
13404
|
+
ctx.frame = { buffer: slice, name: OFFSET_FRAMES.VALUE_SLICE };
|
|
13367
13405
|
result = parseSequence(slice, 0, ctx, emit, opts);
|
|
13368
13406
|
} finally {
|
|
13369
|
-
ctx.
|
|
13407
|
+
ctx.frame = enclosingFrame;
|
|
13370
13408
|
}
|
|
13371
13409
|
emit(unParsedAsSQ({ byteOffset: valueStart }, tag));
|
|
13372
13410
|
return {
|
|
@@ -13404,7 +13442,7 @@ function parseImplicitLE(buffer, datasetStart, ctx, emit, opts = {}) {
|
|
|
13404
13442
|
length = cursor.readUInt32();
|
|
13405
13443
|
} catch (err) {
|
|
13406
13444
|
if (err instanceof RangeError) {
|
|
13407
|
-
throw truncatedDatasetHeader(
|
|
13445
|
+
throw truncatedDatasetHeader(ctx.frame, headerStart);
|
|
13408
13446
|
}
|
|
13409
13447
|
throw err;
|
|
13410
13448
|
}
|
|
@@ -13413,7 +13451,7 @@ function parseImplicitLE(buffer, datasetStart, ctx, emit, opts = {}) {
|
|
|
13413
13451
|
if (opts.stopOnItemDelim === true && tag === "FFFEE00D") {
|
|
13414
13452
|
return { elements, endOffset: cursor.position };
|
|
13415
13453
|
}
|
|
13416
|
-
throw unexpectedFffeAtDatasetRoot(
|
|
13454
|
+
throw unexpectedFffeAtDatasetRoot(ctx.frame, headerStart);
|
|
13417
13455
|
}
|
|
13418
13456
|
const position = { byteOffset: headerStart };
|
|
13419
13457
|
const vr = resolveImplicitVR(tag, ctx, emit, position);
|
|
@@ -13480,10 +13518,10 @@ function parseImplicitLE(buffer, datasetStart, ctx, emit, opts = {}) {
|
|
|
13480
13518
|
continue;
|
|
13481
13519
|
}
|
|
13482
13520
|
}
|
|
13483
|
-
throw undefinedLengthOnNonSqImplicit(
|
|
13521
|
+
throw undefinedLengthOnNonSqImplicit(ctx.frame, headerStart, vr);
|
|
13484
13522
|
}
|
|
13485
13523
|
if (cursor.position + length > buffer.length) {
|
|
13486
|
-
throw elementLengthExceedsBuffer(
|
|
13524
|
+
throw elementLengthExceedsBuffer(ctx.frame, headerStart);
|
|
13487
13525
|
}
|
|
13488
13526
|
const valueStart = cursor.position;
|
|
13489
13527
|
const valueEnd = valueStart + length;
|
|
@@ -13559,7 +13597,7 @@ function _parseExplicit(buffer, datasetStart, ctx, emit, mode, opts = {}) {
|
|
|
13559
13597
|
peekGroup = cursor.readUInt16At(cursor.position);
|
|
13560
13598
|
} catch (err) {
|
|
13561
13599
|
if (err instanceof RangeError) {
|
|
13562
|
-
throw truncatedDatasetHeader(
|
|
13600
|
+
throw truncatedDatasetHeader(ctx.frame, headerStart);
|
|
13563
13601
|
}
|
|
13564
13602
|
throw err;
|
|
13565
13603
|
}
|
|
@@ -13572,7 +13610,7 @@ function _parseExplicit(buffer, datasetStart, ctx, emit, mode, opts = {}) {
|
|
|
13572
13610
|
cursor.readUInt32();
|
|
13573
13611
|
} catch (err) {
|
|
13574
13612
|
if (err instanceof RangeError) {
|
|
13575
|
-
throw truncatedFffeHeader(
|
|
13613
|
+
throw truncatedFffeHeader(ctx.frame, headerStart);
|
|
13576
13614
|
}
|
|
13577
13615
|
throw err;
|
|
13578
13616
|
}
|
|
@@ -13580,14 +13618,14 @@ function _parseExplicit(buffer, datasetStart, ctx, emit, mode, opts = {}) {
|
|
|
13580
13618
|
if (opts.stopOnItemDelim === true && fffeTag === "FFFEE00D") {
|
|
13581
13619
|
return { elements, endOffset: cursor.position };
|
|
13582
13620
|
}
|
|
13583
|
-
throw unexpectedFffeAtDatasetLevel(
|
|
13621
|
+
throw unexpectedFffeAtDatasetLevel(ctx.frame, headerStart);
|
|
13584
13622
|
}
|
|
13585
13623
|
let header;
|
|
13586
13624
|
try {
|
|
13587
13625
|
header = readExplicitElementHeader(cursor, ctx, emit);
|
|
13588
13626
|
} catch (err) {
|
|
13589
13627
|
if (err instanceof RangeError) {
|
|
13590
|
-
throw truncatedExplicitVrHeader(
|
|
13628
|
+
throw truncatedExplicitVrHeader(ctx.frame, headerStart);
|
|
13591
13629
|
}
|
|
13592
13630
|
throw err;
|
|
13593
13631
|
}
|
|
@@ -13727,10 +13765,10 @@ function _parseExplicit(buffer, datasetStart, ctx, emit, mode, opts = {}) {
|
|
|
13727
13765
|
continue;
|
|
13728
13766
|
}
|
|
13729
13767
|
if (length === UNDEFINED_LENGTH2) {
|
|
13730
|
-
throw undefinedLengthOnNonSqExplicit(
|
|
13768
|
+
throw undefinedLengthOnNonSqExplicit(ctx.frame, headerStart, vr);
|
|
13731
13769
|
}
|
|
13732
13770
|
if (cursor.position + length > buffer.length) {
|
|
13733
|
-
throw elementLengthExceedsBuffer(
|
|
13771
|
+
throw elementLengthExceedsBuffer(ctx.frame, headerStart);
|
|
13734
13772
|
}
|
|
13735
13773
|
const valueStart = cursor.position;
|
|
13736
13774
|
const valueEnd = valueStart + length;
|
|
@@ -13791,11 +13829,14 @@ function parseDeflatedLEWithCap(buffer, datasetStart, ctx, emit, maxInflatedByte
|
|
|
13791
13829
|
const code = errAny.code;
|
|
13792
13830
|
const message = errAny.message ?? String(err);
|
|
13793
13831
|
if (code === "ERR_BUFFER_TOO_LARGE" || err instanceof RangeError && /maxOutputLength|too large/i.test(message)) {
|
|
13794
|
-
throw inflatedPayloadExceedsCap(
|
|
13832
|
+
throw inflatedPayloadExceedsCap(ctx.frame, datasetStart, maxInflatedBytes);
|
|
13795
13833
|
}
|
|
13796
|
-
throw inflateFailed(
|
|
13834
|
+
throw inflateFailed(ctx.frame, datasetStart, code);
|
|
13797
13835
|
}
|
|
13798
|
-
const innerCtx = {
|
|
13836
|
+
const innerCtx = {
|
|
13837
|
+
...ctx,
|
|
13838
|
+
frame: { buffer: inflated, name: OFFSET_FRAMES.INFLATED_DATASET }
|
|
13839
|
+
};
|
|
13799
13840
|
const innerChokepoint = makeEmitter(innerCtx);
|
|
13800
13841
|
const innerEmit = (w) => {
|
|
13801
13842
|
const wrapped = {
|
|
@@ -13845,7 +13886,7 @@ function parseDicom(input, options = {}) {
|
|
|
13845
13886
|
const tsUid = fileMeta.transferSyntaxUID;
|
|
13846
13887
|
const strategy = TRANSFER_SYNTAX_PARSERS[tsUid];
|
|
13847
13888
|
if (strategy === void 0) {
|
|
13848
|
-
throw unsupportedTransferSyntax(
|
|
13889
|
+
throw unsupportedTransferSyntax(ctx.frame, fileMetaEnd, tsUid);
|
|
13849
13890
|
}
|
|
13850
13891
|
const { elements } = strategy(buffer, fileMetaEnd, ctx, emit);
|
|
13851
13892
|
return new Dataset({ fileMeta, warnings: ctx.warnings, elements });
|
|
@@ -13863,7 +13904,9 @@ function normalizeInput(input) {
|
|
|
13863
13904
|
}
|
|
13864
13905
|
function buildContext(buffer, options, warnings) {
|
|
13865
13906
|
const base = {
|
|
13866
|
-
|
|
13907
|
+
// The root frame. Every nested frame is entered from here by a swap that
|
|
13908
|
+
// moves the bytes and the name together; see `ParseFrame`.
|
|
13909
|
+
frame: { buffer, name: OFFSET_FRAMES.INPUT },
|
|
13867
13910
|
strict: options.strict === true,
|
|
13868
13911
|
stripPreamble: options.stripPreamble ?? "tolerate",
|
|
13869
13912
|
warnings,
|
|
@@ -15913,6 +15956,7 @@ exports.Dictionary = dictionary_exports;
|
|
|
15913
15956
|
exports.Element = Element;
|
|
15914
15957
|
exports.FATAL_CODES = FATAL_CODES;
|
|
15915
15958
|
exports.Item = Item;
|
|
15959
|
+
exports.OFFSET_FRAMES = OFFSET_FRAMES;
|
|
15916
15960
|
exports.ProfileDefinitionError = ProfileDefinitionError;
|
|
15917
15961
|
exports.SERIALIZE_ERROR_CODES = SERIALIZE_ERROR_CODES;
|
|
15918
15962
|
exports.Sequence = Sequence;
|