Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resize image #31

Merged
merged 5 commits into from
Mar 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 91 additions & 6 deletions fitsio/src/fitsfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,30 @@ impl FitsFile {
&mut status);
}

HduInfo::ImageInfo { shape: shape.iter().map(|v| *v as usize).collect() }
let mut bitpix = 0;
unsafe {
/* Use equiv type as this is more useful
*
* See description here:
* https://heasarc.gsfc.nasa.gov/docs/software/fitsio/c/c_user/node40.html
*/
sys::ffgiet(self.fptr as *mut _, &mut bitpix, &mut status);
}

let image_type = match bitpix {
8 => ImageType::BYTE_IMG,
16 => ImageType::SHORT_IMG,
32 => ImageType::LONG_IMG,
64 => ImageType::LONGLONG_IMG,
-32 => ImageType::FLOAT_IMG,
-64 => ImageType::DOUBLE_IMG,
_ => unreachable!(),
};

HduInfo::ImageInfo {
shape: shape.iter().map(|v| *v as usize).collect(),
image_type: image_type,
}
}
1 | 2 => {
let mut num_rows = 0;
Expand Down Expand Up @@ -823,7 +846,7 @@ pub trait ReadWriteImage: Sized {
/// This reads an entire image into a one-dimensional vector
fn read_image(fits_file: &FitsFile) -> FitsResult<Vec<Self>> {
match fits_file.fetch_hdu_info() {
Ok(HduInfo::ImageInfo { shape }) => {
Ok(HduInfo::ImageInfo { shape, .. }) => {
let mut npixels = 1;
for dimension in &shape {
npixels *= *dimension;
Expand Down Expand Up @@ -856,7 +879,7 @@ macro_rules! read_write_image_impl {
start: usize,
end: usize) -> FitsResult<Vec<Self>> {
match fits_file.fetch_hdu_info() {
Ok(HduInfo::ImageInfo { shape: _shape }) => {
Ok(HduInfo::ImageInfo { shape: _shape, .. }) => {
let nelements = end - start;
let mut out = vec![0 as $t; nelements];
let mut status = 0;
Expand Down Expand Up @@ -885,7 +908,7 @@ macro_rules! read_write_image_impl {
fn read_rows(fits_file: &FitsFile, start_row: usize, num_rows: usize)
-> FitsResult<Vec<Self>> {
match fits_file.fetch_hdu_info() {
Ok(HduInfo::ImageInfo { shape }) => {
Ok(HduInfo::ImageInfo { shape, .. }) => {
if shape.len() != 2 {
unimplemented!();
}
Expand All @@ -910,7 +933,7 @@ macro_rules! read_write_image_impl {
fn read_region(fits_file: &FitsFile, ranges: &[&Range<usize>])
-> FitsResult<Vec<Self>> {
match fits_file.fetch_hdu_info() {
Ok(HduInfo::ImageInfo { shape }) => {
Ok(HduInfo::ImageInfo { shape, .. }) => {
if shape.len() != 2 {
unimplemented!();
}
Expand Down Expand Up @@ -1246,6 +1269,28 @@ impl<'open> FitsHdu<'open> {
T::read_region(self.fits_file, ranges)
}

pub fn resize(&mut self, new_size: &[usize]) -> FitsResult<()> {
self.make_current()?;
fits_check_readwrite!(self.fits_file);

match self.info {
HduInfo::ImageInfo { image_type, .. } => {
let mut status = 0;
unsafe {
sys::ffrsim(self.fits_file.fptr as *mut _,
image_type.into(),
2,
new_size.as_ptr() as *mut _,
&mut status);
}
fits_try!(status, ())
}
HduInfo::TableInfo { .. } => return Err("cannot resize binary table".into()),
HduInfo::AnyInfo => unreachable!(),
}

}

pub fn get_column_no<T: Into<String>>(&self, col_name: T) -> FitsResult<usize> {
self.make_current()?;

Expand Down Expand Up @@ -1431,9 +1476,10 @@ mod test {

let f = FitsFile::open("../testdata/full_example.fits").unwrap();
match f.fetch_hdu_info() {
Ok(HduInfo::ImageInfo { shape }) => {
Ok(HduInfo::ImageInfo { shape, image_type }) => {
assert_eq!(shape.len(), 2);
assert_eq!(shape, vec![100, 100]);
assert_eq!(image_type, ImageType::LONG_IMG);
}
Err(e) => panic!("Error fetching hdu info {:?}", e),
_ => panic!("Unknown error"),
Expand Down Expand Up @@ -2057,6 +2103,45 @@ mod test {
assert_eq!(chunk[25], 75);
}

#[test]
fn resizing_images() {
let tdir = tempdir::TempDir::new("fitsio-").unwrap();
let tdir_path = tdir.path();
let filename = tdir_path.join("test.fits");

// Scope ensures file is closed properly
{
use fitsfile::ImageDescription;

let f = FitsFile::create(filename.to_str().unwrap()).unwrap();
let image_description = ImageDescription {
data_type: ImageType::LONG_IMG,
dimensions: &[100, 20],
};
f.create_image("foo".to_string(), &image_description).unwrap();
}

/* Now resize the image */
{
let f = FitsFile::edit(filename.to_str().unwrap()).unwrap();
let mut hdu = f.hdu("foo").unwrap();
hdu.resize(&vec![1024, 1024]).unwrap();
}

/* Images are only resized when flushed to disk, so close the file and
* open it again */
{
let f = FitsFile::edit(filename.to_str().unwrap()).unwrap();
let hdu = f.hdu("foo").unwrap();
match hdu.info {
HduInfo::ImageInfo { shape, .. } => {
assert_eq!(shape, vec![1024, 1024]);
}
_ => panic!("Unexpected hdu type"),
}
}
}

#[test]
fn write_image_section_to_table() {
let tdir = tempdir::TempDir::new("fitsio-").unwrap();
Expand Down
2 changes: 1 addition & 1 deletion fitsio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
//! # let fptr = FitsFile::open(filename).unwrap();
//! let hdu = fptr.hdu(0).unwrap();
//! // image HDU
//! if let HduInfo::ImageInfo { shape } = hdu.info {
//! if let HduInfo::ImageInfo { shape, .. } = hdu.info {
//! println!("Image is {}-dimensional", shape.len());
//! println!("Found image with shape {:?}", shape);
//! }
Expand Down
12 changes: 9 additions & 3 deletions fitsio/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ macro_rules! imagetype_into_impl {
}
}
}
)
)
}

imagetype_into_impl!(i8);
Expand All @@ -94,7 +94,10 @@ imagetype_into_impl!(i64);
/// Otherwise the variant is `HduInfo::TableInfo`.
#[derive(Debug)]
pub enum HduInfo {
ImageInfo { shape: Vec<usize> },
ImageInfo {
shape: Vec<usize>,
image_type: ImageType,
},
TableInfo {
column_descriptions: Vec<ConcreteColumnDescription>,
num_rows: usize,
Expand Down Expand Up @@ -191,7 +194,10 @@ mod test {

#[test]
fn hdu_types() {
let image_info = HduInfo::ImageInfo { shape: Vec::new() };
let image_info = HduInfo::ImageInfo {
shape: Vec::new(),
image_type: ImageType::LONGLONG_IMG,
};

let table_info = HduInfo::TableInfo {
column_descriptions: Vec::new(),
Expand Down