{"id":18091284,"url":"https://github.com/dfsp-spirit/libfs","last_synced_at":"2026-03-06T08:34:00.971Z","repository":{"id":55833218,"uuid":"383224280","full_name":"dfsp-spirit/libfs","owner":"dfsp-spirit","description":"A header-only, no-dependency, C++11 library for accessing FreeSurfer neuroimaging file formats.","archived":false,"fork":false,"pushed_at":"2026-02-18T09:23:18.000Z","size":43195,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-18T13:58:37.902Z","etag":null,"topics":["brain","fileformats","freesurfer","label","mesh","mgh","mri","neuroimaging","parser","surface","volume","voxel"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dfsp-spirit.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-07-05T17:55:55.000Z","updated_at":"2026-02-18T09:23:22.000Z","dependencies_parsed_at":"2024-10-31T18:11:52.746Z","dependency_job_id":"4a0262f3-6a39-4089-a2d3-16551f97a2e3","html_url":"https://github.com/dfsp-spirit/libfs","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/dfsp-spirit/libfs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfsp-spirit%2Flibfs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfsp-spirit%2Flibfs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfsp-spirit%2Flibfs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfsp-spirit%2Flibfs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dfsp-spirit","download_url":"https://codeload.github.com/dfsp-spirit/libfs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfsp-spirit%2Flibfs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30167963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T07:56:45.623Z","status":"ssl_error","status_checked_at":"2026-03-06T07:55:55.621Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["brain","fileformats","freesurfer","label","mesh","mgh","mri","neuroimaging","parser","surface","volume","voxel"],"created_at":"2024-10-31T18:11:15.786Z","updated_at":"2026-03-06T08:34:00.952Z","avatar_url":"https://github.com/dfsp-spirit.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libfs\nA portable, header-only, single file, no-dependency, mildly templated, C++11 library for accessing [FreeSurfer](https://freesurfer.net/) neuroimaging file formats.\n\n\n\n\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8090828.svg)](https://doi.org/10.5281/zenodo.8090828)\n![main](https://github.com/dfsp-spirit/libfs/actions/workflows/unittests.yml/badge.svg?branch=main)\n\n\n## Features\n\n* read and write FreeSurfer per-vertex data from and to binary curv format files (like `$SUBJECTS_DIR/surf/lh.thickness`).\n* read and write FreeSurfer brain surface meshes from binary surf format files (like `$SUBJECTS_DIR/surf/lh.white`).\n  - can also import triangular meshes from the following standard mesh file formats:\n    * Wavefront object format (.obj)\n    * Stanford PLY format (.ply, ascii version)\n    * Object File Format (.off, both the plain version and the COFF variant including per-vertex colors are supported).\n  - can export meshes to the following standard mesh file formats: Wavefront object, Stanford PLY (ascii version).\n* read FreeSurfer brain surface parcellations, i.e., the result of applying a brain atlas, from binary annot format files (like `$SUBJECTS_DIR/label/lh.aparc.annot`).\n* read and write FreeSurfer ASCII label files (like `$SUBJECTS_DIR/label/lh.cortex.label`).\n* read and write FreeSurfer 4D volume files (typically 3D voxels + a fourth time/subject dimension) from binary MGH format files (like `$SUBJECTS_DIR/mri/brain.mgh` or `$SUBJECTS_DIR/surf/lh.thickness.fwhm5.fsaverage.mgh`).\n\nSupported data types for the MGH format include:\n* `MRI_INT`: 32 bit signed int\n* `MRI_FLOAT`: 32 bit signed float and\n* `MRI_UCHAR`: 8 bit unsigned int.\n* `MRI_SHORT`: 16 bit signed int.\n\n\n#### A note on the MGZ format\n\nThe MGZ format is just a gzipped version of the MGH format. While the MGZ format is not supported directly by `libfs`, you have two options to read and write MGZ files:\n\n* You can use `zlib` and the [zstr](https://github.com/mateidavid/zstr/) header-only C++ library (a stream wrapper around `zlib`) in combination with `libfs` to read MGZ files. It's easy and a complete example program that does it can be found in [examples/read_mgz/](./examples/read_mgz/). The program also contains an example for writing an MGZ file. While `zlib` itself is not header-only, it should be available *everywhere anyways*, so it should not drag you into dependency hell.\n* You can extract the MGZ files manually on the command line before running your program or convert them using the FreeSurfer `mri_convert` command line program: `mri_convert file.mgz file.mgh`.\n\n\n#### What `libfs` is **not**\n\nThis library was written from scratch in C++. It is **not** based on the FreeSurfer C code and does not use the same data structures that are used in FreeSurfer. Note that libfs also does **not** allow you to call FreeSurfer functions from your programs.\n\n## Usage\n\n### Examples\n\nJust download the file [include/libfs.h](./include/libfs.h) and drop it whereever you like. Make sure your compiler knows about that place. Then use the functions:\n\n```cpp\n// filename: main.cpp. To compile with g++ run:\n//     g++ -I\u003cpath_to_directory_containing_libfs.h\u003e main.cpp -o read_curv_data\n#include \"libfs.h\"\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n#include \u003cvector\u003e\n\nint main(int argc, char** argv) {\n    std::string curv_fname = \"lh.thickness\";\n    std::vector\u003cfloat\u003e data = fs::read_curv_data(curv_fname);\n    std::cout \u003c\u003c \"Received \" \u003c\u003c data.size() \u003c\u003c \" per-vertex values.\\n\";\n    exit(0);\n}\n```\n\n#### Full example programs\n\nSee the [examples directory](./examples/) for some full demo programs which use the library. The example above is a minimal version of the [read_curv example](./examples/read_curv/read_curv.cpp). Other examples include:\n\n* [examples/read_annot/read_annot.cpp](./examples/read_annot/read_annot.cpp): demo program that reads a FreeSurfer cortical parcellation file (atlas mapped to a subject)\n* [examples/read_curv/read_curv.cpp](./examples/read_curv/read_curv.cpp): demo program that reads a FreeSurfer per-vertex data file, containing one value for every vertex of a matching surface, in surface vertex order (e.g., cortical thickness at that vertex)\n* [examples/read_label/read_label.cpp](./examples/read_label/read_label.cpp): demo program that reads a FreeSurfer label file, assigning one value to a subset of vertices (e.g., 1 to all vertices in a certain region, and 0 to all others).\n* [examples/read_mgh/read_mgh.cpp](./examples/read_mgh/read_mgh.cpp): demo program that reads a FreeSurfer MGH file, containing a 3D or 4D image.\n* [examples/read_mgz/read_mgz.cpp](./examples/read_mgz/read_mgz.cpp): demo program that reads a FreeSurfer MGZ file, containing a compressed 3D or 4D image.\n* [examples/read_surf/read_surf.cpp](./examples/read_surf/read_surf.cpp): demo program that reads a FreeSurfer cortical mesh (a.k.a. brain surface) file.\n\n\nYou can run the script [examples/run_all_examples.bash](./examples/run_all_examples.bash) to run all example files.\n\n\n### Building your programs\n\nJust add the directory into which you saved `libfs.h` to the include path during compilation. This is done by adding an `-I\u003cpath\u003e` flag for most compilers, check the manual of your compiler if in doubt.\n\nCompilation instructions for g++ and clang are at the top of each example source file, it should be easy to adapt them for your favorite C++ compiler. If you prefer to build with cmake, have a look at the [CMakeLists.txt file](./CMakeLists.txt) we use to build the unit tests.\n\n\n### Full API documentation\n\nThe API docs can be browsed online at [codedocs.xyz/dfsp-spirit/libfs/](https://codedocs.xyz/dfsp-spirit/libfs/). The API docs contain usage examples for many important functions.\n\n\n### Conventions\n\n* Everything from `libfs` is in the `fs::` namespace.\n* Internal functions in `libfs` are prefixed with an underscore, e.g., `_do_internal_stuff`. You should never call these functions from client code, as they may change without notice between versions. Relying on them is an application bug. (Please [open an issue](https://github.com/dfsp-spirit/libfs/issues) if you feel that you need to use an internal function from your client code, and explain your use case.) Internal functions are not listed in the API docs.\n* Function naming:\n  - Functions that read data are called `read_*`, e.g., `read_curv` and `read_mgh`.\n  - Functions that write data to files are called `write_*`, e.g., `write_curv` and `write_mgh`.\n* Most `read_*`/`write_*` functions are overloaded and accept either a `const std::string\u0026 filename` argument or a `std::istream *is`/`std::ostream *os` as a source/sink. This allows you to pass streams and bring your own gunzip (see [examples/read_mgz/](./examples/read_mgz/)).\n* You can control the output of libfs by defining a log level for libfs before importing the libfs header file, see the API docs for details. An example can be seen at the very top of the [demo app](./src/demo_main.cpp).\n\n\n## Development\n\n\n### Running the tests\n\nYou need git, cmake and some C++ compiler. Under Debian-based Linux distributions `sudo apt-get install build-essential cmake git` should do it.\n\nIf you have not cloned yet:\n\n```shell\ngit clone https://github.com/dfsp-spirit/libfs\ncd libfs/\n```\n\nThen build and run the tests:\n\n```shell\ncmake .\nmake\n./run_libfs_tests\n```\nNote that the only things that are being built are the test binary `run_libfs_tests` and the demo application, `demo_libfs`.\n\nNote: If you do not have cmake, you can compile the tests manually, e.g., for `g++`:\n\n```shell\n# in the libfs repo root:\ng++ -Iinclude -Ithird_party src/main.cpp src/libfs_tests.cpp -o run_libfs_tests\n```\n\nPlease check your compiler's manual if you are using a different compiler.\n\n\n### Running all mini examples\n\nThe examples are small, stand-alone programs in the `examples/` directory. Each example demonstrates how to interact with a certain file type.\n\nIn the repo root, just run `./examples/run_all_examples.bash` from your system shell. This script will also compile them (requires `g++`).\n\nNote that the `read_mgz` example requires `zlib`.\n\n\n### Running the demo app\n\nThe demo app `demo_libfs` is a slightly larger app that is build using cmake, like you would build a larger project that uses libfs.\n\nTo build it, see the instructions in the `Running the tests` section above, which will also build the demo app, `demo_libfs`.\n\n\n### Building the documentation locally\n\nIf you have `doxygen` installed (`sudo apt install doxygen graphviz` under Debian-based Linux distros), you can generate the full API documentation like this:\n\n```\ncmake .\nmake doc\n```\n\nor with:\n\n```\ndoxygen\n```\n\nThe documentation will be built and can be found in `doc_built/` afterwards. The recommended way to browse it is to open `doc_built/html/index.html` with your favorite webbrowser, e.g.:\n\n```\nfirefox doc_built/html/index.html\n```\n\n\n## Author and Getting help\n\nThe `libfs` library was written by [Tim Schäfer](https://ts.rcmd.org).\n\nNote that this library is **not** a part of FreeSurfer, and it is **in no way** endorsed by the FreeSurfer developers. Please do not contact them regarding this library, especially not for support. [Open an issue](https://github.com/dfsp-spirit/libfs/issues) in this repo instead.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfsp-spirit%2Flibfs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdfsp-spirit%2Flibfs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfsp-spirit%2Flibfs/lists"}