44PifIO::PifIO(
const string & fname,
IOMode rw)
129 if (fread(&
pfh,
sizeof(PifFileHeader), 1,
file) != 1) {
141 string desc =
"only support PIF with all projects having the same dimensions";
170 const int *data =
static_cast < const int *
>(first_block);
173 int endian = data[7];
174 bool data_big_endian =
false;
176 data_big_endian =
true;
212 (pih_sz + image_size *
mode_size) * image_index;
225 int pih_sz =
sizeof(PifImageHeader);
228 if (fread(&pih, pih_sz, 1,
file) != 1) {
233 int xlen = 0, ylen = 0, zlen = 0;
242 dict[
"apix_x"] =
static_cast < float >(pih.xlen);
243 dict[
"apix_y"] =
static_cast < float >(pih.ylen);
244 dict[
"apix_z"] =
static_cast < float >(pih.zlen);
246 dict[
"minimum"] =
static_cast < float >(pih.min);
247 dict[
"maximum"] =
static_cast < float >(pih.max);
248 dict[
"mean"] =
static_cast < float >(pih.mean);
249 dict[
"sigma"] =
static_cast < float >(pih.sigma);
251 dict[
"origin_x"] =
static_cast < float >(pih.xorigin);
252 dict[
"origin_y"] =
static_cast < float >(pih.yorigin);
278 struct tm *t = localtime(&t0);
285 int nx1 = dict[
"nx"];
286 int ny1 = dict[
"ny"];
287 int nz1 = dict[
"nz"];
292 LOGERR(
"cannot write to different size file %s (%dx%dx%d != %dx%dx%d)",
309 sprintf(
pfh.
program,
"EMAN %d/%02d/%02d", t->tm_mon, t->tm_mday, t->tm_year);
317 fwrite(&
pfh,
sizeof(PifFileHeader), 1,
file);
321 memset(&pih, 0,
sizeof(PifImageHeader));
327 pih.xlen = dict[
"apix_x"];
328 pih.ylen = dict[
"apix_y"];
329 pih.zlen = dict[
"apix_z"];
336 pih.min = dict[
"minimum"];
337 pih.max = dict[
"maximum"];
338 pih.mean = dict[
"mean"];
339 pih.sigma = dict[
"sigma"];
341 pih.xorigin = dict[
"origin_x"];
342 pih.yorigin = dict[
"origin_y"];
344 sprintf(pih.time,
"%d/%02d/%02d %d:%02d",
345 t->tm_mon, t->tm_mday, t->tm_year, t->tm_hour, t->tm_min);
346 fwrite(&pih,
sizeof(PifImageHeader), 1,
file);
359 int pih_sz =
sizeof(PifImageHeader);
362 if (fread(&pih, pih_sz, 1,
file) != 1) {
371 int num_layers = pih.nz;
379 unsigned char * cdata = (
unsigned char*)data;
380 short *sdata = (
short*) data;
386 int xlen = 0, ylen = 0, zlen = 0;
388 size_t size = xlen * ylen * zlen;
392 become_host_endian< float >(data, size);
403 for (
size_t i = 0; i < size; i++) {
404 size_t j = size - 1 - i;
409 for (
size_t i = 0; i < size; i++) {
410 size_t j = size - 1 - i;
415 for (
size_t i = 0; i < size; i++) {
416 size_t j = size - 1 - i;
426 unsigned char *buf =
new unsigned char[buf_size];
428 for (
int l = 0; l < num_layers; l++) {
430 for (
int j = 0; j <
pfh.
ny; j++) {
447 int offset2 = offset1 + j *
pfh.
nx;
449 for (
int k = 0; k <
pfh.
nx; k++) {
453 curr_data = (float) buf[k];
456 curr_data = (float) ((
short *) buf)[k];
459 curr_data = (float) ((
int *) buf)[k];
497 int *buf =
new int[nx];
498 for (
int i = 0; i < nz; i++) {
499 for (
int j = 0; j < ny; j++) {
500 for (
int k = 0; k <
pfh.
nx; k++) {
501 idx = i * nx * ny + j * nx + k;
502 buf[k] = (int) data[idx];
504 fwrite(buf,
sizeof(
int) * nx, 1,
file);
608 LOGERR(
"unknown PIF mode: %d", e);
static bool is_host_big_endian()
static void swap_bytes(T *data, size_t n=1)
swap the byte order of data with 'n' T-type elements.
static bool is_data_big_endian(const T *small_num_addr)
given a pointer to a reasonable small integer number, return whether the number is big endian or not.
Dict is a dictionary to store <string, EMObject> pair.
static void process_region_io(void *cdata, FILE *file, int rw_mode, int image_index, size_t mode_size, int nx, int ny, int nz=1, const Region *area=0, bool need_flip=false, ImageType imgtype=IMAGE_UNKNOWN, int pre_row=0, int post_row=0)
Process image region IO.
EMDataType
Image pixel data type used in EMAN.
static void get_region_dims(const Region *area, int nx, int *area_x, int ny, int *area_y, int nz=1, int *area_z=0)
Get a region's dimensions.
FloatSize is used to describe a 1D, 2D or 3D rectangular size in floating numbers.
ImageIO classes are designed for reading/writing various electron micrography image formats,...
void check_region(const Region *area, const FloatSize &max_size, bool is_new_file=false, bool inbounds_only=true)
Validate image I/O region.
virtual void flush()=0
Flush the IO buffer.
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 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 bool is_complex_mode()=0
Is this an complex image or not.
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.
FILE * sfopen(const string &filename, IOMode mode, bool *is_new=0, bool overwrite=false)
Run fopen safely.
void check_read_access(int image_index)
Validate 'image_index' in file reading.
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 void init()=0
Do some initialization before doing the read/write.
void check_write_access(IOMode rw_mode, int image_index, int max_nimg=0)
Validate rw_mode and image_index in file writing.
void become_host_endian(T *data, size_t n=1)
Convert data of this image into host endian format.
virtual bool is_image_big_endian()=0
Is this image in big endian or not.
bool is_float_int(int mode)
int get_mode_size(PifDataMode mode)
int get_nimg()
Return the number of images in this image file.
static bool is_valid(const void *first_block)
int to_em_datatype(int pif_datatype)
@ PIF_SHORT_FLOAT_COMPLEX
void fseek_to(int image_index)
int to_pif_datatype(int em_datatype)
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
#define ImageReadException(filename, desc)
#define ImageWriteException(imagename, desc)
int portable_fseek(FILE *fp, off_t offset, int whence)