45SerIO::SerIO(
const string & fname,
IOMode rw) :
47 is_new_file(false), data_offset_array(0),tag_offset_array(0),
48 nimg(0), nx(0), ny(0), nz(0), datatypeid(0), datamode(0)
82 if (fread(&
serh,
sizeof(SerHeader), 1,
file) != 1) {
102 const short *data =
static_cast < const short *
>(first_block);
104 short SeriesID = data[1];
106 if(
ByteOrder != 0x4949 || SeriesID != 0x0197) {
121 if (fread(hitem1,
sizeof(
short), 3,
file) != 3) {
125 dict[
"SER.ByteOrder"] = hitem1[0];
126 dict[
"SER.SeriesID"] = hitem1[1];
127 dict[
"SER.SeriesVersion"] = hitem1[2];
133 uint64_t offset_array;
134 if (hitem1[2]==0x210) {
135 if (fread(hitem2,
sizeof(
int), 6,
file) != 6) {
138 dict[
"SER.OffsetArrayOffset"] = hitem2[4];
139 offset_array=(uint64_t)hitem2[4];
142 if (fread(hitem2,
sizeof(
int), 4,
file) != 4) {
145 fread(&offset_array, 8,1,
file);
146 fread(&hitem2[5],4,1,
file);
151 dict[
"SER.DataTypeID"] = hitem2[0];
152 dict[
"SER.TagTypeID"] = hitem2[1];
153 dict[
"SER.TotalNumberElements"] = hitem2[2];
154 dict[
"SER.ValidNumberElements"] = hitem2[3];
155 dict[
"SER.NumberDimensions"] = hitem2[5];
157 nimg = (int)dict[
"SER.ValidNumberElements"];
159 if(image_index >= (
int)dict[
"SER.ValidNumberElements"]) {
163 for(
int idx=0; idx<(int)dict[
"SER.NumberDimensions"]; idx++) {
171 int tot = (int)dict[
"SER.TotalNumberElements"];
175 if (hitem1[2]==0x210) {
176 int *off=
new int[tot*2];
177 if (fread(off, 4, tot*2,
file) != (
unsigned int)tot*2) {
180 for (
int i=0; i<tot; i++) {
195 this->
datatypeid = (int)dict[
"SER.DataTypeID"];
232 size_t size = (size_t)
nx *
ny *
nz;
236 unsigned char * puchar = 0;
239 unsigned int * puint = 0;
241 unsigned short * pushort = 0;
242 double * pdouble = 0;
256 puchar =
new unsigned char[size];
257 if (fread(puchar,
sizeof(
unsigned char), size,
file) != size) {
260 for (i = 0; i<size; ++i) {
261 rdata[i] =
static_cast<float>(puchar[i]);
266 pushort =
new unsigned short[size];
267 if (fread(pushort,
sizeof(
unsigned short), size,
file) != size) {
270 for (i = 0; i<size; ++i) {
271 rdata[i] =
static_cast<float>(pushort[i]);
276 puint =
new unsigned int[size];
277 if (fread(puint,
sizeof(
unsigned int), size,
file) != size) {
280 for (i = 0; i<size; ++i) {
281 rdata[i] =
static_cast<float>(puint[i]);
286 pchar =
new char[size];
287 if (fread(pchar,
sizeof(
unsigned char), size,
file) != size) {
290 for (i = 0; i<size; ++i) {
291 rdata[i] =
static_cast<float>(pchar[i]);
296 pshort =
new short[size];
297 if (fread(pshort,
sizeof(
short), size,
file) != size) {
300 for (i = 0; i<size; ++i) {
301 rdata[i] =
static_cast<float>(pshort[i]);
306 pint =
new int[size];
307 if (fread(pint,
sizeof(
int), size,
file) != size) {
310 for (i = 0; i<size; ++i) {
311 rdata[i] =
static_cast<float>(pint[i]);
316 if (fread(
rdata,
sizeof(
float), size,
file) != size) {
321 pdouble =
new double[size];
322 if (fread(pdouble,
sizeof(
double), size,
file) != size) {
325 for (i = 0; i<size; ++i) {
326 rdata[i] =
static_cast<float>(pdouble[i]);
373 if (fread(&
nimg,
sizeof(
int), 1,
file) != 1) {
383 if (fread(&dimsize,
sizeof(
int), 1,
file) != 1) {
388 dict[
"SER.DimensionSize"+sidx] = dimsize;
391 if (fread(hitem3,
sizeof(
double), 2,
file) != 2) {
394 dict[
"SER.CalibrationOffset"+sidx] = hitem3[0];
395 dict[
"SER.CalibrationDelta"+sidx] = hitem3[1];
398 if (fread(&celement,
sizeof(
int), 1,
file) != 1) {
401 dict[
"SER.CalibrationElement"+sidx] = celement;
404 if (fread(&desclen,
sizeof(
int), 1,
file) != 1) {
407 dict[
"SER.DescriptionLength"+sidx] = desclen;
410 char * descr =
new char[desclen+1];
412 if (fread(descr,
sizeof(
char), desclen,
file) != (
unsigned int)desclen) {
415 descr[desclen] =
'\0';
416 string sdescr(descr);
417 dict[
"SER.Description"+sidx] = sdescr;
422 if (fread(&unitslen,
sizeof(
int), 1,
file) != 1) {
425 dict[
"SER.UnitsLength"+sidx] = unitslen;
428 char * units =
new char[unitslen+1];
430 if (fread(units,
sizeof(
int), unitslen,
file) != (
unsigned int)unitslen) {
433 units[unitslen] =
'\0';
434 string sunits(units);
435 dict[
"SER.Units"+sidx] = sunits;
445 if (fread(hitem4,
sizeof(
double), 2,
file) != 2) {
448 dict[
"SER.CalibrationOffset"] = hitem4[0];
449 dict[
"SER.CalibrationDelta"] = hitem4[1];
452 if (fread(&cali,
sizeof(
int), 1,
file) != 1) {
455 dict[
"SER.CalibrationElement"] = cali;
458 if (fread(&datatype,
sizeof(
short), 1,
file) != 1) {
461 dict[
"SER.DataType"] = datatype;
464 if (fread(&arrlen,
sizeof(
int), 1,
file) != 1) {
477 if (fread(hitem4,
sizeof(
double), 2,
file) != 2) {
480 dict[
"SER.CalibrationOffsetX"] = hitem4[0];
481 dict[
"SER.CalibrationDeltaX"] = hitem4[1];
484 if (fread(&calix,
sizeof(
int), 1,
file) != 1) {
487 dict[
"SER.CalibrationElementX"] = calix;
490 if (fread(hitem5,
sizeof(
double), 2,
file) != 2) {
493 dict[
"SER.CalibrationOffsetX"] = hitem5[0];
494 dict[
"SER.CalibrationDeltaX"] = hitem5[1];
497 if (fread(&caliy,
sizeof(
int), 1,
file) != 1) {
500 dict[
"SER.CalibrationElementY"] = caliy;
503 if (fread(&datatype,
sizeof(
short), 1,
file) != 1) {
506 dict[
"SER.DataType"] = datatype;
510 if (fread(&arrsize,
sizeof(
int), 2,
file) != 2) {
513 dict[
"nx"] = arrsize[0];
514 dict[
"ny"] = arrsize[1];
525 int tag_type = (int)dict[
"SER.TagTypeID"];
528 if (fread(&tagtype,
sizeof(
short), 1,
file) != 1) {
531 assert((
int)tagtype == tag_type);
534 if (fread(&sertime,
sizeof(
int), 1,
file) != 1) {
537 dict[
"SER.Time"] = sertime;
539 else if( tag_type ==
posTime ) {
541 if (fread(&tagtype,
sizeof(
short), 1,
file) != 1) {
544 assert((
int)tagtype == tag_type);
547 if (fread(&sertime,
sizeof(
int), 1,
file) != 1) {
550 dict[
"SER.Time"] = sertime;
553 if (fread(&pos,
sizeof(
double), 2,
file) != 2) {
556 dict[
"SER.PosionX"] = pos[0];
557 dict[
"SER.PosionY"] = pos[1];
ByteOrder defines functions to work on big/little endian byte orders.
Dict is a dictionary to store <string, EMObject> pair.
EMDataType
Image pixel data type used in EMAN.
ImageIO classes are designed for reading/writing various electron micrography image formats,...
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.
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.
virtual bool is_image_big_endian()=0
Is this image in big endian or not.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
void read_data_element(Dict &dict)
helper function to read header attributes in data element
static bool is_valid(const void *first_block)
void read_data_tag(Dict &dict)
helper function to read header attributes in data tag
int get_nimg()
Return the number of images in this image file.
void read_dim_arr(Dict &dict, int idx)
helper function to read attributes in dimension array
uint64_t * data_offset_array
uint64_t * tag_offset_array
static string int2str(int n)
Get a string format of an integer, e.g.
#define ImageReadException(filename, desc)
#define ImageWriteException(imagename, desc)
int portable_fseek(FILE *fp, off_t offset, int whence)
static const int ValidNumberElementsOffset
static const short SER_BYTE_ORDER
static const short SER_SERIES_ID