@cosyte/dicom 0.0.13 → 0.0.15

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/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.13";
14
+ var VERSION = "0.0.15";
15
15
 
16
16
  // src/dictionary/index.ts
17
17
  var dictionary_exports = {};
@@ -11787,6 +11787,11 @@ function safePrivateCreator(creator, profile) {
11787
11787
  function renderVr(vr) {
11788
11788
  return vr !== void 0 && KNOWN_VRS.has(vr) ? vr : WITHHELD;
11789
11789
  }
11790
+ var TAG_SHAPE = /^[0-9A-F]{8}$/u;
11791
+ function renderTag(tag) {
11792
+ if (tag === void 0 || !TAG_SHAPE.test(tag)) return WITHHELD;
11793
+ return lookup(tag) === void 0 ? WITHHELD : tag;
11794
+ }
11790
11795
 
11791
11796
  // src/parser/fatals.ts
11792
11797
  var SUPPORTED_TRANSFER_SYNTAXES = "1.2.840.10008.1.2, 1.2.840.10008.1.2.1, 1.2.840.10008.1.2.2, 1.2.840.10008.1.2.1.99";
@@ -11835,7 +11840,7 @@ var FATAL_MESSAGES = Object.freeze({
11835
11840
  // four bytes are not what they claim to be.
11836
11841
  FILE_META_GROUP_LENGTH_OVERRUNS: {
11837
11842
  code: FATAL_CODES.INVALID_FILE_META,
11838
- message: "(0002,0000) FileMetaInformationGroupLength declares more bytes than remain in the input; {n} bytes remain. The declared length is withheld; the byte offset locates the group."
11843
+ 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."
11839
11844
  },
11840
11845
  FILE_META_TRANSFER_SYNTAX_MISSING: {
11841
11846
  code: FATAL_CODES.INVALID_FILE_META,
@@ -11878,7 +11883,7 @@ var FATAL_MESSAGES = Object.freeze({
11878
11883
  },
11879
11884
  ELEMENT_LENGTH_EXCEEDS_BUFFER: {
11880
11885
  code: FATAL_CODES.INVALID_FILE_META,
11881
- message: "An element declares a Value Length reaching past the end of the bytes being read; {n} bytes remain. Its tag and its declared length are withheld; the byte offset locates it."
11886
+ message: "An element declares a Value Length reaching past the end of the bytes being read. Its tag, its declared length and the count of bytes that remain are withheld; the byte offset locates it."
11882
11887
  },
11883
11888
  UNEXPECTED_TAG_INSIDE_SEQUENCE: {
11884
11889
  code: FATAL_CODES.INVALID_FILE_META,
@@ -11949,8 +11954,8 @@ function unsupportedTransferSyntax(buffer, offset, ts) {
11949
11954
  function fileMetaTruncated(buffer, offset) {
11950
11955
  return at("FILE_META_TRUNCATED", buffer, offset);
11951
11956
  }
11952
- function fileMetaGroupLengthOverruns(buffer, offset, remaining) {
11953
- return at("FILE_META_GROUP_LENGTH_OVERRUNS", buffer, offset, { n: remaining });
11957
+ function fileMetaGroupLengthOverruns(buffer, offset) {
11958
+ return at("FILE_META_GROUP_LENGTH_OVERRUNS", buffer, offset);
11954
11959
  }
11955
11960
  function fileMetaTransferSyntaxMissing(buffer, offset) {
11956
11961
  return at("FILE_META_TRANSFER_SYNTAX_MISSING", buffer, offset);
@@ -11979,8 +11984,8 @@ function undefinedLengthOnNonSqExplicit(buffer, offset, vr) {
11979
11984
  function undefinedLengthOnNonSqImplicit(buffer, offset, vr) {
11980
11985
  return at("UNDEFINED_LENGTH_ON_NON_SQ_IMPLICIT", buffer, offset, { vr });
11981
11986
  }
11982
- function elementLengthExceedsBuffer(buffer, offset, remaining) {
11983
- return at("ELEMENT_LENGTH_EXCEEDS_BUFFER", buffer, offset, { n: remaining });
11987
+ function elementLengthExceedsBuffer(buffer, offset) {
11988
+ return at("ELEMENT_LENGTH_EXCEEDS_BUFFER", buffer, offset);
11984
11989
  }
11985
11990
  function unexpectedTagInsideSequence(buffer, offset) {
11986
11991
  return at("UNEXPECTED_TAG_INSIDE_SEQUENCE", buffer, offset);
@@ -12206,15 +12211,38 @@ var WARNING_MESSAGES = Object.freeze({
12206
12211
  DICOM_FILE_META_GROUP_LENGTH_MISSING: "(0002,0000) FileMetaInformationGroupLength missing; scanning forward to first non-(0002,xxxx) element.",
12207
12212
  DICOM_FILE_META_GROUP_LENGTH_MISMATCH: "(0002,0000) FileMetaInformationGroupLength declared {n} bytes; actual File Meta group size is {n2} bytes. Trusting actual.",
12208
12213
  DICOM_UNDEFINED_LENGTH_IN_EXPLICIT_VR: "Element ({tag}) uses undefined length (0xFFFFFFFF) under an Explicit VR transfer syntax.",
12209
- DICOM_ODD_LENGTH_VALUE_PADDED: "Element ({tag}) has odd declared length {n}; cursor advanced by one padding byte to maintain alignment.",
12214
+ // The declared length is gone from this string and the reason is measured, not
12215
+ // cautious: this code fires on ANY element header, including one a lying Value
12216
+ // Length upstream composed out of somebody's value, and it then rendered four
12217
+ // payload bytes as {tag} and four more as the decimal {n} - eight consecutive
12218
+ // bytes of a name in one message. See `oddLengthValuePadded`.
12219
+ DICOM_ODD_LENGTH_VALUE_PADDED: "Element ({tag}) has an odd declared length; cursor advanced by one padding byte to maintain alignment. The declared length is withheld; the byte offset identifies the element.",
12210
12220
  DICOM_VR_MISMATCH: "Element ({tag}) on-wire VR is {vr2}; dictionary lists {vr}. Trusting on-wire VR.",
12211
- DICOM_PRIVATE_TAG_NO_CREATOR: "Private element ({tag}) has no Private Creator registered for its block; treating as VR=UN.",
12212
- DICOM_GROUP_LENGTH_IN_DATASET: "Retired Group Length element ({tag}) encountered in dataset; preserved as-is.",
12221
+ // No tag, and the reason is the one `nonzeroReservedBytes` states: this code's
12222
+ // three siblings below fire only on an ODD group, and an odd group is the one
12223
+ // class of tag no closed table this library holds can ever vouch for. See
12224
+ // `privateTagNoCreator`.
12225
+ DICOM_PRIVATE_TAG_NO_CREATOR: "A private element has no Private Creator registered for its block; treating as VR=UN. Its tag is withheld; the byte offset identifies the element.",
12226
+ // No tag, and it is the membership bound in `renderTag` that made the slot
12227
+ // dead rather than a judgement here: this code fires on a (gggg,0000), the
12228
+ // element number is a constant of the code, and PS3.6 carries a literal row
12229
+ // for exactly one such tag - (0002,0000), which is File Meta and never
12230
+ // reaches this code. So every tag this slot could ever have rendered was one
12231
+ // no closed table names, leaving the group number as sixteen free bits of a
12232
+ // header that may itself be fabricated. See `groupLengthInDataset`.
12233
+ DICOM_GROUP_LENGTH_IN_DATASET: "A retired Group Length element (gggg,0000) was encountered in the dataset; preserved as-is. Its group number is withheld; the byte offset identifies the element.",
12213
12234
  // The tag is deliberately absent, and this is the only *parser* message where
12214
12235
  // that is true. See `nonzeroReservedBytes`. Kept terse for the same reason the
12215
12236
  // de-identify messages are: it is emitted once per element, and element count
12216
12237
  // is attacker-chosen.
12217
- DICOM_NONZERO_RESERVED_BYTES: "Non-zero reserved bytes between VR and length (first byte {n}, second byte {n2}); ignoring. Tag withheld; the byte offset identifies the element.",
12238
+ // 🩺 THE TWO BYTE VALUES ARE GONE FOR THE REASON THE TAG WAS ALREADY GONE, AND
12239
+ // LEAVING THEM MADE THAT BOUND HALF A BOUND. This code's trigger is "these two
12240
+ // bytes are not what PS3.5 7.1.2 says they must be", so the header may not be
12241
+ // a header - and then the reserved pair is two bytes from inside some
12242
+ // element's value, printed as two decimals that reverse with no work at all.
12243
+ // Measured on a name-bearing payload across six under-declare deltas. See
12244
+ // `nonzeroReservedBytes`.
12245
+ DICOM_NONZERO_RESERVED_BYTES: "Non-zero reserved bytes between VR and length; ignoring. Their two values are withheld with the tag; the byte offset identifies the element.",
12218
12246
  DICOM_SQ_NOT_DESCENDED: "Element ({tag}) resolved to VR=SQ from the dictionary but its defined-length value is not a valid item stream; kept as opaque bytes and NOT descended, so nothing nested inside it is visible to navigation, and deidentify() cannot audit it. See DICOM_DEIDENT_SEQUENCE_NOT_AUDITABLE.",
12219
12247
  DICOM_UN_PARSED_AS_SQ: "Element ({tag}) has VR=UN with undefined length; descended as Implicit VR LE sequence per CP-246.",
12220
12248
  DICOM_EMPTY_ITEM_IN_SEQUENCE: "Sequence ({tag}) contains an empty item (length=0); tolerated.",
@@ -12249,15 +12277,22 @@ var WARNING_MESSAGES = Object.freeze({
12249
12277
  // No value and no length, for the same reason as the code above: the retained
12250
12278
  // text is the file's own. The tag is a constant of this code.
12251
12279
  DICOM_DEIDENT_METHOD_PRIOR_RETAINED: "A De-identification Method (0012,0063) value the source file already carried was kept beside the one this run recorded, as PS3.15 E.1.1 requires. That attribute is not in Table E.1-1, so no rule in this run inspected, audited or redacted those bytes: if the sender wrote identifying text there it is in the de-identified output, under (0012,0062) = YES. The text is withheld from this message.",
12252
- // The Item's own declared length is deliberately absent. See
12253
- // `itemCrossesSequenceEnd`; `{n2}` stays because the emit site's
12254
- // `endLimit < buffer.length` conjunct bounds it by the buffer.
12255
- DICOM_ITEM_CROSSES_SEQUENCE_END: "Item ({tag}) declares a length reaching past its enclosing sequence's declared end, so it reads the enclosing Data Set's bytes; {n2} bytes remained inside the sequence. The file's two length fields disagree (PS3.5 7.5.1 and 7.5.2 govern them); the item's is used. The declared length is withheld; the byte offset locates the item.",
12256
- DICOM_PIXEL_DATA_LENGTH_MISMATCH: "(7FE0,0010) PixelData declared length {n} does not match computed {n2} bytes.",
12257
- DICOM_IMPLICIT_VR_FOR_PRIVATE_TAG_WITHOUT_VR: "Private element ({tag}) under Implicit VR LE has no VR override; falling back to UN.",
12258
- DICOM_PRIVATE_CREATOR_UNKNOWN: "Private element ({tag}) has a Private Creator the active profile's private dictionary does not name; falling back to UN. The creator string is not reproduced here - read the (gggg,00EE) element if you need it.",
12280
+ // BOTH of the disagreeing length fields are deliberately absent, and the
12281
+ // second one is the eighth instance of `DICOM-DIAGNOSTIC-PHI-RESIDUALS`: the
12282
+ // remaining-bytes count this string used to carry was the enclosing sequence's
12283
+ // declared Value Length less the bytes of that sequence already consumed. See
12284
+ // `itemCrossesSequenceEnd`.
12285
+ DICOM_ITEM_CROSSES_SEQUENCE_END: "Item ({tag}) declares a length reaching past its enclosing sequence's declared end, so it reads the enclosing Data Set's bytes. The file's two length fields disagree (PS3.5 7.5.1 and 7.5.2 govern them); the item's is used. Both declared lengths are withheld; the byte offset locates the item.",
12286
+ // Declared but not emitted by this build. The declared length is bound out
12287
+ // anyway: it is a raw 32-bit read off a header, so activating this code later
12288
+ // with the slot still here would ship the leak this slice closed one code
12289
+ // over. `{n2}` stays - it is the product this parser computed from the image
12290
+ // description attributes, not a number it read. The tag is a constant.
12291
+ DICOM_PIXEL_DATA_LENGTH_MISMATCH: "(7FE0,0010) PixelData declared length does not match the computed {n2} bytes. The declared length is withheld; the byte offset identifies the element.",
12292
+ DICOM_IMPLICIT_VR_FOR_PRIVATE_TAG_WITHOUT_VR: "A private element under Implicit VR LE has no VR override; falling back to UN. Its tag is withheld; the byte offset identifies the element.",
12293
+ DICOM_PRIVATE_CREATOR_UNKNOWN: "A private element has a Private Creator the active profile's private dictionary does not name; falling back to UN. The creator string is not reproduced here - read the (gggg,00EE) element if you need it. Its tag is withheld; the byte offset identifies the element.",
12259
12294
  DICOM_BURNED_IN_ANNOTATION_NOT_REMOVED: "Pixel Data is present and Burned In Annotation is not 'NO'; this metadata-only de-identifier cannot inspect or clean pixels. Recognizable text may remain burned into the image.",
12260
- DICOM_DEIDENT_EMBEDDED_ATTRIBUTE_REMOVED: "Element ({tag}) {vr} was kept by the action table, but its value ends with {n} whole Data Element(s) - an over-declared Value Length swallowed what followed it. Emptied rather than kept, because the action table cannot see an attribute encoded inside a value. Read report.embeddedAttributes for the tags that were hidden there.",
12295
+ DICOM_DEIDENT_EMBEDDED_ATTRIBUTE_REMOVED: "Element ({tag}) {vr} was kept by the action table, but its value ends with {n} whole Data Element(s) - an over-declared Value Length swallowed what followed it. Emptied rather than kept, because the action table cannot see an attribute encoded inside a value. report.embeddedAttributes names the ones this run acts on that also have a literal Table E.1-1 row, which may be none of them.",
12261
12296
  // Deliberately short. One of these is raised per un-auditable element, so a
12262
12297
  // long message is multiplied by an element count the input controls; the
12263
12298
  // reasoning belongs in the docs, not in a string repeated thousands of times.
@@ -12265,19 +12300,31 @@ var WARNING_MESSAGES = Object.freeze({
12265
12300
  // its two producers is an element the profile declares a Sequence while the
12266
12301
  // wire says UN or OB, so naming a VR here would state a fact about the file
12267
12302
  // that the file contradicts - on the one channel this class designates.
12268
- DICOM_DEIDENT_SEQUENCE_NOT_AUDITABLE: "Element ({tag}) is a Sequence carrier with no parsed items, so its {n} recorded bytes could not be audited (PS3.15 E.1.1); emptied. See report.unauditableSequences.",
12303
+ // The recorded byte count is gone from this string, and the reason is the same
12304
+ // one that took the declared length out of `DICOM_ODD_LENGTH_VALUE_PADDED`:
12305
+ // `Element.rawBytes.length` EQUALS the Value Length off the element header, so
12306
+ // when that header is fabricated the decimal is four document bytes. See
12307
+ // `sequenceNotAuditable`. `report.unauditableSequences[].byteLength` still
12308
+ // carries it, on a type documented as not value-free.
12309
+ DICOM_DEIDENT_SEQUENCE_NOT_AUDITABLE: "Element ({tag}) is a Sequence carrier with no parsed items, so its recorded bytes could not be audited (PS3.15 E.1.1); emptied. The byte count is withheld; see report.unauditableSequences.",
12269
12310
  // Deliberately short for the same reason as the code above: one per element,
12270
12311
  // and the element count is chosen by the input.
12271
12312
  //
12272
- // NEITHER THE TAG NOR THE VR IS ECHOED, and that is specific to this code
12273
- // rather than caution. Every other factory's {tag} is composed from a real
12274
- // Data Element header; the condition that raises THIS one is that the header
12275
- // was fabricated from bytes inside some element's value, so its four tag bytes
12276
- // and its two VR bytes are document content. `renderTag` shape-checks a tag
12277
- // and cannot refuse one, so the withholding has to happen at the call site.
12313
+ // NEITHER THE TAG NOR THE VR NOR THE BYTE COUNT IS ECHOED, and that is
12314
+ // specific to this code rather than caution. Every other factory's {tag} is
12315
+ // composed from a real Data Element header; the condition that raises THIS one
12316
+ // is that the header was fabricated from bytes inside some element's value, so
12317
+ // its four tag bytes, its two VR bytes AND its four length bytes are document
12318
+ // content. `renderTag` is a membership test against PS3.6's registry and would
12319
+ // refuse this one - but a slot that has to rely on that is a slot a future
12320
+ // call site can still be handed, so the withholding stays at the call site
12321
+ // where it does not depend on a table. The length had no table to fall back on
12322
+ // at all: the message withheld the two fields a renderer could check and then
12323
+ // printed the one it could not, which is the shape this code was already
12324
+ // written to refuse.
12278
12325
  // The byte offset locates the element instead, and is a position this parser
12279
12326
  // counted rather than anything the document said.
12280
- DICOM_DEIDENT_UNDEFINED_VR_NOT_AUDITABLE: "An element at byte offset {n2} carries an on-wire VR that is not one of the 34 PS3.5 6.2 defines, so its {n} value bytes are not a Value Field this library decoded; emptied (PS3.15 E.1.1). Its tag and VR are withheld: an earlier under-declared length can make them fragments of some element's value. See report.undefinedVrElements.",
12327
+ DICOM_DEIDENT_UNDEFINED_VR_NOT_AUDITABLE: "An element at byte offset {n2} carries an on-wire VR that is not one of the 34 PS3.5 6.2 defines, so its value bytes are not a Value Field this library decoded; emptied (PS3.15 E.1.1). Its tag, VR and byte count are withheld: an earlier under-declared length can make them fragments of some element's value. See report.undefinedVrElements.",
12281
12328
  DICOM_BOM_IN_TEXT_VR: "Element ({tag}) {vr} value begins with a UTF-8 BOM; stripped on decode.",
12282
12329
  DICOM_TRAILING_NULL_IN_TEXT_VR: "Element ({tag}) {vr} value has a trailing NULL pad where SPACE is expected; trimmed.",
12283
12330
  DICOM_UI_TRAILING_SPACE: "Element ({tag}) UI value is SPACE-padded; UI requires NULL padding (PS3.5 \xA76.2). Trimmed.",
@@ -12288,10 +12335,6 @@ var WARNING_MESSAGES = Object.freeze({
12288
12335
  DICOM_UNSUPPORTED_CHARSET: "(0008,0005) Specific Character Set value {n} names a defined term this build does not support; decoding text as UTF-8 best-effort. The term is not reproduced here - read the element if you need it.",
12289
12336
  DICOM_CHARSET_AMBIGUOUS_SEPARATOR: "(0008,0005) Specific Character Set value {n} is ambiguous under the active code extensions; decoding text as UTF-8 best-effort."
12290
12337
  });
12291
- var TAG_SHAPE = /^[0-9A-F]{8}$/u;
12292
- function renderTag(tag) {
12293
- return tag !== void 0 && TAG_SHAPE.test(tag) ? tag : WITHHELD;
12294
- }
12295
12338
  function build2(code, position, tokens = {}) {
12296
12339
  const message = WARNING_MESSAGES[code].replace("{tag}", renderTag(tokens.tag)).replace("{vr2}", renderVr(tokens.vr2)).replace("{vr}", renderVr(tokens.vr)).replace("{n2}", String(tokens.n2 ?? 0)).replace("{n}", String(tokens.n ?? 0));
12297
12340
  return { code, message, position };
@@ -12311,26 +12354,20 @@ function fileMetaGroupLengthMismatch(position, declared, actual) {
12311
12354
  function undefinedLengthInExplicitVR(position, tag) {
12312
12355
  return build2(WARNING_CODES.DICOM_UNDEFINED_LENGTH_IN_EXPLICIT_VR, position, { tag });
12313
12356
  }
12314
- function oddLengthValuePadded(position, tag, declaredLength) {
12315
- return build2(WARNING_CODES.DICOM_ODD_LENGTH_VALUE_PADDED, position, {
12316
- tag,
12317
- n: declaredLength
12318
- });
12357
+ function oddLengthValuePadded(position, tag) {
12358
+ return build2(WARNING_CODES.DICOM_ODD_LENGTH_VALUE_PADDED, position, { tag });
12319
12359
  }
12320
12360
  function vrMismatch(position, tag, dictVR, fileVR) {
12321
12361
  return build2(WARNING_CODES.DICOM_VR_MISMATCH, position, { tag, vr: dictVR, vr2: fileVR });
12322
12362
  }
12323
- function privateTagNoCreator(position, tag) {
12324
- return build2(WARNING_CODES.DICOM_PRIVATE_TAG_NO_CREATOR, position, { tag });
12363
+ function privateTagNoCreator(position) {
12364
+ return build2(WARNING_CODES.DICOM_PRIVATE_TAG_NO_CREATOR, position);
12325
12365
  }
12326
- function groupLengthInDataset(position, tag) {
12327
- return build2(WARNING_CODES.DICOM_GROUP_LENGTH_IN_DATASET, position, { tag });
12366
+ function groupLengthInDataset(position) {
12367
+ return build2(WARNING_CODES.DICOM_GROUP_LENGTH_IN_DATASET, position);
12328
12368
  }
12329
- function nonzeroReservedBytes(position, first, second) {
12330
- return build2(WARNING_CODES.DICOM_NONZERO_RESERVED_BYTES, position, {
12331
- n: first,
12332
- n2: second
12333
- });
12369
+ function nonzeroReservedBytes(position) {
12370
+ return build2(WARNING_CODES.DICOM_NONZERO_RESERVED_BYTES, position);
12334
12371
  }
12335
12372
  function unParsedAsSQ(position, tag) {
12336
12373
  return build2(WARNING_CODES.DICOM_UN_PARSED_AS_SQ, position, { tag });
@@ -12338,11 +12375,8 @@ function unParsedAsSQ(position, tag) {
12338
12375
  function sqNotDescended(position, tag) {
12339
12376
  return build2(WARNING_CODES.DICOM_SQ_NOT_DESCENDED, position, { tag });
12340
12377
  }
12341
- function itemCrossesSequenceEnd(position, tag, availableLength) {
12342
- return build2(WARNING_CODES.DICOM_ITEM_CROSSES_SEQUENCE_END, position, {
12343
- tag,
12344
- n2: availableLength
12345
- });
12378
+ function itemCrossesSequenceEnd(position, tag) {
12379
+ return build2(WARNING_CODES.DICOM_ITEM_CROSSES_SEQUENCE_END, position, { tag });
12346
12380
  }
12347
12381
  function emptyItemInSequence(position, tag) {
12348
12382
  return build2(WARNING_CODES.DICOM_EMPTY_ITEM_IN_SEQUENCE, position, { tag });
@@ -12353,11 +12387,11 @@ function duplicateTagInDataSet(position) {
12353
12387
  function duplicateFileMetaElement(position) {
12354
12388
  return build2(WARNING_CODES.DICOM_DUPLICATE_FILE_META_ELEMENT, position);
12355
12389
  }
12356
- function implicitVRForPrivateTagWithoutVR(position, tag) {
12357
- return build2(WARNING_CODES.DICOM_IMPLICIT_VR_FOR_PRIVATE_TAG_WITHOUT_VR, position, { tag });
12390
+ function implicitVRForPrivateTagWithoutVR(position) {
12391
+ return build2(WARNING_CODES.DICOM_IMPLICIT_VR_FOR_PRIVATE_TAG_WITHOUT_VR, position);
12358
12392
  }
12359
- function privateCreatorUnknown(position, tag) {
12360
- return build2(WARNING_CODES.DICOM_PRIVATE_CREATOR_UNKNOWN, position, { tag });
12393
+ function privateCreatorUnknown(position) {
12394
+ return build2(WARNING_CODES.DICOM_PRIVATE_CREATOR_UNKNOWN, position);
12361
12395
  }
12362
12396
  function burnedInAnnotationNotRemoved(position) {
12363
12397
  return build2(WARNING_CODES.DICOM_BURNED_IN_ANNOTATION_NOT_REMOVED, position);
@@ -12378,15 +12412,11 @@ function embeddedAttributeRemoved(position, tag, vr, count) {
12378
12412
  n: count
12379
12413
  });
12380
12414
  }
12381
- function sequenceNotAuditable(position, tag, byteLength) {
12382
- return build2(WARNING_CODES.DICOM_DEIDENT_SEQUENCE_NOT_AUDITABLE, position, {
12383
- tag,
12384
- n: byteLength
12385
- });
12415
+ function sequenceNotAuditable(position, tag) {
12416
+ return build2(WARNING_CODES.DICOM_DEIDENT_SEQUENCE_NOT_AUDITABLE, position, { tag });
12386
12417
  }
12387
- function undefinedVrNotAuditable(position, byteLength) {
12418
+ function undefinedVrNotAuditable(position) {
12388
12419
  return build2(WARNING_CODES.DICOM_DEIDENT_UNDEFINED_VR_NOT_AUDITABLE, position, {
12389
- n: byteLength,
12390
12420
  n2: position.byteOffset
12391
12421
  });
12392
12422
  }
@@ -12462,18 +12492,18 @@ function resolveImplicitVR(tag, ctx, emit, position) {
12462
12492
  }
12463
12493
  const creator = resolvePrivateCreator(tag, ctx);
12464
12494
  if (creator === void 0) {
12465
- emit(privateTagNoCreator(position, tag));
12466
- emit(implicitVRForPrivateTagWithoutVR(position, tag));
12495
+ emit(privateTagNoCreator(position));
12496
+ emit(implicitVRForPrivateTagWithoutVR(position));
12467
12497
  return "UN";
12468
12498
  }
12469
12499
  if (ctx.profile !== void 0) {
12470
12500
  const def = resolvePrivateTag(ctx.profile, tag, creator);
12471
12501
  if (def !== void 0) return def.vr;
12472
12502
  if (!ctx.profile.privateDictionary.has(creator)) {
12473
- emit(privateCreatorUnknown(position, tag));
12503
+ emit(privateCreatorUnknown(position));
12474
12504
  }
12475
12505
  }
12476
- emit(implicitVRForPrivateTagWithoutVR(position, tag));
12506
+ emit(implicitVRForPrivateTagWithoutVR(position));
12477
12507
  return "UN";
12478
12508
  }
12479
12509
  const direct = TAGS[tag];
@@ -12557,7 +12587,7 @@ function readExplicitElementHeader(cursor, _ctx, emit) {
12557
12587
  const reserved1 = cursor.buffer[cursor.position + 1];
12558
12588
  cursor.position += 2;
12559
12589
  if ((reserved0 ?? 0) !== 0 || (reserved1 ?? 0) !== 0) {
12560
- emit(nonzeroReservedBytes({ byteOffset: headerStart }, reserved0 ?? 0, reserved1 ?? 0));
12590
+ emit(nonzeroReservedBytes({ byteOffset: headerStart }));
12561
12591
  }
12562
12592
  length = cursor.readUInt32();
12563
12593
  headerLength = 12;
@@ -12597,7 +12627,7 @@ function parseFileMeta(buffer$1, datasetStart, ctx, emit) {
12597
12627
  if (firstElement.tag === "00020000" && firstElement.vr === "UL" && firstElement.value.length === 4) {
12598
12628
  declaredFmLength = firstElement.value.readUInt32LE(0);
12599
12629
  if (cursor.position + declaredFmLength > buffer$1.length) {
12600
- throw fileMetaGroupLengthOverruns(buffer$1, fmStart, buffer$1.length - cursor.position);
12630
+ throw fileMetaGroupLengthOverruns(buffer$1, fmStart);
12601
12631
  }
12602
12632
  } else {
12603
12633
  emit(fileMetaGroupLengthMissing({ byteOffset: fmStart, fileMeta: true }));
@@ -13236,13 +13266,7 @@ function parseSequence(buffer, valueStart, ctx, emit, opts) {
13236
13266
  cursor.position = inner.endOffset;
13237
13267
  } else {
13238
13268
  if (opts.explicitLength !== void 0 && endLimit < buffer.length && cursor.position + itemLength > endLimit) {
13239
- emit(
13240
- itemCrossesSequenceEnd(
13241
- { byteOffset: itemHeaderStart },
13242
- itemTag,
13243
- Math.max(0, endLimit - cursor.position)
13244
- )
13245
- );
13269
+ emit(itemCrossesSequenceEnd({ byteOffset: itemHeaderStart }, itemTag));
13246
13270
  }
13247
13271
  if (cursor.position + itemLength > buffer.length) {
13248
13272
  throw itemLengthExceedsBuffer(buffer, itemHeaderStart);
@@ -13440,7 +13464,7 @@ function parseImplicitLE(buffer, datasetStart, ctx, emit, opts = {}) {
13440
13464
  throw undefinedLengthOnNonSqImplicit(buffer, headerStart, vr);
13441
13465
  }
13442
13466
  if (cursor.position + length > buffer.length) {
13443
- throw elementLengthExceedsBuffer(buffer, headerStart, buffer.length - cursor.position);
13467
+ throw elementLengthExceedsBuffer(buffer, headerStart);
13444
13468
  }
13445
13469
  const valueStart = cursor.position;
13446
13470
  const valueEnd = valueStart + length;
@@ -13477,7 +13501,7 @@ function parseImplicitLE(buffer, datasetStart, ctx, emit, opts = {}) {
13477
13501
  }
13478
13502
  }
13479
13503
  if (element === 0 && group !== 2) {
13480
- emit(groupLengthInDataset(position, tag));
13504
+ emit(groupLengthInDataset(position));
13481
13505
  }
13482
13506
  if (group % 2 === 1 && element >= 16 && element <= 255) {
13483
13507
  registerPrivateCreator(tag, valueSlice, ctx);
@@ -13560,7 +13584,7 @@ function _parseExplicit(buffer, datasetStart, ctx, emit, mode, opts = {}) {
13560
13584
  }
13561
13585
  }
13562
13586
  if (length !== UNDEFINED_LENGTH2 && length % 2 === 1) {
13563
- emit(oddLengthValuePadded(position, tag, length));
13587
+ emit(oddLengthValuePadded(position, tag));
13564
13588
  }
13565
13589
  if (vr === "SQ") {
13566
13590
  const valueStart2 = cursor.position;
@@ -13687,7 +13711,7 @@ function _parseExplicit(buffer, datasetStart, ctx, emit, mode, opts = {}) {
13687
13711
  throw undefinedLengthOnNonSqExplicit(buffer, headerStart, vr);
13688
13712
  }
13689
13713
  if (cursor.position + length > buffer.length) {
13690
- throw elementLengthExceedsBuffer(buffer, headerStart, buffer.length - cursor.position);
13714
+ throw elementLengthExceedsBuffer(buffer, headerStart);
13691
13715
  }
13692
13716
  const valueStart = cursor.position;
13693
13717
  const valueEnd = valueStart + length;
@@ -13695,7 +13719,7 @@ function _parseExplicit(buffer, datasetStart, ctx, emit, mode, opts = {}) {
13695
13719
  cursor.position = valueEnd;
13696
13720
  const elementHexNum = parseInt(tag.slice(4, 8), 16);
13697
13721
  if (elementHexNum === 0 && groupNum !== 2) {
13698
- emit(groupLengthInDataset(position, tag));
13722
+ emit(groupLengthInDataset(position));
13699
13723
  }
13700
13724
  if (groupNum % 2 === 1 && elementHexNum >= 16 && elementHexNum <= 255) {
13701
13725
  registerPrivateCreator(tag, valueSlice, ctx);
@@ -15225,6 +15249,10 @@ function hasByteOutsideRepertoire(region, carrierVr) {
15225
15249
  }
15226
15250
  return false;
15227
15251
  }
15252
+ function isTableBound(tag) {
15253
+ const action = annexE(tag);
15254
+ return action !== void 0 && action.repeatingGroup === void 0;
15255
+ }
15228
15256
  function findEmbeddedAttributes(value, carrierVr, encoding, isActionable) {
15229
15257
  if (!isScannableCarrier(carrierVr)) return void 0;
15230
15258
  if (value.length < MIN_HEADER) return void 0;
@@ -15248,15 +15276,19 @@ function findEmbeddedAttributes(value, carrierVr, encoding, isActionable) {
15248
15276
  for (let off = 0; off + MIN_HEADER <= n; off += 2) {
15249
15277
  if (hit[off >> 1] !== 1) continue;
15250
15278
  if (!hasByteOutsideRepertoire(window.subarray(off), carrierVr)) return void 0;
15251
- const tags = [];
15279
+ const hidden = [];
15280
+ let elementCount = 0;
15252
15281
  let pos = off;
15253
15282
  while (pos < n) {
15254
15283
  const decoded = decodeAt(window, pos, encoding);
15255
15284
  if (decoded === void 0) break;
15256
- if (decoded.tag !== void 0) tags.push(decoded.tag);
15285
+ if (decoded.tag !== void 0) {
15286
+ elementCount += 1;
15287
+ if (isActionable(decoded.tag) && isTableBound(decoded.tag)) hidden.push(decoded.tag);
15288
+ }
15257
15289
  pos = decoded.next;
15258
15290
  }
15259
- return tags;
15291
+ return { hidden, elementCount };
15260
15292
  }
15261
15293
  return void 0;
15262
15294
  }
@@ -15461,8 +15493,8 @@ function keepOrEmpty(el, ctx, contextPath, out) {
15461
15493
  emptyUndefinedVrElement(el, ctx, contextPath, out);
15462
15494
  return false;
15463
15495
  }
15464
- const hidden = findEmbeddedAttributes(el.rawBytes, el.vr, ctx.encoding, (t) => actsOnTag(t, ctx));
15465
- if (hidden === void 0) {
15496
+ const run = findEmbeddedAttributes(el.rawBytes, el.vr, ctx.encoding, (t) => actsOnTag(t, ctx));
15497
+ if (run === void 0) {
15466
15498
  out.elements.set(el.tag, el);
15467
15499
  return true;
15468
15500
  }
@@ -15470,11 +15502,11 @@ function keepOrEmpty(el, ctx, contextPath, out) {
15470
15502
  out.embeddedAttributes.push({
15471
15503
  tag: el.tag,
15472
15504
  vr: el.vr,
15473
- hidden,
15505
+ hidden: run.hidden,
15474
15506
  ...contextPath.length > 0 ? { contextPath: [...contextPath] } : {}
15475
15507
  });
15476
15508
  out.warnings.push(
15477
- embeddedAttributeRemoved({ byteOffset: el.byteOffset }, el.tag, el.vr, hidden.length)
15509
+ embeddedAttributeRemoved({ byteOffset: el.byteOffset }, el.tag, el.vr, run.elementCount)
15478
15510
  );
15479
15511
  return false;
15480
15512
  }
@@ -15487,7 +15519,7 @@ function emptyUndefinedVrElement(el, ctx, contextPath, out) {
15487
15519
  byteLength: el.rawBytes.length,
15488
15520
  ...contextPath.length > 0 ? { contextPath: [...contextPath] } : {}
15489
15521
  });
15490
- out.warnings.push(undefinedVrNotAuditable({ byteOffset: el.byteOffset }, el.rawBytes.length));
15522
+ out.warnings.push(undefinedVrNotAuditable({ byteOffset: el.byteOffset }));
15491
15523
  }
15492
15524
  function isUnauditableSequence(el) {
15493
15525
  return el.vr === "SQ" && el.items === void 0;
@@ -15504,9 +15536,7 @@ function emptyUnauditableCarrier(el, ctx, contextPath, out, replacement) {
15504
15536
  byteLength: el.rawBytes.length,
15505
15537
  ...contextPath.length > 0 ? { contextPath: [...contextPath] } : {}
15506
15538
  });
15507
- out.warnings.push(
15508
- sequenceNotAuditable({ byteOffset: el.byteOffset }, el.tag, el.rawBytes.length)
15509
- );
15539
+ out.warnings.push(sequenceNotAuditable({ byteOffset: el.byteOffset }, el.tag));
15510
15540
  }
15511
15541
  function creatorsInScope(source) {
15512
15542
  const byBlock = /* @__PURE__ */ new Map();