# See docs/fluorender-plan.md for the survey behind this spec: why a master # snapshot and not the v2.34.1 tag, the bundled-code inventory, the licence # audit and the upstream asks. # # master df5d443 (2026-08-05) is 40 commits past v2.34.1 (2026-05-20). The # snapshot is what has the Linux install layout this package relies on: # GetDataRoot() looks in /usr/share/fluorender (Utility/Directory.h), user # state goes to $XDG_CONFIG_HOME/FluoRender, and the readlink() buffer that the # tag left unterminated is fixed. It also builds against OpenCV 5, which the # COPR buildroot carries. Master itself did not compile on Linux (patch 1). %global commit df5d443cc16afaada83aacebcb42882f65bb4aeb %global shortcommit %(c=%{commit}; echo ${c:0:7}) %global snapdate 20260805 Name: fluorender Version: 2.34.1^%{snapdate}git%{shortcommit} # Explicit, not %%autorelease (ci/PROCEDURES.md golden rule 3). Release: 0.1%{?dist} Summary: Interactive rendering and analysis of fluorescence microscopy volumes # FluoRender: MIT (LICENSE.txt; per-file headers, (c) 2026 SCI Institute). # Compiled in and bundled (see the Provides below): # File/confini.{c,h} libconfini 1.16.4 GPL-3.0-or-later # File/pole.{cpp,h} POLE BSD-2-Clause # File/tiny-json.{c,h} tiny-json MIT # Glad/ glad 2.0.8 output (WTFPL OR CC0-1.0) AND Apache-2.0 # Glad/include/KHR/khrplatform.h MIT-Khronos-old # Graphics/glm.{cpp,h} Nate Robins' Wavefront OBJ reader (glm.c, 1997, # 2000). The file states no licence. It was # distributed with Mark Kilgard's GLUT 3.7 (the # "smooth" demo) and is still carried by Mesa as # mesa/demos src/objviewer/glm.c, which Fedora # ships in mesa-demos under License: MIT. Kept on # that precedent, with no extra License term; # confirming its terms is an open upstream ask # before any Fedora package review (see the plan). # Shipped as data: Templates/d3.v4.min.js, d3 4.13.0, BSD-3-Clause. # Because libconfini is compiled into the one executable, the binary as a # whole is distributable only under GPL-3.0-or-later terms. # Removed by fluorender-clean.sh (not in the SRPM): the Nikon ND2 SDK binaries, # Microsoft Holographic Remoting DLLs, nuget.exe, VC_redist.x64.exe, the # Java_Code jars (including SlideBook6Reader.jar and bio-formats), and the # Looking Glass Bridge SDK headers (FluoRender/BridgeRuntime, no licence # statement; Looking Glass support is compiled out, see Patch5). # Deleted in %%prep (in the SRPM, not in the binary RPM): Wacom WinTab sample # code (Windows only), tinyxml2 10.0.0 (system copy used), the FreeFont .ttf # files (system fonts used), upstream's modified wxWidgets aui sources. License: MIT AND GPL-3.0-or-later AND BSD-2-Clause AND BSD-3-Clause AND Apache-2.0 AND (WTFPL OR CC0-1.0) AND MIT-Khronos-old URL: https://github.com/SCIInstitute/fluorender # NOT an upstream tarball: fluorender-clean.sh removes prebuilt binaries that # Fedora cannot ship (see the script's header). Same arrangement as invesalius # and opencv in this repo: the cleaned tarball goes in this project's COPR # dist-git lookaside, content-addressed by md5, so the package builds from git. # Upstream URL of the uncleaned tree, for reference: # %%{url}/archive/%%{commit}/fluorender-%%{commit}.tar.gz %global copr_lookaside https://copr-dist-git.fedorainfracloud.org/repo/pkgs/mhough/neurofedora/%{name} %global cleanmd5 385908b575fd2f407346ffa3b9ad8e31 Source0: %{copr_lookaside}/%{name}-clean-%{shortcommit}.tar.xz/md5/%{cleanmd5}/%{name}-clean-%{shortcommit}.tar.xz Source1: fluorender-clean.sh Source2: fluorender-wrapper.sh Source3: fluorender.desktop Source4: fluorender.metainfo.xml # Use system libraries only: shared system wxWidgets, openvr, OpenXR, OpenJPEG # link fix, tinyxml2; Java_Code copy only if present. Adds the CMake option # FLUORENDER_USE_SYSTEM_LIBS (default OFF). Patch0: fluorender-system-libraries.patch # master does not compile on Linux: debugging output added 2026-07-13 uses the # Windows BOOL type. Use GLboolean. Patch1: fluorender-glboolean.patch # Fedora has wxWidgets 3.2.9; upstream now targets 3.3. Every change is behind # wxCHECK_VERSION(3, 3, 0): wxAuiSerializer (tab layouts are not saved on 3.2), # wxApp::SetAppearance, wxDisplay::GetFromRect, wxAUI_NB_MULTILINE, range-for # over wxGridCellCoordsArray, and one call that only exists in upstream's own # modified wxAuiNotebook. Patch2: fluorender-wx32.patch # wxGLContextAttrs::PlatformDefaults() is what sets x11Direct on GLX; without # it glXCreateContext gets an uninitialised Bool and the X server answers # BadValue, so FluoRender exited before showing a window under Xvfb. Patch3: fluorender-glx-context-defaults.patch # OnInit() chdirs to the executable's directory before the command line is # parsed, so relative file and -m movie paths resolved under /usr/libexec. Patch4: fluorender-relative-cmdline-paths.patch # Looking Glass holographic displays need the Bridge SDK headers, which carry # no licence statement (removed from the tarball by fluorender-clean.sh), and # the proprietary Looking Glass Bridge runtime, which Fedora cannot ship. Adds # the CMake option FLUORENDER_LOOKINGGLASS (OFF under FLUORENDER_USE_SYSTEM_LIBS) # and guards every Looking Glass code path, the light-field shader, the # "Holography" toolbar button and the Settings controls. Stereo/VR (OpenXR, # openvr) is unaffected. Patch5: fluorender-no-lookingglass.patch # OpenCL kernels, dlib, OpenCV 5 and hdf5 have only been tried on x86_64; # nothing here is x86-specific, but aarch64 has not been built. BuildRequires: cmake BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: make BuildRequires: wxGTK-devel >= 3.2 BuildRequires: libglvnd-devel BuildRequires: zlib-devel BuildRequires: libtiff-devel BuildRequires: libpng-devel BuildRequires: libjpeg-turbo-devel BuildRequires: boost-devel BuildRequires: bzip2-devel BuildRequires: dlib-devel BuildRequires: eigen3-devel BuildRequires: opencv-devel BuildRequires: python3-devel BuildRequires: hdf5-devel # Only for : the JVM is dlopen()ed at run time from a user-set path. BuildRequires: java-devel BuildRequires: pkgconfig(libavcodec) BuildRequires: pkgconfig(libavformat) BuildRequires: pkgconfig(libavutil) BuildRequires: pkgconfig(libswscale) BuildRequires: pkgconfig(libswresample) BuildRequires: freetype-devel BuildRequires: glm-devel BuildRequires: ocl-icd-devel BuildRequires: opencl-headers BuildRequires: openjpeg2-devel BuildRequires: openxr-devel BuildRequires: openvr-devel BuildRequires: teem-devel BuildRequires: tinyxml2-devel # dlib's exported CMake link interface names these libraries but dlib-devel # does not require their -devel packages; without them the final link fails # with "No rule to make target /usr/lib64/libflexiblas.so" and -ljxl. BuildRequires: flexiblas-devel BuildRequires: sqlite-devel BuildRequires: pkgconfig(libavdevice) BuildRequires: pkgconfig(libavfilter) BuildRequires: libjxl-devel # %%check: render a volume under Xvfb with Mesa llvmpipe. BuildRequires: xorg-x11-server-Xvfb BuildRequires: mesa-dri-drivers BuildRequires: python3-pillow BuildRequires: desktop-file-utils BuildRequires: /usr/bin/appstream-util # Fonts/ ships GNU FreeFont; the package links the system copies instead. Requires: gnu-free-sans-fonts Requires: gnu-free-mono-fonts Requires: gnu-free-serif-fonts Requires: hicolor-icon-theme Recommends: %{name}-data = %{version}-%{release} Provides: bundled(libconfini) = 1.16.4 Provides: bundled(pole) Provides: bundled(tiny-json) Provides: bundled(glad2) = 2.0.8 Provides: bundled(js-d3) = 4.13.0 %description FluoRender is an interactive tool for multichannel fluorescence microscopy from the SCI Institute (University of Utah). It renders confocal and light-sheet volume stacks in real time, with per-channel transfer functions, clipping planes and colocalization, and supports painting-based selection, connected-component analysis and tracking over time, rulers and measurements, OpenCL image filters and movie export. It reads TIFF stacks, NRRD, Olympus OIB/OIF, Zeiss LSM and CZI, Leica LIF/LOF, DICOM and PrairieView XML. Not in this build: Nikon ND2 files (the ND2 SDK is proprietary), Looking Glass holographic displays (the Looking Glass Bridge is proprietary) and the ImageJ/Bio-Formats bridge. %package data Summary: Sample volumes for FluoRender License: MIT BuildArch: noarch Requires: %{name} = %{version}-%{release} %description data Sample data shipped with FluoRender: a three-channel zebrafish brain (used by upstream's benchmark) and small density and distance fields. %prep %autosetup -n %{name}-%{commit} -p1 # Windows-only code, with system replacements, or not built on Linux. rm -r FluoRender/FluoRender/WacomUtils FluoRender/FluoRender/XInput rm FluoRender/Glad/src/wgl.c FluoRender/Glad/include/glad/wgl.h rm FluoRender/FluoRender/File/tinyxml2.cpp FluoRender/FluoRender/File/tinyxml2.h # Upstream's modified copies of wxWidgets' aui sources, for its static wx build. rm -r wxWidgets rm Fonts/*.ttf %build %cmake \ -DFLUORENDER_USE_SYSTEM_LIBS:BOOL=ON \ -DFLUORENDER_LOOKINGGLASS:BOOL=OFF \ -DJAVA_HOME:PATH=%{_jvmdir}/java %cmake_build %install # Upstream has no install rules; the build tree's bin/ is the portable layout. B=%{_vpath_builddir}/bin install -Dpm 0755 $B/FluoRender %{buildroot}%{_libexecdir}/%{name}/FluoRender install -Dpm 0755 %{SOURCE2} %{buildroot}%{_bindir}/%{name} sed -i 's|/usr/libexec|%{_libexecdir}|' %{buildroot}%{_bindir}/%{name} # GetDataRoot() finds /usr/share/fluorender by its Scripts/ directory. # Main.cpp's InitializeUserSettings() copies CL_code, Commands, Database, # Scripts, Templates and the two .xml files to ~/.config/FluoRender once per # major.minor version; Fonts and Data are read in place. install -d %{buildroot}%{_datadir}/%{name} for d in CL_code Commands Database Scripts Templates Data; do cp -pr $B/$d %{buildroot}%{_datadir}/%{name}/ done install -pm 0644 $B/fluorender.xml $B/fluorender_default.xml %{buildroot}%{_datadir}/%{name}/ install -d %{buildroot}%{_datadir}/%{name}/Fonts for f in FreeMono FreeMonoBold FreeMonoBoldOblique FreeMonoOblique \ FreeSans FreeSansBold FreeSansBoldOblique FreeSansOblique \ FreeSerif FreeSerifBold FreeSerifBoldItalic FreeSerifItalic; do ln -s ../../fonts/gnu-free/$f.ttf %{buildroot}%{_datadir}/%{name}/Fonts/$f.ttf done for s in 48 128; do install -Dpm 0644 Install/Ubuntu/fluorender/assets/icons/hicolor/${s}x${s}/apps/fluorender.png \ %{buildroot}%{_datadir}/icons/hicolor/${s}x${s}/apps/%{name}.png done desktop-file-install --dir=%{buildroot}%{_datadir}/applications %{SOURCE3} install -Dpm 0644 %{SOURCE4} %{buildroot}%{_metainfodir}/%{name}.metainfo.xml %check desktop-file-validate %{buildroot}%{_datadir}/applications/%{name}.desktop appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/%{name}.metainfo.xml # Upstream has no test suite (Tester/ is Windows-only). Render a synthetic # volume headless instead: a 64x64x32 uint8 NRRD with a bright sphere centred # at x=40, y=28 on a dim z gradient, loaded through teem, rendered by the GL # volume renderer on llvmpipe, and written out by the command-line movie # export (-m). The first frame must show a red sphere right of the volume's # centre, and nothing in green or blue. mkdir -p check/home check/mov export HOME=$PWD/check/home XDG_CONFIG_HOME=$PWD/check/home/.config python3 - check/sphere.nrrd <<'EOF' import sys nx, ny, nz = 64, 64, 32 vox = bytearray() for z in range(nz): for y in range(ny): for x in range(nx): r2 = (x - 40) ** 2 + (y - 28) ** 2 + ((z - 16) * 2.0) ** 2 vox.append(min(255, (220 if r2 < 18 * 18 else 0) + 2 * z)) with open(sys.argv[1], "wb") as f: f.write(b"NRRD0004\ntype: uint8\ndimension: 3\nsizes: 64 64 32\n" b"spacings: 1 1 2\nencoding: raw\n\n") f.write(bytes(vox)) EOF exec 5>check/xdisplay Xvfb -displayfd 5 -screen 0 1280x800x24 -nolisten tcp > check/xvfb.log 2>&1 & xvfb=$! for i in $(seq 50); do [ -s check/xdisplay ] && break; sleep 0.2; done export DISPLAY=:$(cat check/xdisplay) export LIBGL_ALWAYS_SOFTWARE=1 GDK_BACKEND=x11 NO_AT_BRIDGE=1 %{_vpath_builddir}/bin/FluoRender check/sphere.nrrd -m check/mov/f.tif > check/run.log 2>&1 & app=$! # Frame 000 is complete once frame 001 exists. Allow 4 minutes on a slow builder. for i in $(seq 240); do ls check/mov/f_*1.tif >/dev/null 2>&1 && break kill -0 $app 2>/dev/null || break sleep 1 done kill $app 2>/dev/null || : kill $xvfb 2>/dev/null || : wait $app 2>/dev/null || : cat check/run.log | grep -v -e '^$' -e 'Gtk-CRITICAL' -e 'for_size smaller' | tail -n 20 || : python3 - <<'EOF' import glob from PIL import Image frames = sorted(glob.glob("check/mov/f_*.tif")) assert frames, "no movie frame was written" im = Image.open(frames[0]).convert("RGB") w, h = im.size px = im.load() red = [(x, y) for y in range(h) for x in range(w) if px[x, y][0] > 200] box = [(x, y) for y in range(h) for x in range(w) if px[x, y][0] > 0] gb = max(max(px[x, y][1], px[x, y][2]) for y in range(0, h, 4) for x in range(0, w, 4)) assert len(red) > 0.02 * w * h, f"sphere missing: {len(red)} bright pixels of {w*h}" assert gb < 16, f"unexpected green/blue signal {gb}" x0 = min(p[0] for p in box); x1 = max(p[0] for p in box) cx = sum(p[0] for p in red) / len(red) fx = (cx - x0) / (x1 - x0) print(f"{frames[0]}: {w}x{h}, {len(red)} sphere pixels, centroid at {fx:.3f} of the volume width") assert 0.55 < fx < 0.70, f"sphere centroid {fx:.3f}, expected ~0.625" EOF %files %license LICENSE.txt %doc README.md %{_bindir}/%{name} %{_libexecdir}/%{name}/ %dir %{_datadir}/%{name} %{_datadir}/%{name}/CL_code/ %{_datadir}/%{name}/Commands/ %{_datadir}/%{name}/Database/ %{_datadir}/%{name}/Fonts/ %{_datadir}/%{name}/Scripts/ %{_datadir}/%{name}/Templates/ %{_datadir}/%{name}/fluorender.xml %{_datadir}/%{name}/fluorender_default.xml %{_datadir}/applications/%{name}.desktop %{_datadir}/icons/hicolor/*/apps/%{name}.png %{_metainfodir}/%{name}.metainfo.xml %files data %{_datadir}/%{name}/Data/ %changelog * Sat Oct 10 2026 Morgan Hough - 2.34.1^20260805gitdf5d443-1 - Initial package: master snapshot df5d443 (40 commits after v2.34.1), from a tarball cleaned of the proprietary Nikon ND2 SDK, Microsoft DLLs, Windows installers, prebuilt Java jars and the unlicensed Looking Glass Bridge SDK headers; Looking Glass support is compiled out. Built against Fedora's shared wxGTK 3.2, system tiff/png/jpeg/zlib/boost/dlib/OpenCV/hdf5/ffmpeg/ freetype/glm/teem/OpenJPEG/OpenXR/openvr/tinyxml2 and GNU FreeFont. Fixes for the Linux build (BOOL), wx 3.2, an uninitialised GLX context flag and relative command-line paths. Wrapper runs it through XWayland. %%check renders a volume headless.