#include <imageio.h>
Inheritance diagram for EMAN::ImageIO:
Public Types | |
READ_ONLY = 1 | |
READ_WRITE = 2 | |
WRITE_ONLY = 3 | |
enum | IOMode { READ_ONLY = 1, READ_WRITE = 2, WRITE_ONLY = 3 } |
Public Member Functions | |
virtual | ~ImageIO () |
virtual int | read_header (Dict &dict, int image_index=0, const Region *area=0, bool is_3d=false)=0 |
Read the header from an image. | |
virtual int | write_header (const Dict &dict, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0 |
Write a header to an image. | |
virtual int | read_data (float *data, int image_index=0, const Region *area=0, bool is_3d=false)=0 |
Read the data from an image. | |
virtual int | write_data (float *data, int image_index=0, const Region *area=0, EMUtil::EMDataType filestoragetype=EMUtil::EM_FLOAT, bool use_host_endian=true)=0 |
Write data to an image. | |
virtual int | read_ctf (Ctf &ctf, int image_index=0) |
Read CTF data from this image. | |
virtual void | write_ctf (const Ctf &ctf, int image_index=0) |
Write CTF data to this image. | |
virtual void | flush ()=0 |
Flush the IO buffer. | |
virtual int | get_nimg () |
Return the number of images in this image file. | |
virtual bool | is_complex_mode ()=0 |
Is this an complex image or not. | |
virtual bool | is_image_big_endian ()=0 |
Is this image in big endian or not. | |
virtual bool | is_single_image_format () const |
Is this image format only storing 1 image or not. | |
template<class T> | |
void | become_host_endian (T *data, size_t n=1) |
Convert data of this image into host endian format. | |
Protected Member Functions | |
virtual void | init ()=0 |
Do some initialization beforing doing the read/write. | |
void | check_read_access (int image_index) |
Validate 'image_index' in file reading. | |
void | check_read_access (int image_index, const float *data) |
Validate 'image_index' and 'data' in file reading. | |
void | check_write_access (IOMode rw_mode, int image_index, int max_nimg=0) |
Validate rw_mode and image_index in file writing. | |
void | check_write_access (IOMode rw_mode, int image_index, int max_nimg, const float *data) |
Validate rw_mode, image_index, and data pointer in file writing. | |
void | check_region (const Region *area, const FloatSize &max_size, bool is_new_file=false, bool inbounds_only=true) |
Validate image I/O region. | |
void | check_region (const Region *area, const IntSize &max_size, bool is_new_file=false, bool inbounds_only=true) |
Validate image I/O region. | |
FILE * | sfopen (const string &filename, IOMode mode, bool *is_new=0, bool overwrite=false) |
Run fopen safely. |
ImageIO class is the base class for all image io classes. Each subclass defines the IO routines for reading/writing a type of image format. For example, MrcIO is for reading/writing MRC images.
A subclass should implement functions declared in DEFINE_IMAGEIO_FUNC macro.
Image header I/O is separated from image data I/O.
Some image formats (e.g., MRC, DM3, Gatan2, TIFF, PNG, EM, ICOS) only store a single 2D or 3D images. For them, image_index should always be 0. To read/write part of the image, use a region.
Some image formats (e.g., Imagic) can store either a stack of 2D images or a single 3D image. From the physical image file itself, there is no difference between them. Only at reading time, they may be treated as either a stack of 2D images, or a single 3D image. A boolean hint should be given for these formats at reading time.
Some image formats (e.g. HDF, PIF) can store a stack of images. Each image can be 2D or 3D.
For image formats storing multiple images, valid image_index = [0, n].
For image formats storing multiple images, the image append and insertion policy is:
Image region writing follows the following princeples:
Each ImageIO subclass XYZ must define a static function to determine whether a given image is a valid XYZ image or not. It looks like: static bool is_valid(const void *first_block); 'first_block' is the first block of binary data in that image file.
The typical way to use an ImageIO instance is: a) To read: ImageIO *imageio = EMUtil::get_imageio(filename, ImageIO::READ_ONLY); int err = imageio->read_header(dict, img_index, region, is_3d); err = imageio->read_ctf(ctf, img_index); err = imageio->read_data(data, img_index, region, is_3d);
b) To write: similar to read.
Definition at line 130 of file imageio.h.
ImageIO::~ImageIO | ( | ) | [virtual] |
void EMAN::ImageIO::become_host_endian | ( | T * | data, | |
size_t | n = 1 | |||
) | [inline] |
Convert data of this image into host endian format.
data | An array of data. It can be any type, short, int, float, double, etc. | |
n | Array size. |
Definition at line 245 of file imageio.h.
References EMAN::ByteOrder::is_host_big_endian(), is_image_big_endian(), and EMAN::ByteOrder::swap_bytes().
00246 { 00247 if (is_image_big_endian() != ByteOrder::is_host_big_endian()) { 00248 ByteOrder::swap_bytes(data, n); 00249 } 00250 }
void ImageIO::check_read_access | ( | int | image_index, | |
const float * | data | |||
) | [protected] |
Validate 'image_index' and 'data' in file reading.
image_index | The 'image_index'th image. Valid value = [0, nimg-1]. | |
data | The array used to store the image data in reading. |
NullPointerException | If 'data' is NULL. | |
OutofRangeException | If image_index is out of range. |
Definition at line 109 of file imageio.cpp.
References check_read_access(), and NullPointerException.
00110 { 00111 check_read_access(image_index); 00112 if (!data) { 00113 throw NullPointerException("image data is NULL"); 00114 } 00115 }
void ImageIO::check_read_access | ( | int | image_index | ) | [protected] |
Validate 'image_index' in file reading.
image_index | The 'image_index'th image. Valid value = [0, nimg-1]. |
OutofRangeException | If image_index is out of range. |
Definition at line 99 of file imageio.cpp.
References get_nimg(), init(), and OutofRangeException.
Referenced by check_read_access().
00100 { 00101 init(); 00102 00103 int nimg = get_nimg(); 00104 if (image_index < 0 || image_index >= nimg) { 00105 throw OutofRangeException(0, nimg-1, image_index, "image index"); 00106 } 00107 }
void ImageIO::check_region | ( | const Region * | area, | |
const IntSize & | max_size, | |||
bool | is_new_file = false , |
|||
bool | inbounds_only = true | |||
) | [protected] |
Validate image I/O region.
area | The image I/O region. | |
max_size | The upper limit of the region's size. The region must be within 'max_size'. | |
is_new_file | Whether it is on a new file or not. | |
inbounds_only | if true verifies that the region is inside the image, otherwise no check is performed |
ImageReadException | Any image reading problem. |
Definition at line 92 of file imageio.cpp.
References check_region().
00094 { 00095 check_region(area, FloatSize(max_size[0], max_size[1], max_size[2]), 00096 is_new_file,inbounds_only); 00097 }
void ImageIO::check_region | ( | const Region * | area, | |
const FloatSize & | max_size, | |||
bool | is_new_file = false , |
|||
bool | inbounds_only = true | |||
) | [protected] |
Validate image I/O region.
area | The image I/O region. | |
max_size | The upper limit of the region's size. The region must be within 'max_size'. | |
is_new_file | Whether it is on a new file or not. | |
inbounds_only | if true verifies that the region is inside the image, otherwise no check is performed |
ImageReadException | Any image reading problem. |
Definition at line 62 of file imageio.cpp.
References EMAN::Region::get_ndim(), EMAN::FloatSize::get_ndim(), EMAN::Region::get_string(), ImageReadException, and EMAN::Region::is_region_in_box().
Referenced by check_region(), EMAN::MrcIO::read_fei_header(), EMAN::MrcIO::read_mrc_header(), EMAN::SpiderIO::write_single_data(), and EMAN::SpiderIO::write_single_header().
00064 { 00065 if (area) { 00066 if (is_new_file) { 00067 throw ImageReadException("", "file must exist before accessing its region"); 00068 } 00069 int img_ndim = max_size.get_ndim(); 00070 int area_ndim = area->get_ndim(); 00071 00072 if (area_ndim > img_ndim) { 00073 char desc[256]; 00074 sprintf(desc, "Image is %dD. Cannot read %dD region", img_ndim, area_ndim); 00075 throw ImageReadException("", desc); 00076 } 00077 00078 // EMUtil::process_region_io handles regions that are outside the image. So some image types don't mind if the 00079 // region is beyond the boundary. It would be ideal if they all could do this, but it would take some work. 00080 if (inbounds_only ){ 00081 if (!area->is_region_in_box(max_size)) { 00082 char desc[1024]; 00083 sprintf(desc, "Region box %s is outside image area (%d,%d,%d)", 00084 area->get_string().c_str(), (int)max_size[0], 00085 (int)max_size[1], (int)max_size[2]); 00086 throw ImageReadException("", desc); 00087 } 00088 } 00089 } 00090 }
void ImageIO::check_write_access | ( | IOMode | rw_mode, | |
int | image_index, | |||
int | max_nimg, | |||
const float * | data | |||
) | [protected] |
Validate rw_mode, image_index, and data pointer in file writing.
rw_mode | File Read/Write mode. | |
image_index | The 'image_index'th image. Valid value = [0, max_nimg]. | |
max_nimg | Maximum number of images in the file. If its value <= 0, don't check image_index againt max_nimg. | |
data | The data array to be writting to the image file. |
ImageWriteException | Image is not opened for writing. | |
OutofRangeException | If image_index is out of range. |
Definition at line 130 of file imageio.cpp.
References check_write_access(), and NullPointerException.
00132 { 00133 check_write_access(iomode, image_index, max_nimg); 00134 if (!data) { 00135 throw NullPointerException("image data is NULL"); 00136 } 00137 }
void ImageIO::check_write_access | ( | IOMode | rw_mode, | |
int | image_index, | |||
int | max_nimg = 0 | |||
) | [protected] |
Validate rw_mode and image_index in file writing.
rw_mode | File Read/Write mode. | |
image_index | The 'image_index'th image. Valid value = [0, max_nimg]. | |
max_nimg | Maximum number of images in the file. If its value <= 0, don't check image_index against max_nimg. |
ImageWriteException | Image is not opened for writing. | |
OutofRangeException | If image_index is out of range. |
Definition at line 117 of file imageio.cpp.
References ImageWriteException, init(), OutofRangeException, and READ_ONLY.
Referenced by check_write_access(), EMAN::SpiderIO::write_single_data(), and EMAN::SpiderIO::write_single_header().
00118 { 00119 init(); 00120 00121 if (iomode == READ_ONLY) { 00122 throw ImageWriteException("", "File is not openned to write"); 00123 } 00124 00125 if ((image_index < -1) || (max_nimg > 0 && image_index >= max_nimg)) { 00126 throw OutofRangeException(-1, max_nimg - 1, image_index, "image index"); 00127 } 00128 }
virtual void EMAN::ImageIO::flush | ( | ) | [pure virtual] |
int ImageIO::get_nimg | ( | ) | [virtual] |
Return the number of images in this image file.
Reimplemented in EMAN::EmimIO, EMAN::ImagicIO, EMAN::ImagicIO2, EMAN::LstFastIO, EMAN::LstIO, EMAN::MrcIO, EMAN::PifIO, EMAN::XYZIO, EMAN::SerIO, and EMAN::SpiderIO.
Definition at line 185 of file imageio.cpp.
References init().
Referenced by check_read_access(), and EMAN::EMUtil::get_image_count().
00186 { 00187 init(); 00188 return 1; 00189 }
virtual void EMAN::ImageIO::init | ( | ) | [protected, pure virtual] |
Do some initialization beforing doing the read/write.
Referenced by check_read_access(), check_write_access(), EMAN::SpiderIO::get_nimg(), EMAN::SerIO::get_nimg(), EMAN::PifIO::get_nimg(), EMAN::MrcIO::get_nimg(), EMAN::LstIO::get_nimg(), EMAN::LstFastIO::get_nimg(), EMAN::XYZIO::get_nimg(), EMAN::ImagicIO2::get_nimg(), EMAN::ImagicIO::get_nimg(), get_nimg(), EMAN::EmimIO::get_nimg(), EMAN::MrcIO::read_ctf(), EMAN::FitsIO::read_ctf(), EMAN::MrcIO::read_fei_header(), EMAN::MrcIO::write_ctf(), EMAN::ImagicIO2::write_ctf(), EMAN::ImagicIO::write_ctf(), and EMAN::FitsIO::write_ctf().
virtual bool EMAN::ImageIO::is_complex_mode | ( | ) | [pure virtual] |
Is this an complex image or not.
Referenced by EMAN::EMData::read_binedimage(), EMAN::EMData::read_image(), and EMAN::MrcIO::read_mrc_header().
virtual bool EMAN::ImageIO::is_image_big_endian | ( | ) | [pure virtual] |
Is this image in big endian or not.
Referenced by become_host_endian(), and EMAN::EMData::save_byteorder_to_dict().
virtual bool EMAN::ImageIO::is_single_image_format | ( | ) | const [inline, virtual] |
Is this image format only storing 1 image or not.
Some image formats like MRC only store 1 image in a file, so this function returns 'true' for them. Other image formats like IMAGIC/HDF5 may store mutliple images, so this function returns 'false' for them.
Reimplemented in EMAN::EmimIO, EMAN::ImagicIO, EMAN::ImagicIO2, EMAN::LstFastIO, EMAN::LstIO, EMAN::PifIO, EMAN::SpiderIO, and EMAN::SingleSpiderIO.
Definition at line 234 of file imageio.h.
Referenced by EMAN::EMData::write_image().
int ImageIO::read_ctf | ( | Ctf & | ctf, | |
int | image_index = 0 | |||
) | [virtual] |
Read CTF data from this image.
ctf | Used to store the CTF data. | |
image_index | The index of the image to read. |
Reimplemented in EMAN::FitsIO, and EMAN::MrcIO.
Definition at line 52 of file imageio.cpp.
virtual int EMAN::ImageIO::read_data | ( | float * | data, | |
int | image_index = 0 , |
|||
const Region * | area = 0 , |
|||
bool | is_3d = false | |||
) | [pure virtual] |
Read the data from an image.
data | An array to store the data. It should be created outside of this function. | |
image_index | The index of the image to read. | |
area | Define an image-region to read. | |
is_3d | Whether to treat the image as a single 3D or a set of 2Ds. This is a hint for certain image formats which has no difference between 3D image and set of 2Ds. |
Referenced by EMAN::EMData::read_image().
virtual int EMAN::ImageIO::read_header | ( | Dict & | dict, | |
int | image_index = 0 , |
|||
const Region * | area = 0 , |
|||
bool | is_3d = false | |||
) | [pure virtual] |
Read the header from an image.
dict | A keyed-dictionary to store the header information. | |
image_index | The index of the image to read. | |
area | Define an image-region to read. | |
is_3d | Whether to treat the image as a single 3D or a set of 2Ds. This is a hint for certain image formats which has no difference between 3D image and set of 2Ds. |
Referenced by EMAN::EMData::read_binedimage(), and EMAN::EMData::read_image().
FILE * ImageIO::sfopen | ( | const string & | filename, | |
IOMode | mode, | |||
bool * | is_new = 0 , |
|||
bool | overwrite = false | |||
) | [protected] |
Run fopen safely.
filename | The file name to be opened. | |
mode | File open mode. | |
is_new | Is this a new file? | |
overwrite | If the file exists, should we truncate it? |
FileAccessException | The file has access error. |
Definition at line 139 of file imageio.cpp.
References FileAccessException, READ_ONLY, READ_WRITE, and WRITE_ONLY.
00141 { 00142 FILE *f = 0; 00143 if (mode == READ_ONLY) { 00144 f = fopen(filename.c_str(), "rb"); 00145 } 00146 else if (mode == READ_WRITE) { 00147 if (overwrite) { 00148 f = fopen(filename.c_str(), "wb"); 00149 if (is_new) { 00150 *is_new = true; 00151 } 00152 } 00153 else { 00154 f = fopen(filename.c_str(), "r+b"); 00155 if (!f) { 00156 FILE *f1 = fopen(filename.c_str(), "wb"); 00157 if (!f1) { 00158 throw FileAccessException(filename); 00159 } 00160 else { 00161 if (is_new) { 00162 *is_new = true; 00163 } 00164 fclose(f1); 00165 f1 = 0; 00166 f = fopen(filename.c_str(), "r+b"); 00167 } 00168 } 00169 } 00170 } 00171 else if (mode == WRITE_ONLY) { 00172 f = fopen(filename.c_str(), "wb"); 00173 if (is_new) { 00174 *is_new = true; 00175 } 00176 } 00177 00178 if (!f) { 00179 throw FileAccessException(filename); 00180 } 00181 return f; 00182 }
void ImageIO::write_ctf | ( | const Ctf & | ctf, | |
int | image_index = 0 | |||
) | [virtual] |
Write CTF data to this image.
ctf | Ctf instance storing the CTF data. | |
image_index | The index of the image to write. |
Reimplemented in EMAN::FitsIO, and EMAN::MrcIO.
Definition at line 57 of file imageio.cpp.
virtual int EMAN::ImageIO::write_data | ( | float * | data, | |
int | image_index = 0 , |
|||
const Region * | area = 0 , |
|||
EMUtil::EMDataType | filestoragetype = EMUtil::EM_FLOAT , |
|||
bool | use_host_endian = true | |||
) | [pure virtual] |
Write data to an image.
data | An array storing the data. | |
image_index | The index of the image to write. | |
area | The region to write data to. | |
filestoragetype | The image data type used in the output file. | |
use_host_endian | Whether to use the host machine endian to write out or not. If false, use the endian opposite to the host machine's endian. |
Implemented in EMAN::SingleSpiderIO.
Referenced by EMAN::EMData::write_image().
virtual int EMAN::ImageIO::write_header | ( | const Dict & | dict, | |
int | image_index = 0 , |
|||
const Region * | area = 0 , |
|||
EMUtil::EMDataType | filestoragetype = EMUtil::EM_FLOAT , |
|||
bool | use_host_endian = true | |||
) | [pure virtual] |
Write a header to an image.
dict | A keyed-dictionary storing the header information. | |
image_index | The index of the image to write. | |
area | The region to write data to. | |
filestoragetype | The image data type used in the output file. | |
use_host_endian | Whether to use the host machine endian to write out or not. If false, use the endian opposite to the host machine's endian. |
Implemented in EMAN::SingleSpiderIO.
Referenced by EMAN::EMData::write_image().