@cosyte/dicom 0.1.0 → 0.1.1
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 +6 -0
- package/README.md +4 -4
- package/TRADEMARKS.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +28 -41
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 71149ed: The `deidentify()` JSDoc now names `docs-content/limitations.md` as the list of open de-identification residuals, instead of a contributor file the package does not ship.
|
|
8
|
+
|
|
3
9
|
## 0.1.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -135,7 +135,7 @@ Everything is exported from the single top-level entry point, `@cosyte/dicom`. T
|
|
|
135
135
|
- **Two access patterns**: named views, or structural `ds.get("00100010")` by 8-character `(group,element)` tag (resolve a keyword to its tag with `Dictionary.byKeyword`), plus `ds.elements()` to walk everything.
|
|
136
136
|
- **Compressed objects read, pixels untouched**: every PS3.5 2026c section A.4 encapsulation syntax (JPEG, JPEG-LS, JPEG 2000, HTJ2K, RLE and the rest) parses under Explicit VR LE rules, and `readPixelDataFragments(ds)` hands back the Basic Offset Table and every fragment as raw bytes. Pixels are never decoded. `serializeDicom` writes those syntaxes back, fragments byte for byte, and refuses with `INVALID_ENCAPSULATED_PIXEL_DATA` a top-level Pixel Data section A.4 does not allow.
|
|
137
137
|
- **Lazy typed value decode**: `element.value` decodes raw bytes into a discriminated `DicomValue` across all 34 VRs (numbers, `bigint`s, person names, dates/times, sequences, raw `binary`), honoring `(0008,0005)` Specific Character Set through nested items.
|
|
138
|
-
- **Real-world tolerance, Postel's Law**: a lenient reader emits stable warning codes for what it tolerated; only 4 truly-structural conditions are fatal.
|
|
138
|
+
- **Real-world tolerance, Postel's Law**: a lenient reader emits stable warning codes for what it tolerated; only 4 truly-structural conditions are fatal. (The count used to be quoted here and had drifted: it read `25` against a `WARNING_CODES` of `28`. The locked snapshot in `test/property/__snapshots__/warning-codes.snapshot.test.ts.snap` is the pin, and it is measured on every run rather than narrated here.)
|
|
139
139
|
- **Source/vendor profile system**: `defineProfile()` + 5 built-ins (`ge`, `siemens`, `philips`, `strict`, `lenient`) that only ever _tighten or annotate_ a parse, resolving vendor private tags by the file's live Private Creator string, never a wrong decode.
|
|
140
140
|
- **Metadata-level de-identification**: `deidentify()` applies the PS3.15 Annex E Basic Profile + the metadata-affecting Options, returning a fresh dataset and an audit report built from static tables, with two fields that carry source bytes and are named as such on the type: `report.uidMap` (source UIDs) and `report.removedPrivateTags`.
|
|
141
141
|
- **Spec-clean serializer**: `serializeDicom(ds)` round-trips a dataset back to Part 10 bytes in its source transfer syntax (no transcode; the four native syntaxes and every PS3.5 2026c section A.4 encapsulation syntax, whose top-level Pixel Data is written as an `OB` fragment stream with its Items byte for byte, or refused with `INVALID_ENCAPSULATED_PIXEL_DATA` when section A.4 does not allow it), with correct File Meta group length, even-length padding, every Data Set it can walk (the root and each Sequence Item, at every depth up to `NESTING_DEPTH_LIMIT`) emitted in ascending tag order with Items kept in order and no value changed, and lossless File Meta: non-modeled `(0002,xxxx)` elements are preserved and re-emitted in tag order. Not ordered: a tag repeated inside an Item (both copies kept), a Sequence that cannot be walked, is nested past the bound or whose parsed `items` do not match its bytes, and any `UN`-carried Sequence. Written last whatever its tag: an element whose own bytes do not show where a reader ends it, such as an undefined-length `UN` the parser could not read as a Sequence.
|
|
@@ -306,7 +306,7 @@ At an RSNA-era interoperability test, ~80% of real-world patient CDs failed stri
|
|
|
306
306
|
|
|
307
307
|
| Tier | Behavior | When | Example codes |
|
|
308
308
|
| ---- | -------------- | ------------------------------ | ------------------------ |
|
|
309
|
-
| 0 | Silent |
|
|
309
|
+
| 0 | Silent | No deviation detected | none |
|
|
310
310
|
| 1 | Auto-handled | Trivial deviation, no warning | trailing-space tidy |
|
|
311
311
|
| 2 | Warning | Recoverable deviation | `DICOM_MISSING_PREAMBLE` |
|
|
312
312
|
| 3 | Fatal (always) | Unrecoverable structural error | `NOT_DICOM_PART_10` |
|
|
@@ -346,7 +346,7 @@ const ds = parseDicom(buf, { profile: profiles.siemens });
|
|
|
346
346
|
A profile bundles three things that only ever **tighten or annotate** a parse, never loosen it past the lenient default:
|
|
347
347
|
|
|
348
348
|
- **Private-dictionary overlay**: resolves the Implicit VR of vendor private data elements by the file's _live_ Private Creator string (e.g. `"SIEMENS CSA HEADER"`), keyed canonically as `"GGGGxxLL"` (PS3.5 §7.8.1), never a hard-coded block number. (This is why Agfa IMPAX re-assigning blocks still resolves.) An unknown creator degrades to `UN` plus a `DICOM_PRIVATE_CREATOR_UNKNOWN` warning. The lookup is scoped to one Data Set, and every Sequence Item is its own (PS3.5 §7.5.1, §7.8.1): a block claimed at the root does not resolve an element inside an item, and an element whose block was never claimed in its own Data Set reads `UN` plus `DICOM_PRIVATE_TAG_NO_CREATOR` rather than borrowing a neighbour's VR. Declare the creator in each item that writes private data.
|
|
349
|
-
- **Escalations**: Tier-2 warning codes promoted to a thrown `DicomParseError` (a stricter posture
|
|
349
|
+
- **Escalations**: Tier-2 warning codes promoted to a thrown `DicomParseError` (a stricter posture).
|
|
350
350
|
- **Suppressions**: benign, high-volume warning codes silenced for a known-quirky source.
|
|
351
351
|
|
|
352
352
|
Five built-ins ship under the `profiles` namespace: `ge`, `siemens`, `philips` (vendor overlays, grounded in the public GDCM / dcm4che / dcm2niix dictionaries) and `strict` / `lenient` (posture presets). Build your own with `defineProfile()`. It validates input, composes via `extends`, and returns a frozen profile:
|
|
@@ -584,7 +584,7 @@ A contribution has to clear the same gates CI runs: `pnpm lint`, `pnpm typecheck
|
|
|
584
584
|
|
|
585
585
|
## Trademarks
|
|
586
586
|
|
|
587
|
-
GE, Siemens, and Philips are trademarks of their respective owners.
|
|
587
|
+
GE, Siemens, and Philips are trademarks of their respective owners. Cosyte is not affiliated with, endorsed by, or
|
|
588
588
|
sponsored by any of them. The names identify the vendors whose private dictionaries the built-in profiles resolve. See [TRADEMARKS.md](./TRADEMARKS.md).
|
|
589
589
|
|
|
590
590
|
## License
|
package/TRADEMARKS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Trademarks
|
|
2
2
|
|
|
3
|
-
`@cosyte/dicom` is an independent open-source project.
|
|
3
|
+
`@cosyte/dicom` is an independent open-source project. Cosyte is **not affiliated with, endorsed by,
|
|
4
4
|
or sponsored by** any company named in this repository or its documentation.
|
|
5
5
|
|
|
6
6
|
## Why these names appear
|