FFI wrapper around cfitsio in Rust

Overview

rust-fitsio

FFI wrapper around cfitsio in Rust

Join the chat at https://gitter.im/mindriot101/rust-fitsio Build Status Coverage Status

Installation

fitsio supports versions of cfitsio >= 3.08.

cfitsio must be compiled with reentrant support (making it thread-safe) if it is to be compiled with the --enable-reentrant flag passed to configure. This affects developers of this library as the tests by default are run in parallel.

For example on a mac with homebrew, install cfitsio with:

brew install cfitsio --with-reentrant

Alternatively, it is possible to automatically have cargo automatically compile cfitsio from source. To do this, you are required to have a C compiler, autotools (to run the configure script) and make (to run the Makefile). This functionality is made available with the fitsio-src feature:

cargo build --features fitsio-src

For the time being, it's best to stick to the development version from github. The code is tested before being pushed and is relatively stable. Add this to your Cargo.toml file:

[dependencies]
fitsio = { git = "https://github.com/mindriot101/rust-fitsio" }

If you want the latest release from crates.io then add the following:

[dependencies]
fitsio = "*"

Or pin a specific version:

[dependencies]
fitsio = "0.19.0"

This repository contains fitsio-sys-bindgen which generates the C wrapper using bindgen at build time. This requires clang to build, and as this is likely to not be available in general, I do not recommend using it. It is contained here but is not actively developed, and untested. Use at your own peril. To opt in to building with bindgen, compile as:

cargo build --no-default-features --features bindgen

or use from your Cargo.toml as such:

[dependencies]
fitsio = { version = "0.19.0", default-features = false, features = ["bindgen"] }

Documentation

fitsio fitsio documentation
fitsio-sys fitsio-sys documentation
fitsio-sys-bindgen fitsio-sys-bindgen documentation

Feature support

Supported features of the underlying cfitsio library that are available in fitsio are detailed in this tracking issue. If a particular function is not implemented in fitsio, then the underlying fitsfile pointer can be accessed through an unsafe API.

Examples

Open a fits file

let f = fitsio::FitsFile::open("test.fits");

Accessing the underlying fitsfile object

fn main() {
    let filename = "../testdata/full_example.fits";
    let fptr = fitsio::FitsFile::open(filename).unwrap();

    /* Find out the number of HDUs in the file */
    let mut num_hdus = 0;
    let mut status = 0;

    unsafe {
        let fitsfile = fptr.as_raw();

        /* Use the unsafe fitsio-sys low level library to call a function that is possibly not
       implemented in this crate */
        fitsio_sys::ffthdu(fitsfile, &mut num_hdus, &mut status);
    }
    assert_eq!(num_hdus, 2);
}
Comments
  • Opening FITS-files from memory

    Opening FITS-files from memory

    My program receives FITS file from INDI server. I need functionality to open FITS files directly from memory without writing to disk. Is this possible for cfitsio and rust-fitsio?

    opened by art-den 15
  • Handle 'X' for a ColumnDataType.

    Handle 'X' for a ColumnDataType.

    Hi! Thank you so much for your work on this crate - it's been incredibly useful for me.

    I have some fits files that store data using the BIT type in a BINTABLE extension. With a one-line change, I was able to unpack the contents into a Vec<u32> just fine. I don't know the ramifications of this change, so please feel free to consult me on this.

    An example file is shared below:

    https://drive.google.com/file/d/1JTYEQD2f42HZMb7D3wskSx6Wkto3HsVO/view?usp=sharing

    Thanks again for your time and effort!

    opened by cjordan 13
  • Allow cfitsio to be compiled from source.

    Allow cfitsio to be compiled from source.

    Hey @mindriot101, hope you're doing well. This commit looks rather scary, but that's just because it includes all the cfitsio source code. Feel free to review this if you like and have the time.

    One potential point for apprehension here is that the code is not tested under OSX. At my work, we recently got a Mac-using developer, so they can test my commit before it gets merged, should you not want to or have time.

    Cheers!

    opened by cjordan 12
  • Nasa files can't be read

    Nasa files can't be read

    Hi,

    could you please look at why NASA files cannot be read using the function? image_data is contains only 0

    let filename = "./testdata/UITfuv2582gc.fits";
    let mut fptr = fitsio::FitsFile::open(filename).unwrap();
    fptr.pretty_print();
    
    let hdu = fptr.hdu(0).unwrap();
    
    let image_data: Vec<f32> = hdu.read_image(&mut fptr, ).unwrap();
    

    Data: https://fits.gsfc.nasa.gov/samples/UITfuv2582gc.fits

    opened by rafaeling 10
  • Not able to save u16 vector to a fits file

    Not able to save u16 vector to a fits file

    Is there any way to save a u16 Vec to a fits file? Currently it says u16 is not implemented for the WriteImage trait when I try to use hdu.write_image for a u16 vector, but can that be added here, or is there a way to change that? I am currently recasting the vector to a u32, but the vector contains 61 million entries, and recasting takes a long time.

    opened by emaadparacha 8
  • How to write color images?

    How to write color images?

    I'm trying this:

    use fitsio::{*, images::*};
    
    fn main() {
        _ = std::fs::remove_file(r"testfile.fit");
    
        let mut fptr = FitsFile::create(r"testfile.fit").open().unwrap();
    
        let description = ImageDescription {
            data_type: ImageType::Float,
            dimensions: &[3, 42, 42],
        };
        let data_to_write = vec![1.0_f32; 3 * 42 * 42];
    
        let hdu = fptr.create_image("EXTNAME".to_string(), &description).unwrap();
    
        hdu.write_image(&mut fptr, &data_to_write).unwrap();
    }
    

    File is being created but many programs can't read it

    opened by art-den 7
  • Invalid bitpix value from ffgiet causing panic

    Invalid bitpix value from ffgiet causing panic

    rust-fitsio uses ffgiet to determine the dtype of an image HDU. I have an image for which ffgiet returns 20, which runs me into an unreachable!(). The cfitsio docs suggest this shouldn't be possible. The header starts off like this:

    SIMPLE  =                    T                                                  
    BITPIX  =                   16 /8 unsigned int, 16 & 32 int, -32 & -64 real     
    NAXIS   =                    2 /number of axes                                  
    NAXIS1  =                 1024 /fastest changing axis                           
    NAXIS2  =                 1024 /next to fastest changing axis                   
    BSCALE  =   1.0000000000000000 /physical = BZERO + BSCALE*array_value           
    BZERO   =   32768.000000000000 /physical = BZERO + BSCALE*array_value           
    

    Here's a link to download the full file

    As a workaround for this one file, I can use ffgidt. Is this a bug in cfitsio?

    opened by saethlin 7
  • Cannot compile on armv7-unknown-linux-gnueabihf

    Cannot compile on armv7-unknown-linux-gnueabihf

    Trying to compile a crate with fitsio="0.17.0" as a dependency on a Raspberry Pi running Raspberry Pi OS Lite. This is the error message:

    error: no rules expected the token `DataType`
       --> /root/.cargo/registry/src/github.com-1285ae84e5963aae/fitsio-0.17.0/src/images.rs:295:42
        |
    91  | macro_rules! read_image_impl_vec {
        | -------------------------------- when calling this macro
    ...
    295 | read_image_impl_vec!(i64, i64::default() DataType::TLONGLONG);
        |                                         -^^^^^^^^ no rules expected this token in macro call
        |                                         |
        |                                         help: missing comma here
    
    error: no rules expected the token `DataType`
       --> /root/.cargo/registry/src/github.com-1285ae84e5963aae/fitsio-0.17.0/src/images.rs:308:39
        |
    210 | macro_rules! write_image_impl {
        | ----------------------------- when calling this macro
    ...
    308 | write_image_impl!(i64, i64::default() DataType::TLONGLONG);
        |                                      -^^^^^^^^ no rules expected this token in macro call
        |                                      |
        |                                      help: missing comma here
    
    error[E0425]: cannot find function `fits_read_key_lnglng` in this scope
       --> /root/.cargo/registry/src/github.com-1285ae84e5963aae/fitsio-0.17.0/src/headers.rs:61:22
        |
    61  |   reads_key_impl!(i64, fits_read_key_lnglng);
        |                        ^^^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `fits_read_key_lng`
        |
       ::: /root/.cargo/registry/src/github.com-1285ae84e5963aae/fitsio-0.17.0/src/longnam.rs:240:1
        |
    240 | / pub(crate) unsafe fn fits_read_key_lng(
    241 | |     fptr: *mut fitsfile,
    242 | |     keyname: *const c_char,
    243 | |     value: *mut c_long,
    ...   |
    247 | |     ffgkyj(fptr, keyname, value, comm, status)
    248 | | }
        | |_- similarly named function `fits_read_key_lng` defined here
    
    error[E0425]: cannot find function `fits_read_col_lnglng` in this scope
       --> /root/.cargo/registry/src/github.com-1285ae84e5963aae/fitsio-0.17.0/src/tables.rs:156:22
        |
    156 |   reads_col_impl!(i64, fits_read_col_lnglng, 0);
        |                        ^^^^^^^^^^^^^^^^^^^^ help: a function with a similar name exists: `fits_read_col_lng`
        |
       ::: /root/.cargo/registry/src/github.com-1285ae84e5963aae/fitsio-0.17.0/src/longnam.rs:198:1
        |
    198 | / pub(crate) unsafe fn fits_read_col_lng(
    199 | |     fptr: *mut fitsfile,
    200 | |     colnum: c_int,
    201 | |     firstrow: LONGLONG,
    ...   |
    211 | |     )
    212 | | }
        | |_- similarly named function `fits_read_col_lng` defined here
    
    For more information about this error, try `rustc --explain E0425`.
    
    opened by al-jshen 5
  • trait `fitsio::images::ReadImage` is not implemented for `ndarray...`

    trait `fitsio::images::ReadImage` is not implemented for `ndarray...`

    Hi,

    Sorry, if I am making an obvious mistake as I am a total rust beginner.

    Everything seems to be working fine until I want to create an ndarray from the image in the FITS file.

    No matter how I write it, I always get an

    the trait bound ndarray::ArrayBase<ndarray::OwnedRepr<u32>, ndarray::dimension::dim::Dim<ndarray::dimension::dynindeximpl::IxDynImpl>>: fitsio::images::ReadImage is not satisfied

    error.

    I think this is not just caused by my code as I can reproduce it by trying to compile the example code in this repo:

    ➜  ~/tmp git clone [email protected]:mindriot101/rust-fitsio.git
    Klone nach 'rust-fitsio' ...
    remote: Enumerating objects: 121, done.
    remote: Counting objects: 100% (121/121), done.
    remote: Compressing objects: 100% (70/70), done.
    remote: Total 5665 (delta 65), reused 88 (delta 46), pack-reused 5544
    Empfange Objekte: 100% (5665/5665), 6.85 MiB | 2.05 MiB/s, Fertig.
    Löse Unterschiede auf: 100% (4305/4305), Fertig.
    ➜  ~/tmp cd rust-fitsio/homepage/fitsioexample 
    ➜  ~/…/homepage/fitsioexample git:(master) cargo run --bin ndarray_support
        Updating git repository `https://github.com/mindriot101/rust-fitsio`
        Updating crates.io index
       Compiling num-traits v0.2.6
       Compiling matrixmultiply v0.1.15
       Compiling libc v0.2.51
       Compiling pkg-config v0.3.14
       Compiling either v1.5.1
       Compiling num-complex v0.2.1
       Compiling rawpointer v0.1.0
       Compiling ndarray v0.11.2
       Compiling ndarray v0.12.1
       Compiling itertools v0.7.11
       Compiling fitsio-sys v0.3.0 (https://github.com/mindriot101/rust-fitsio#98910ee3)
       Compiling num-traits v0.1.43
       Compiling num-complex v0.1.43
       Compiling fitsio v0.14.1 (https://github.com/mindriot101/rust-fitsio#98910ee3)
       Compiling fitsioexample v0.1.0 (/home/lukas/tmp/rust-fitsio/homepage/fitsioexample)
    error[E0277]: the trait bound `ndarray::ArrayBase<ndarray::OwnedRepr<f32>, ndarray::Dim<ndarray::IxDynImpl>>: fitsio::images::ReadImage` is not satisfied
      --> src/bin/ndarray_support.rs:12:31
       |
    12 | let image: ArrayD<f32> = phdu.read_image(&mut fptr)?;
       |                               ^^^^^^^^^^ the trait `fitsio::images::ReadImage` is not implemented for `ndarray::ArrayBase<ndarray::OwnedRepr<f32>, ndarray::Dim<ndarray::IxDynImpl>>`
    
    error: aborting due to previous error
    
    For more information about this error, try `rustc --explain E0277`.
    error: Could not compile `fitsioexample`.
    
    To learn more, run the command again with --verbose.
    

    Maybe it isn't working because I seem to be using the latest rust version:

    ➜ cargo --version
    cargo 1.33.0 (f099fe94b 2019-02-12)
    ➜ rustc --version
    rustc 1.33.0 (2aa4c46cf 2019-02-28)
    
    opened by Findus23 5
  • `unimplemented!` panic when trying to read fits file with color image

    `unimplemented!` panic when trying to read fits file with color image

    Trying to read FITS file with RGB image

    use fitsio::{*, images::*, hdu::*};
    
    fn main() {
        let mut fptr = FitsFile::open("some_color_fits.fit").unwrap();
        let image_hdu = fptr.primary_hdu().unwrap();
    
        if let HduInfo::ImageInfo { shape, .. } = &image_hdu.info {
            assert!(shape.len() == 3 && shape[0] == 3, "Is not RGB image");
    
            let height = shape[1];
            let width = shape[2];
    
            let red_data: Vec<f32> = image_hdu.read_rows(&mut fptr, 0, width*height).unwrap(); // <- Panic here
            let green_data: Vec<f32> = image_hdu.read_rows(&mut fptr, width*height, width*height).unwrap();
            let blue_data: Vec<f32> = image_hdu.read_rows(&mut fptr, 2*width*height, width*height).unwrap();
        }
    }
    

    FIT file example: https://drive.google.com/file/d/1g7MW2_rEF8DhIYOUITIqEa_kPH3faLFO/view (not mine. its link from cloudynights.com)

    opened by art-den 4
  • Dep versions

    Dep versions

    Hi @mindriot101, me again. The first commit here should help keep dependabot quiet. It was my mistake to pull libc down to 0.1.*; it should've always been something in 0.2.*.

    The second commit also pins us against the most-current version of ndarray. In the main branch, the >=0.8.0 range is not very different from what it used to be (0), but this commit solves an important problem; if a new version of ndarray (e.g. 0.16.0) is released and a crate is using both rust-fitsio and ndarray 0.15.*, cargo will eagerly use ndarray 0.16.0 for rust-fitsio and 0.15.* otherwise, causing interoperability issues. This has caused me great pain in the past (not via rust-fitsio, mind you) but I've only relatively recently understood why.

    Anyway, let me know what you think! Cheers.

    opened by cjordan 4
  • build(deps): update bindgen requirement from 0.60.1 to 0.61.0 in /fitsio-sys

    build(deps): update bindgen requirement from 0.60.1 to 0.61.0 in /fitsio-sys

    Updates the requirements on bindgen to permit the latest version.

    Changelog

    Sourced from bindgen's changelog.

    0.61.0

    Released 2022/10/16

    Added

    • new feature: --sort-semantically flag to sort the output in a predefined manner [(#1743)].
    • new feature: Bindgen::emit_warnings method to emit warnings to stderr in build scripts.
    • new feature: --newtype-global-enum flag to generate enum variants as global constants.
    • new feature: --default-non-copy-union-style flag to set the default style of code used to generate unions with non-Copy members.
    • new feature: --bindgen-wrapper-union flag to mark any union that matches a regex and has a non-Copy member to use a bindgen-generated wrapper for its fields.
    • new feature: --manually-drop-union flag to mark any union that matches a regex and has a non-Copy member to use ManuallyDrop.
    • new feature: --merge-extern-blocks flag to merge several extern blocks that have the same ABI.
    • new feature: --no-size_t-is-usize flag to not bind size_t as usize.
    • new feature: Builder implements Clone.

    Changed

    • clap and regex have been updated, new msrv is 1.57.
    • The --enable-function-attribute-detection flag is also used to detect diverging functions so the generated bindings use ! as the return type.
    • The --size_t-is-usize flag is enabled by default.
    • Unused type aliases for <stdint.h> types are no longer emitted.
    • The blocklist options now can be used to block objective-C methods.
    • The core::ffi module is used the sized raw integer types instead of std::os::raw if the Rust target version is 1.64 or higher and the --use-core flag is enabled.
    • The bindgen CLI utility must be installed using cargo install bindgen-cli now.
    • Using bindgen as a library no longer pulls clap and any other CLI related dependencies.

    Fixed

    • Const correctness of incomplete arrays has been fixed. (#2301)
    • C++ inline namespaces don't panic. (#2294)

    [(#1743)]: rust-lang/rust-bindgen#1743

    0.60.1

    Released 2022/06/06

    ... (truncated)

    Commits
    • 784d3e8 bindgen-cli v0.61.0
    • adb178a Specify readme.
    • 4f9b970 v0.61.0
    • 142f62a ci: clippy fixes.
    • c424e03 Add a few missing changelog entries.
    • 2c01810 Remove no-longer-correct include entry in Cargo.toml.
    • 6f6f9fb Move the csmith-fuzzing directory to the top level.
    • 17dd093 Handle incomplete external array constants
    • 626797b Merge pull request #2302 from ferrous-systems/clonable-builder
    • d241e95 Merge pull request #2299 from ferrous-systems/more-robust-postprocessing
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Add coverage for features

    Add coverage for features

    We should add coverage for the individual features. This could be done via a matrix of features that we test, then combining the coverage via the coveralls action finaliser. This way we have more accurate coverage for branches that are not taken.

    opened by simonrw 0
Owner
Simon Walker
Simon Walker
cargo-check This is a wrapper around cargo rustc

cargo-check This is a wrapper around cargo rustc -- -Zno-trans. It can be helpful for running a faster compile if you only need correctness checks. In

Ray Solomon 99 Oct 13, 2022
A simple, yet feature-filled wrapper around the coqui-stt C API

A simple, yet feature-filled wrapper around the coqui-stt C API

0/0 56 Jan 3, 2023
A safe wrapper around Gamercade's raw Api.

gamercade-rs A safe wrapper around Gamercade's Raw Api. As the Raw Api requires using a lot of unsafe and hiding of values through different types (fo

null 1 Aug 23, 2022
🌋 A very lightweight wrapper around the Vulkan Memory Allocator 🦀

?? vk-mem-alloc-rs A very lightweight wrapper around the Vulkan Memory Allocator ?? [dependencies] vk-mem-alloc = "0.1.1" Simple Vulkan Memory Allocat

Project KML 13 Nov 8, 2022
A high-level Rust crate around the Discord API, aimed to be easy and straight-forward to use.

rs-cord A high-level Rust crate around the Discord API, aimed to be easy and straight-forward to use. Documentation • Crates.io • Discord Navigation M

Jay3332 4 Sep 24, 2022
Just a personal Rust Playground to play around and understand the language.

Rust Proactive Introduction The code is a bit messy but it serves just as a personal Rust Playground to play around and understand the language. You c

Fernando Cejas 3 Dec 21, 2022
A collection of compilers based around compiling a high level language to a Brainfuck dialect.

tf A collection of compilers based around compiling a high level language to a Brainfuck dialect. Built at, and for, the VolHacks V hackathon during O

adam mcdaniel 6 Nov 25, 2021
A simple library with just one struct which is used to wrap around pointers

A simple library with just one struct which is used to wrap around pointers. This can be used to create pointers and share them across threads without the hassle of synchronization if you really do not care about that.

null 1 Apr 11, 2022
dm-jitaux is a Rust-based JIT compiler using modified auxtools, dmasm and Inkwell LLVM wrapper for boosting Byond DM performance without any hassle!

dm-jitaux is a Rust-based JIT compiler using modified auxtools, dmasm and Inkwell LLVM wrapper for boosting Byond DM performance without any hassle (such as rewriting/refactroing your DM code).

SS220 20 Dec 13, 2022
A rust wrapper for the spam protection API

SpamProtection-rs Table of contents About Supported Rust version Features How to use Credits License About This repo has been shifted to the official

cyberknight777 28 Aug 5, 2022
A Rust wrapper for the SponsorBlock API.

sponsor-block A Rust wrapper for the SponsorBlock API, which you can find complete documentation for here. Uses SponsorBlock data licensed under CC BY

Zacchary Dempsey-Plante 8 Nov 19, 2022
Wrapper library for utilizing DigitalOcean API v2 in Rust

doapi-rs Wrapper library for utilizing DigitalOcean API v2 in Rust Disclaimer This library is in alpha - it may do anything up to, and including, eati

Kevin K. 30 Nov 5, 2022
Autogenerated wrapper for the Telegram Bot API written in Rust.

An Elegant Rust Client for Telegram Bot API crates.io • docs.rs Table of contents Introduction Key Features Installation Getting Started Documentation

FerrisGram 22 Oct 29, 2022
A simple, fast and fully-typed JSPaste API wrapper for Rust

rspaste A simple, fast and fully-typed JSPaste API wrapper for Rust. aidak.tk » Installation Put the desired version of the crate into the dependencie

Aidak 2 May 17, 2022
A lightweight Discord wrapper made in Tauri

Discord-Tauri is a work in progress lightweight wrapper for Discord.

null 104 Dec 20, 2022
API wrapper for the tankerkönig api

tankerkoenig-rs API wrapper for the tankerkoenig-api written in rust. Gives you ready deserialized structs and a easy to use and strictly typed api. I

Jonathan 2 Feb 27, 2022
Provides a wrapper to deserialize clap app using serde.

clap-serde Provides a wrapper to deserialize clap app using serde. API Reference toml const CLAP_TOML: &'static str = r#" name = "app_clap_serde" vers

null 17 Jan 9, 2023
A minimal discord api wrapper.

descord Descord is a discord api wrapper. Example use descord::prelude::*; #[tokio::main] async fn main() { let mut client = Client::new(

null 12 May 6, 2024
First Git on Rust is reimplementation with rust in order to learn about rust, c and git.

First Git on Rust First Git on Rust is reimplementation with rust in order to learn about rust, c and git. Reference project This project refer to the

Nobkz 1 Jan 28, 2022