Name: neuro-mime-types Version: 1.0 Release: 6%{?dist} Summary: Shared MIME type definitions for neuroimaging and electrophysiology formats License: MIT URL: https://gitlab.com/morgan.hough/neurofedora Source0: neuro-mime-types.xml Source1: neuro-mime-types.LICENSE BuildArch: noarch BuildRequires: libxml2 BuildRequires: shared-mime-info # The file triggers in shared-mime-info rebuild /usr/share/mime on install # and uninstall, so this package needs no scriptlets of its own -- but it is # useless without the database, so the dependency is hard. Requires: shared-mime-info %description MIME type definitions for the file formats used in neuroimaging and electrophysiology, so that desktop environments and file managers can identify them and offer the applications that read them. Covers volumes (NIfTI, CIFTI, MGH/MGZ, MINC, AFNI, MRtrix), tractography and surfaces (TCK, TRK, TRX, GIFTI), 3D Slicer scenes (MRML, MRB), and electrophysiology recordings (FIFF, EDF, BioSemi BDF, GDF, BrainVision, XDF, NWB, Blackrock, Neuralynx, Open Ephys, CTF MEG, Intan, Plexon, Spike2, Axon ABF), plus diffusion gradient tables. Detection uses file content where a reliable magic number exists and the file extension otherwise; each entry records which, and why, in a comment. Formats already defined elsewhere are deliberately left alone: DICOM by shared-mime-info, and NRRD, MetaImage and Radiance .hdr by f3d. %prep %autosetup -c -T cp -p %{SOURCE0} %{SOURCE1} . %build # Nothing to compile. The validation that matters happens in %%check. %install install -Dpm0644 neuro-mime-types.xml \ %{buildroot}%{_datadir}/mime/packages/neuro-mime-types.xml %check # 1. Well-formed XML. Necessary, nowhere near sufficient: the file that # shipped a root-XML element without its required namespaceURI attribute # was perfectly well-formed. xmllint --noout neuro-mime-types.xml # 2. The real gate: build a MIME database from it and fail on ANY diagnostic. # update-mime-database exits 0 while printing errors, and a rejected # element does not stop the others from loading -- so the missing # namespaceURI above silently dropped the that followed it, and # .gii files fell back to application/xml. Nothing about that looks like a # failure unless you are reading stderr, which is why this greps it. mimedir=$(mktemp -d) install -Dpm0644 neuro-mime-types.xml "$mimedir/packages/neuro-mime-types.xml" update-mime-database "$mimedir" 2>"$mimedir/err.log" >/dev/null || : # The pattern matters: a missing attribute prints "Error in type ...", but a # malformed comment prints "... parser error : Double hyphen within comment" # and then "Failed to parse", at which point the ENTIRE file is dropped and # the first pattern never matches. Both spellings are checked because both # have now happened here. if grep -qiE '^error|Error in type|parser error|Failed to parse' "$mimedir/err.log"; then echo "update-mime-database rejected part of the definition:" >&2 cat "$mimedir/err.log" >&2 exit 1 fi # 3. Every declared type must reach the compiled database. A type that fails # to compile leaves no trace in the install tree, so count both sides. declared=$(grep -c ' - 1.0-6 - Define application/vnd.nrrd and application/vnd.mhd, which f3d also defines, deliberately and with identical globs. 3D Slicer's two desktop entries declare both types as handled; nothing here defined either, so on a machine without f3d the declarations were INERT and a .nrrd resolved to nothing -- Slicer was never offered for its own native format. Requested by the 3dslicer session, approved by Morgan, conditional on the test below. 33 types. - Tested before adding, because 1.0-5 removed a duplicate definition for exactly the opposite reason. The rule is not "never define a type twice", it is "never define it twice DIFFERENTLY": update-mime-database merges definitions that agree. A database built from f3d's real f3d-image-formats.xml plus this one resolves, identically with and without f3d present and with rc=0: .nrrd .nhrd .nhdr -> application/vnd.nrrd .mhd .mha -> application/vnd.mhd - *.nhdr is one glob beyond f3d's set and is the reason this is worth doing at all. f3d carries *.nhrd, a transposition; NRRD's detached header, which is what Slicer writes when it separates a header from its .raw, is .nhdr. Nothing in Fedora or in this COPR claimed it, and 3dslicer ships four files that handle it (confirmed independently by the 3dslicer session). Both spellings are listed so the f3d-installed case stays consistent. Upstream report drafted at docs/upstream/f3d-nrrd-nhdr-glob-typo.md for Morgan to file. - ci/mime-agreed-duplicates.tsv records the two types as intentional duplicates so ci/check-mime-consistency.py does not report them, and the allowlist suppresses ONLY that report: a glob mapping to two different types is still a hard failure, which is what would catch the two definitions drifting apart later. * Sun Oct 04 2026 Morgan Hough - 1.0-5 - Stop defining application/x-mrtrix and application/x-mrtrix-tracks. The mrtrix3 package defines both, so every install of the two together had one type defined twice, by two files, disagreeing: our *.mif.gz glob carried weight 60 and mrtrix3's own application/x-mrtrix-gz carried the default 50, so .mif.gz resolved to application/x-mrtrix -- a type mrview.desktop does not declare. Installing both packages broke a file association that either one alone got right. 31 types. - Considered and rejected: adding NRRD and MetaImage. f3d defines application/vnd.nrrd and application/vnd.mhd in f3d-image-formats.xml, so claiming them here would have recreated the same bug this release fixes. f3d was not installed on the machine the check first ran on, which is why ci/mime-external-owners.tsv now records externally-owned types explicitly instead of inferring them from whatever is installed locally. * Fri Oct 02 2026 Morgan Hough - 1.0-4 - Revert the *.hdr claim added in -3, at Morgan's direction: the two-file form is not worth contending for, because its *.img half cannot be typed by anything. The extension belongs to everything, and shared-mime-info already gives it to application/vnd.efi.img. - The ni1 magic stays, so a two-file header is still recognised when its extension is not already spoken for, but we no longer game the glob weights to take *.hdr off image/vnd.radiance. - Recorded while here, because it is easy to get backwards: Analyze 7.5 is not supported and cannot be. Its .hdr carries four ZERO bytes where NIfTI puts its magic -- verified by writing one with nibabel -- so an Analyze header is indistinguishable from any other 348-byte file. Nothing in this package ever matched Analyze; ni1 is NIfTI-1's own two-file form, a different format wearing the same two extensions. * Fri Oct 02 2026 Morgan Hough - 1.0-3 - Recognise the OLD two-file NIfTI form. .hdr/.img is not just Analyze 7.5: NIfTI-1 inherited it, and such a header carries "ni1\0" at offset 344 where the single-file form carries "n+1\0". The magic for it was already here and never fired, because f3d claims *.hdr for image/vnd.radiance. - The fix is not a higher magic priority. Measured at 60, 80 and 90, all three lost: when exactly ONE type claims an extension, that glob decides and the content is never consulted. Claiming *.hdr ourselves makes the glob match AMBIGUOUS, which is what sends the question to the magic -- and weighting it 40, below Radiance's default 50, means a .hdr matching no magic still falls to Radiance. Verified both directions: a nibabel written pair header resolves to application/x-nifti and a real "#?RADIANCE" file still resolves to image/vnd.radiance. - *.img stays unclaimed and cannot be otherwise: it is raw voxels with no header, so nothing in it identifies the format, and shared-mime-info already types the extension as application/vnd.efi.img. Typing the .hdr is enough in practice, since every reader opens the header and finds its own .img. - tests/neuro-mime-types.bats covers all of this, with the Radiance control synthesised when f3d is absent so the collision is always exercised. * Tue Sep 29 2026 Morgan Hough - 1.0-2 - Add application/x-mrml and application/x-mrb, the two formats 3D Slicer saves scenes in. Slicer is the largest application in this repo and had no desktop integration of any kind; these are the half of it that belongs here. - The .mrml entry is a collision, not a new extension. shared-mime-info already defines text/x-mrml for the unrelated Multimedia Retrieval Markup Language and claims *.mrml, so both globs sit at weight 50 and the extension cannot decide. XML is case sensitive and the two formats differ in exactly that: a playlist opens " - 1.0-1 - Initial package. 34 MIME types for neuroimaging and electrophysiology. - Written because the COPR had three MIME packages across 1046 binary packages (afni, f3d, paraview) and none of them covered the formats the field exchanges: a .nii.gz on Fedora 44 opens in GNOME Text Editor. - Magic numbers are verified against real files where possible and marked as such in the XML: NIfTI "n+1\0" at offset 344 with sizeof_hdr 348, read from ds000114; the FIFF 12-byte tag header 00000064 0000001f 00000014, identical across all seven .fif files in ds000117. Entries with no verified magic say so and use the extension. - Two collisions resolved on content rather than on extension: *.bdf is application/x-font-bdf in shared-mime-info, and BioSemi BDF takes it back with magic at priority 90; *.nev is claimed by both Blackrock and Neuralynx, and both globs are weighted below default so the magic decides. - Formats left to their existing owners: DICOM (shared-mime-info), NRRD, MetaImage and Radiance .hdr (f3d). *.img and *.hdr are not claimed at all: they collide with disk images and Radiance respectively, and a viewer that wins that fight has taken something from the user.