DICOM, HL7 FHIR, PACS and EHR interop. Segmentation, registration and reconstruction. Biosignals. Every one of them in Rust — no C, C++, Fortran or assembly compiled into a shipped build — with the regulatory data plane wired into the source rather than bolted on at the end.
oximed crate, on every target. Two native items used to survive that selection — ring, the default crypto provider of the rustls/rcgen stack, and the bundled C SQLite engine behind sqlx’s sqlite feature. Neither was documented into acceptability. rustls is now built with no provider feature and takes a Pure-Rust one from OxiTLS; the PACS SQL registry runs on oxisqlite, and sqlx is gone from the workspace. deny.toml denies both outright with no wrappers carve-out, so any dependent fails the check, not merely a new one. What remains, so the graph holds no surprises: ring is still an entry in Cargo.lock with no normal edge reaching it; cc appears as a build-dependency of blake3, pinned to the pure feature under which its build script compiles none of its assembly or NEON C, and of iana-time-zone-haiku, which builds only on Haiku. One workspace crate has an opt-in fuzz feature that pulls LLVM’s libFuzzer, which is C++ — a coverage-guided test harness, unreachable from the oximed crate at any feature selection, and never in a device build.
No unknown provenance
A DICOM parser is a solved problem. What is not solved is arriving at a design review with a dependency tree that a notified body will accept without a stack of justification documents.
| Library | Language | Licence | Shippable in a device | 62304 evidence |
|---|---|---|---|---|
| dcm4che | Java | AGPL / commercial | Runtime + licence problem | You produce it |
| DCMTK | C++ | BSD-style | Yes | You produce it |
| GDCM · ITK | C++ | Apache / BSD | Yes | You produce it |
| Commercial toolkits | C / C++ | Per-seat, per-device | Yes | Partial, at a price |
| OxiMed | Rust | Licensed source | Yes | Included with licence |
Every option above except the last one leaves you holding the same job: classify the software, inventory the SOUP, justify each item, trace requirements to tests, and defend memory safety in code that was written in a language which does not have any. That work is where the schedule goes.
Rust does not make your device safe. It removes an entire category of hazard from the analysis, and it lets the evidence be produced by the build system instead of by a technical writer reading a diff.
Modular. Take the DICOM layer alone for an interop project, or the imaging pipeline for a diagnostic product.
OxiMed is licensed source, not open source. What comes with it is the dossier that goes into your technical file, regenerated for every version you ship. It is produced by oximed-cert — 230 modules and 42,832 lines of code, a regulatory data plane rather than a folder of templates.
#[test] functions and 170 property-based proptest! blocks across 2,372 integration-test files. That is a count of test functions, which is evidence of effort rather than of coverage — treat it as the size of what you inherit, not as an argument that it is sufficient.verify_invariant() takes the Hoare-style condition (ranges ∧ precondition) → postcondition to the embedded Pure-Rust OxiZ SMT solver and returns Verified, Falsified with a counter-example, or Unknown. Nothing shells out; the solver is a default-enabled dependency. A predicate outside the decidable linear-integer fragment comes back Unknown — never as a pass. Full CTL/LTL model checking of the transition relation is not built.Iterator::all over nothing is true, a count of blockers over nothing is 0, and completed ÷ total over nothing is 100%. Each gate carries an assessed flag and reads assessed && …. The count metrics keep their vacuous values, which are arithmetically correct; a metric may stay vacuous only while no gate and no rendered sentence derives from it. A regression test locks the whole family, so the next aggregate anyone adds cannot quietly reintroduce the shape.todo! or unimplemented! across any of it — but a few hundred lines is a starting point for that standard, not coverage of it.A worked example of the §8.1.2 row, since that is the one that costs you time. DICOM Part 10 parsing is not written from scratch here — it comes from the third-party dicom-rs family, pinned at 0.10.0. So it is a SOUP item, and it is kept as one: the family carries an informational advisory for an unmaintained text-decoding crate, triaged in deny.toml with the reachability argument written out rather than silenced, and the live unchecked-length defect in dicom-parser is mitigated on our side by oximed_dicom::parser::validate_declared_lengths, which has its own regression-test file. Version, licence, purpose, known anomaly, mitigation, why it is acceptable — that is the row you would otherwise be writing yourself.
Scaffolding is the honest word for most of this: oximed-cert generates the structure, the records and the traceability, and the safety-invariant checks above are genuinely discharged by a solver — but a generated document is an input to your technical file, not a substitute for authoring it. We supply evidence for our software as a SOUP item in your device. We are not your notified body, your consultant or your quality system, and the classification of your device remains yours to determine.
Most of this workspace is real, working Rust — over a million lines of it. Five areas are not yet what a reader of the capability list would assume, and you should know which before you scope around them, not after.
…1.2.4.90 decodes; …1.2.4.91 decodes on its reversible path. HTJ2K is the gap, and it is a narrow one: T.814 replaces exactly that tier-1 stage with an HT block coder, which is not implemented, so the codec validates the codestream framing and returns a typed refusal naming the missing decoder rather than a generic “unsupported transfer syntax”. The reason is written in the module: no HTJ2K conformance stream exists here and none can be produced without an encoder, so nothing could distinguish a correct block decoder from a plausible one. Encoding is asymmetric too — JPEG-LS and RLE encode, JPEG and JPEG 2000 do not, and those paths error rather than fabricate output.RfScore is therefore a generic linear evaluator with no bundled defaults — you pair it with weights fitted against your own data. If you expected a scoring function that works out of the box, this is the row that costs you time.par_all36m_prot.prm ships from the MacKerell lab, so charmm36::cmap_for_residue returns NotImplemented naming the file, the loader that reads it and where to fetch it. A synthetic Ramachandran surface exists, but it only answers when asked for by name — get_for_production refuses any grid flagged synthetic, so a placeholder cannot be applied as though it were tabulated data.Unknown. Temporal-logic model checking of the transition relation is future work, not a shipped capability.There is no CI workflow behind these claims; company policy restricts .github/workflows to publishing. The gate is a fixed command set run locally before a change is considered done — nextest at all features, clippy with -D warnings, doctests, cargo deny check, and the three no_std builds against a target that genuinely has no std. A host build would prove nothing about a bare-metal claim, so it is not used for one.
You should be able to find out whether this fits your budget without talking to anyone. Annual terms, per device family, invoiced once.
Payable in advance. Source access within one business day of receipt.
Credited in full against an Integration or Class C programme licence. Complete workspace, the full evidence kit above, in full detail. Non-commercial evaluation use only. No sales contact unless you ask for it.
A licensed build for one device family, plus the full evidence kit above — regenerated per release, SBOM and VEX service, 5 business day response.
Everything above, plus a named engineer, participation in your design reviews, and a commitment to support your shipped version for the device lifetime.
No royalty on your device revenue, no per-seat runtime fee, no audit clause. Perpetual licences are available on request.
Nine years removing C. The medical stack is what got built on top.
Registration is optimisation. Reconstruction is transforms. Segmentation is tensors. Every medical imaging toolkit in existence sits on ITK, on VTK, on BLAS, on FFTW — and all of it is C, C++ or Fortran, which is why every SOUP inventory in the industry is long and every justification is hard.
The imaging layer could not be clean until the numerics were replaced. So we started at the bottom and worked up, and OxiMed is what became possible once the floor was Rust.
A Rust wrapper over ITK still puts ITK in your inventory. Ours does not, because the layer beneath it was rewritten first, and the layer beneath that one before it.
The stack is public on GitHub — 60+ projects, Apache-2.0. OxiMed is the part we licence.
Genuinely — send the current list, or just the device class and what it does. You will get back a mapping of which items OxiMed replaces, what stays, and an honest estimate of what that removes from your documentation load. One business day, no call required.