@cosyte/dicom 0.0.10 → 0.0.11

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.d.cts CHANGED
@@ -391,11 +391,14 @@ interface ParseOptions {
391
391
  * ```
392
392
  */
393
393
  declare const WARNING_CODES: {
394
+ readonly DICOM_DUPLICATE_FILE_META_ELEMENT: "DICOM_DUPLICATE_FILE_META_ELEMENT";
395
+ readonly DICOM_DUPLICATE_TAG_IN_DATA_SET: "DICOM_DUPLICATE_TAG_IN_DATA_SET";
394
396
  readonly DICOM_EMPTY_ITEM_IN_SEQUENCE: "DICOM_EMPTY_ITEM_IN_SEQUENCE";
395
397
  readonly DICOM_FILE_META_GROUP_LENGTH_MISMATCH: "DICOM_FILE_META_GROUP_LENGTH_MISMATCH";
396
398
  readonly DICOM_FILE_META_GROUP_LENGTH_MISSING: "DICOM_FILE_META_GROUP_LENGTH_MISSING";
397
399
  readonly DICOM_GROUP_LENGTH_IN_DATASET: "DICOM_GROUP_LENGTH_IN_DATASET";
398
400
  readonly DICOM_IMPLICIT_VR_FOR_PRIVATE_TAG_WITHOUT_VR: "DICOM_IMPLICIT_VR_FOR_PRIVATE_TAG_WITHOUT_VR";
401
+ readonly DICOM_ITEM_CROSSES_SEQUENCE_END: "DICOM_ITEM_CROSSES_SEQUENCE_END";
399
402
  readonly DICOM_MISSING_PREAMBLE: "DICOM_MISSING_PREAMBLE";
400
403
  readonly DICOM_NONZERO_RESERVED_BYTES: "DICOM_NONZERO_RESERVED_BYTES";
401
404
  readonly DICOM_ODD_LENGTH_VALUE_PADDED: "DICOM_ODD_LENGTH_VALUE_PADDED";
@@ -416,6 +419,8 @@ declare const WARNING_CODES: {
416
419
  readonly DICOM_UNSUPPORTED_CHARSET: "DICOM_UNSUPPORTED_CHARSET";
417
420
  readonly DICOM_BURNED_IN_ANNOTATION_NOT_REMOVED: "DICOM_BURNED_IN_ANNOTATION_NOT_REMOVED";
418
421
  readonly DICOM_DEIDENT_EMBEDDED_ATTRIBUTE_REMOVED: "DICOM_DEIDENT_EMBEDDED_ATTRIBUTE_REMOVED";
422
+ readonly DICOM_DEIDENT_METHOD_NOT_ADDED: "DICOM_DEIDENT_METHOD_NOT_ADDED";
423
+ readonly DICOM_DEIDENT_METHOD_PRIOR_RETAINED: "DICOM_DEIDENT_METHOD_PRIOR_RETAINED";
419
424
  readonly DICOM_DEIDENT_SEQUENCE_NOT_AUDITABLE: "DICOM_DEIDENT_SEQUENCE_NOT_AUDITABLE";
420
425
  readonly DICOM_DEIDENT_UNDEFINED_VR_NOT_AUDITABLE: "DICOM_DEIDENT_UNDEFINED_VR_NOT_AUDITABLE";
421
426
  readonly DICOM_PRIVATE_CREATOR_UNKNOWN: "DICOM_PRIVATE_CREATOR_UNKNOWN";
@@ -2643,7 +2648,15 @@ interface DeidentifyReport {
2643
2648
  readonly uidMap: ReadonlyMap<string, string>;
2644
2649
  /** Safety warnings - notably burned-in-pixel annotation that cannot be cleaned. */
2645
2650
  readonly warnings: readonly DicomParseWarning[];
2646
- /** The Retain/Clean options that were active for this run. */
2651
+ /**
2652
+ * The Retain/Clean options that were active for this run.
2653
+ *
2654
+ * **Not a list of what survived.** Attributes Table E.1-1 does not list are
2655
+ * kept without appearing anywhere in this field - `(0012,0063)`
2656
+ * De-identification Method is the one whose retention is disclosed, and it is
2657
+ * disclosed as `DICOM_DEIDENT_METHOD_PRIOR_RETAINED` on
2658
+ * {@link DeidentifyReport.warnings}, because it is not an option set.
2659
+ */
2647
2660
  readonly retained: readonly DeidentifyOption[];
2648
2661
  }
2649
2662
  /**
@@ -2676,8 +2689,44 @@ interface DeidentifyOptions {
2676
2689
  */
2677
2690
  readonly profile?: Profile;
2678
2691
  /**
2679
- * Text written to `(0012,0063)` De-identification Method. Default names the
2692
+ * Text **added to** `(0012,0063)` De-identification Method. Default names the
2680
2693
  * Basic Profile and the active options.
2694
+ *
2695
+ * PS3.15 E.1.1 says this string is "inserted in or added to" the attribute, so
2696
+ * a value the incoming Data Set already carried is kept and this one is
2697
+ * appended after a `\` as a further value of the `1-n` attribute - the
2698
+ * provenance chain, not a replacement.
2699
+ *
2700
+ * **This string is itself a `1-n` value**: it is split on `\` and only the
2701
+ * values not already recorded are added.
2702
+ *
2703
+ * **Trailing SPACE and NUL are padding, not content** (PS3.5 Table 6.2-1's `LO`
2704
+ * row, which describes a **Value** - and `LO` is `1-n`). They are ignored when
2705
+ * a value here is matched against one already recorded, **per value, on both
2706
+ * sides**, and they are trimmed from the value written. That makes repeated
2707
+ * de-identification a fixed point **from the first pass**, for every string:
2708
+ * with or without a delimiter, and with a pad byte on any value, last or not.
2709
+ * A string that is padding only records nothing. Leading spaces are yours and
2710
+ * are written through untouched.
2711
+ *
2712
+ * One bound, and it is over the value that would be **written**, not over the
2713
+ * join: when that value would exceed the largest Value Length an `LO` can
2714
+ * encode, the prior value is **replaced** rather than added to - an element the
2715
+ * serializer cannot encode would take the whole de-identified object down - and
2716
+ * `report.warnings` carries `DICOM_DEIDENT_METHOD_NOT_ADDED`. That includes a
2717
+ * prior value already at the ceiling which records this method already, where
2718
+ * there is no join to exceed anything. A string longer than that ceiling on its
2719
+ * own is not bounded here and will fail to serialize, exactly as it did before
2720
+ * this option grew a join.
2721
+ *
2722
+ * `DICOM_DEIDENT_METHOD_NOT_ADDED` means "the length ceiling was reached", never
2723
+ * "every fallback is disclosed": a `(0012,0063)` a file encoded under a VR other
2724
+ * than `LO` is also replaced, and that one is silent.
2725
+ *
2726
+ * When the prior value **is** kept, `report.warnings` carries
2727
+ * `DICOM_DEIDENT_METHOD_PRIOR_RETAINED`: `(0012,0063)` is not in Table E.1-1, so
2728
+ * nothing in the run inspected or redacted those bytes, and a name a sender
2729
+ * wrote there is in output stamped `(0012,0062) = YES`.
2681
2730
  */
2682
2731
  readonly deidentificationMethod?: string;
2683
2732
  }
@@ -2775,8 +2824,10 @@ declare class DeidentifyError extends Error {
2775
2824
  * {@link Profile}, keeps the private data elements the profile's overlay names
2776
2825
  * as safe (and the private-creator elements the profile recognizes).
2777
2826
  * - Remaps `(0002,0003)` Media Storage SOP Instance UID consistently (unless
2778
- * `RetainUIDs`), writes `(0012,0062)` Patient Identity Removed = `YES` and
2779
- * `(0012,0063)` De-identification Method, and warns
2827
+ * `RetainUIDs`), writes `(0012,0062)` Patient Identity Removed = `YES`, **adds**
2828
+ * its method text to `(0012,0063)` De-identification Method rather than
2829
+ * replacing what the file already recorded there (PS3.15 E.1.1 - see
2830
+ * `addDeidentificationMethod`), and warns
2780
2831
  * (`DICOM_BURNED_IN_ANNOTATION_NOT_REMOVED`) when Pixel Data is present and not
2781
2832
  * marked free of burned-in annotation - this metadata-only pass cannot clean
2782
2833
  * pixels (deferred to `@cosyte/dicom-pixel`).
@@ -2851,7 +2902,21 @@ declare class DeidentifyError extends Error {
2851
2902
  * private value the sender wrote **outside** the sequence was retained on the
2852
2903
  * Item's reservation and written into output stamped `PatientIdentityRemoved =
2853
2904
  * YES` with `removedPrivateTags: []` (`DICOM-PRIVATE-CREATOR-RESERVATION-LEAK`,
2854
- * live through `0.0.9`). See {@link itemStreamOverrunsSequence}.
2905
+ * measured on the published `0.0.8` tarball and fixed on `0.0.10`; there is no `0.0.9` on
2906
+ * the registry). See {@link itemStreamOverrunsSequence}.
2907
+ * - `RetainSafePrivate` **retains nothing that a Data Set holds after a sequence
2908
+ * whose own contents contradict the extent it declared** - the mirror
2909
+ * direction, where an Item that *under*-declares **ejects** its trailing
2910
+ * elements out and a Private Creator landing in the enclosing Data Set reserves
2911
+ * a block for elements the sender never put beside it. The same false
2912
+ * attestation, and it applies **in every Data Set, not just the root**: an
2913
+ * inner sequence ejecting a creator into the still-usable Item that encloses it
2914
+ * is measured and pinned. The cut is positional, so a reservation the sender
2915
+ * wrote **ahead of** the offending sequence is untouched. Every private element
2916
+ * after that point is removed and named in `report.removedPrivateTags`, and the
2917
+ * **private-`SQ` carve-out above still applies**: a private `SQ` inside the
2918
+ * settled run that the profile vouches for is kept verbatim and never walked.
2919
+ * See {@link settledBound}.
2855
2920
  *
2856
2921
  * @module
2857
2922
  */
package/dist/index.d.ts CHANGED
@@ -391,11 +391,14 @@ interface ParseOptions {
391
391
  * ```
392
392
  */
393
393
  declare const WARNING_CODES: {
394
+ readonly DICOM_DUPLICATE_FILE_META_ELEMENT: "DICOM_DUPLICATE_FILE_META_ELEMENT";
395
+ readonly DICOM_DUPLICATE_TAG_IN_DATA_SET: "DICOM_DUPLICATE_TAG_IN_DATA_SET";
394
396
  readonly DICOM_EMPTY_ITEM_IN_SEQUENCE: "DICOM_EMPTY_ITEM_IN_SEQUENCE";
395
397
  readonly DICOM_FILE_META_GROUP_LENGTH_MISMATCH: "DICOM_FILE_META_GROUP_LENGTH_MISMATCH";
396
398
  readonly DICOM_FILE_META_GROUP_LENGTH_MISSING: "DICOM_FILE_META_GROUP_LENGTH_MISSING";
397
399
  readonly DICOM_GROUP_LENGTH_IN_DATASET: "DICOM_GROUP_LENGTH_IN_DATASET";
398
400
  readonly DICOM_IMPLICIT_VR_FOR_PRIVATE_TAG_WITHOUT_VR: "DICOM_IMPLICIT_VR_FOR_PRIVATE_TAG_WITHOUT_VR";
401
+ readonly DICOM_ITEM_CROSSES_SEQUENCE_END: "DICOM_ITEM_CROSSES_SEQUENCE_END";
399
402
  readonly DICOM_MISSING_PREAMBLE: "DICOM_MISSING_PREAMBLE";
400
403
  readonly DICOM_NONZERO_RESERVED_BYTES: "DICOM_NONZERO_RESERVED_BYTES";
401
404
  readonly DICOM_ODD_LENGTH_VALUE_PADDED: "DICOM_ODD_LENGTH_VALUE_PADDED";
@@ -416,6 +419,8 @@ declare const WARNING_CODES: {
416
419
  readonly DICOM_UNSUPPORTED_CHARSET: "DICOM_UNSUPPORTED_CHARSET";
417
420
  readonly DICOM_BURNED_IN_ANNOTATION_NOT_REMOVED: "DICOM_BURNED_IN_ANNOTATION_NOT_REMOVED";
418
421
  readonly DICOM_DEIDENT_EMBEDDED_ATTRIBUTE_REMOVED: "DICOM_DEIDENT_EMBEDDED_ATTRIBUTE_REMOVED";
422
+ readonly DICOM_DEIDENT_METHOD_NOT_ADDED: "DICOM_DEIDENT_METHOD_NOT_ADDED";
423
+ readonly DICOM_DEIDENT_METHOD_PRIOR_RETAINED: "DICOM_DEIDENT_METHOD_PRIOR_RETAINED";
419
424
  readonly DICOM_DEIDENT_SEQUENCE_NOT_AUDITABLE: "DICOM_DEIDENT_SEQUENCE_NOT_AUDITABLE";
420
425
  readonly DICOM_DEIDENT_UNDEFINED_VR_NOT_AUDITABLE: "DICOM_DEIDENT_UNDEFINED_VR_NOT_AUDITABLE";
421
426
  readonly DICOM_PRIVATE_CREATOR_UNKNOWN: "DICOM_PRIVATE_CREATOR_UNKNOWN";
@@ -2643,7 +2648,15 @@ interface DeidentifyReport {
2643
2648
  readonly uidMap: ReadonlyMap<string, string>;
2644
2649
  /** Safety warnings - notably burned-in-pixel annotation that cannot be cleaned. */
2645
2650
  readonly warnings: readonly DicomParseWarning[];
2646
- /** The Retain/Clean options that were active for this run. */
2651
+ /**
2652
+ * The Retain/Clean options that were active for this run.
2653
+ *
2654
+ * **Not a list of what survived.** Attributes Table E.1-1 does not list are
2655
+ * kept without appearing anywhere in this field - `(0012,0063)`
2656
+ * De-identification Method is the one whose retention is disclosed, and it is
2657
+ * disclosed as `DICOM_DEIDENT_METHOD_PRIOR_RETAINED` on
2658
+ * {@link DeidentifyReport.warnings}, because it is not an option set.
2659
+ */
2647
2660
  readonly retained: readonly DeidentifyOption[];
2648
2661
  }
2649
2662
  /**
@@ -2676,8 +2689,44 @@ interface DeidentifyOptions {
2676
2689
  */
2677
2690
  readonly profile?: Profile;
2678
2691
  /**
2679
- * Text written to `(0012,0063)` De-identification Method. Default names the
2692
+ * Text **added to** `(0012,0063)` De-identification Method. Default names the
2680
2693
  * Basic Profile and the active options.
2694
+ *
2695
+ * PS3.15 E.1.1 says this string is "inserted in or added to" the attribute, so
2696
+ * a value the incoming Data Set already carried is kept and this one is
2697
+ * appended after a `\` as a further value of the `1-n` attribute - the
2698
+ * provenance chain, not a replacement.
2699
+ *
2700
+ * **This string is itself a `1-n` value**: it is split on `\` and only the
2701
+ * values not already recorded are added.
2702
+ *
2703
+ * **Trailing SPACE and NUL are padding, not content** (PS3.5 Table 6.2-1's `LO`
2704
+ * row, which describes a **Value** - and `LO` is `1-n`). They are ignored when
2705
+ * a value here is matched against one already recorded, **per value, on both
2706
+ * sides**, and they are trimmed from the value written. That makes repeated
2707
+ * de-identification a fixed point **from the first pass**, for every string:
2708
+ * with or without a delimiter, and with a pad byte on any value, last or not.
2709
+ * A string that is padding only records nothing. Leading spaces are yours and
2710
+ * are written through untouched.
2711
+ *
2712
+ * One bound, and it is over the value that would be **written**, not over the
2713
+ * join: when that value would exceed the largest Value Length an `LO` can
2714
+ * encode, the prior value is **replaced** rather than added to - an element the
2715
+ * serializer cannot encode would take the whole de-identified object down - and
2716
+ * `report.warnings` carries `DICOM_DEIDENT_METHOD_NOT_ADDED`. That includes a
2717
+ * prior value already at the ceiling which records this method already, where
2718
+ * there is no join to exceed anything. A string longer than that ceiling on its
2719
+ * own is not bounded here and will fail to serialize, exactly as it did before
2720
+ * this option grew a join.
2721
+ *
2722
+ * `DICOM_DEIDENT_METHOD_NOT_ADDED` means "the length ceiling was reached", never
2723
+ * "every fallback is disclosed": a `(0012,0063)` a file encoded under a VR other
2724
+ * than `LO` is also replaced, and that one is silent.
2725
+ *
2726
+ * When the prior value **is** kept, `report.warnings` carries
2727
+ * `DICOM_DEIDENT_METHOD_PRIOR_RETAINED`: `(0012,0063)` is not in Table E.1-1, so
2728
+ * nothing in the run inspected or redacted those bytes, and a name a sender
2729
+ * wrote there is in output stamped `(0012,0062) = YES`.
2681
2730
  */
2682
2731
  readonly deidentificationMethod?: string;
2683
2732
  }
@@ -2775,8 +2824,10 @@ declare class DeidentifyError extends Error {
2775
2824
  * {@link Profile}, keeps the private data elements the profile's overlay names
2776
2825
  * as safe (and the private-creator elements the profile recognizes).
2777
2826
  * - Remaps `(0002,0003)` Media Storage SOP Instance UID consistently (unless
2778
- * `RetainUIDs`), writes `(0012,0062)` Patient Identity Removed = `YES` and
2779
- * `(0012,0063)` De-identification Method, and warns
2827
+ * `RetainUIDs`), writes `(0012,0062)` Patient Identity Removed = `YES`, **adds**
2828
+ * its method text to `(0012,0063)` De-identification Method rather than
2829
+ * replacing what the file already recorded there (PS3.15 E.1.1 - see
2830
+ * `addDeidentificationMethod`), and warns
2780
2831
  * (`DICOM_BURNED_IN_ANNOTATION_NOT_REMOVED`) when Pixel Data is present and not
2781
2832
  * marked free of burned-in annotation - this metadata-only pass cannot clean
2782
2833
  * pixels (deferred to `@cosyte/dicom-pixel`).
@@ -2851,7 +2902,21 @@ declare class DeidentifyError extends Error {
2851
2902
  * private value the sender wrote **outside** the sequence was retained on the
2852
2903
  * Item's reservation and written into output stamped `PatientIdentityRemoved =
2853
2904
  * YES` with `removedPrivateTags: []` (`DICOM-PRIVATE-CREATOR-RESERVATION-LEAK`,
2854
- * live through `0.0.9`). See {@link itemStreamOverrunsSequence}.
2905
+ * measured on the published `0.0.8` tarball and fixed on `0.0.10`; there is no `0.0.9` on
2906
+ * the registry). See {@link itemStreamOverrunsSequence}.
2907
+ * - `RetainSafePrivate` **retains nothing that a Data Set holds after a sequence
2908
+ * whose own contents contradict the extent it declared** - the mirror
2909
+ * direction, where an Item that *under*-declares **ejects** its trailing
2910
+ * elements out and a Private Creator landing in the enclosing Data Set reserves
2911
+ * a block for elements the sender never put beside it. The same false
2912
+ * attestation, and it applies **in every Data Set, not just the root**: an
2913
+ * inner sequence ejecting a creator into the still-usable Item that encloses it
2914
+ * is measured and pinned. The cut is positional, so a reservation the sender
2915
+ * wrote **ahead of** the offending sequence is untouched. Every private element
2916
+ * after that point is removed and named in `report.removedPrivateTags`, and the
2917
+ * **private-`SQ` carve-out above still applies**: a private `SQ` inside the
2918
+ * settled run that the profile vouches for is kept verbatim and never walked.
2919
+ * See {@link settledBound}.
2855
2920
  *
2856
2921
  * @module
2857
2922
  */