41const char *TagTable::IMAGE_WIDTH_TAG =
"Dimensions #0";
42const char *TagTable::IMAGE_HEIGHT_TAG =
"Dimensions #1";
43const char *TagTable::IMAGE_DATATYPE_TAG =
"DataType";
44const char *TagTable::IMAGE_THUMB_INDEX_TAG =
"ImageIndex";
47 : img_index(0), is_big_endian(true)
53 for (
unsigned int i = 0; i <
data_list.size(); i++) {
63 const char *value_str = value.c_str();
66 x_list.push_back(atoi(value_str));
69 y_list.push_back(atoi(value_str));
99 return atoi(
tags[name].c_str());
104 return static_cast < float >(atof(
tags[name].c_str()));
109 return atof(
tags[name].c_str());
114 map < string, string >::const_iterator p;
116 for (p =
tags.begin(); p !=
tags.end(); p++) {
118 printf(
" %s: %s\n", (*p).first.c_str(), (*p).second.c_str());
144 if (i != 0 && i != 1) {
158 : in(data_file), tagtable(table), name(tagname), tag_type(UNKNOWN)
174 nr = fread(&val, sz, 1,
in); nr++;
176 sprintf(val_str,
"%d", val);
179 unsigned short val = 0;
180 nr = fread(&val, sz, 1,
in); nr++;
182 sprintf(val_str,
"%d", val);
186 nr = fread(&val, sz, 1,
in); nr++;
188 sprintf(val_str,
"%d", val);
192 nr = fread(&val, sz, 1,
in); nr++;
193 sprintf(val_str,
"%d", val);
197 nr = fread(&val, sz, 1,
in); nr++;
199 sprintf(val_str,
"%d", val);
202 unsigned int val = 0;
203 nr = fread(&val, sz, 1,
in); nr++;
205 sprintf(val_str,
"%d", (
int) val);
209 nr = fread(&val, sz, 1,
in); nr++;
211 sprintf(val_str,
"%f", val);
215 nr = fread(&val, sz, 1,
in); nr++;
217 sprintf(val_str,
"%10e", val);
224 if (is_value_stored) {
228 LOGVAR(
"value = '%s'", val_str);
230 return string(val_str);
235 LOGVAR(
"TagData::read_array_types()");
239 nr = fread(&array_type,
sizeof(array_type), 1,
in); nr++;
245 vector < int >item_types;
247 if (array_type ==
STRUCT) {
250 else if (array_type ==
ARRAY) {
252 LOGERR(
"DM3: don't know how to handle this array type");
255 item_types.push_back(array_type);
269 unsigned short *buf =
new unsigned short[size];
270 char *str =
new char[size + 1];
273 nr = fread(buf, size *
sizeof(
unsigned short), 1,
in); nr++;
276 for (
int i = 0; i < size; i++) {
277 str[i] =
static_cast < char >(buf[i]);
281 string str1 = string(str);
299 if (item_types.size() == 0) {
300 LOGERR(
"DM3 item types cannot be empty");
308 nr = fread(&array_size,
sizeof(array_size), 1,
in); nr++;
311 LOGVAR(
"array size = %d\n", array_size);
313 size_t item_size = 0;
314 for (
size_t i = 0; i < item_types.size(); i++) {
315 item_size +=
typesize(item_types[i]);
318 LOGVAR(
"%s array item size = %d\n",
name.c_str(), item_size);
320 size_t buf_size = item_size * array_size;
322 if (item_types.size() == 1 && item_types[0] ==
USHORT && nodata) {
325 LOGVAR(
"value: %s", val.c_str());
327 else if (!nodata &&
name ==
"Data") {
328 char *data =
new char[buf_size];
329 nr = fread(data, buf_size, 1,
in); nr++;
331 if (item_size ==
sizeof(
short)) {
334 else if (item_size ==
sizeof(
int)) {
337 else if (item_size ==
sizeof(
double)) {
341 LOGERR(
"cannot handle this type of DM3 image data");
356 LOGVAR(
"TagData::read_struct_types()");
358 unsigned int namelength = 0;
359 unsigned int nfields = 0;
362 nr = fread(&namelength,
sizeof(namelength), 1,
in); nr++;
365 nr = fread(&nfields,
sizeof(nfields), 1,
in); nr++;
368 LOGVAR(
"namelength = %d\n", namelength);
369 LOGVAR(
"num fields = %d\n", nfields);
371 vector < int >field_types;
373 for (
unsigned int i = 0; i < nfields; i++) {
374 nr = fread(&namelength,
sizeof(namelength), 1,
in); nr++;
378 nr = fread(&field_type,
sizeof(field_type), 1,
in); nr++;
381 LOGVAR(
"%dth namelength = %d, type = '%s'",
383 field_types.push_back(field_type);
405 for (
unsigned int i = 0; i < field_types.size(); i++) {
409 sprintf(int_str,
" #%d", i);
410 string fieldname =
name + string(int_str);
416 nr = fread(&str_sz,
sizeof(str_sz), 1,
in); nr++;
419 char *val =
new char[str_sz + 1];
420 nr = fread(val, str_sz, 1,
in); nr++;
422 string val_str = string(val);
440 LOGVAR(
"TagData::read()");
443 const char *DATA_TYPE_MARK =
"%%%%";
444 const size_t mark_sz = strlen(DATA_TYPE_MARK);
445 char *mark =
new char[mark_sz + 1];
448 nr = fread(mark, mark_sz, 1,
in); nr++;
449 mark[mark_sz] =
'\0';
451 if (strcmp(mark, DATA_TYPE_MARK) != 0) {
452 LOGERR(
"data type label has been changed from '%s' to '%s'",
453 DATA_TYPE_MARK, mark);
462 int encoded_types_size = 0;
463 nr = fread(&encoded_types_size,
sizeof(
int), 1,
in); nr++;
466 LOGVAR(
"encoded types size = %d\n", encoded_types_size);
481 Type type =
static_cast < Type > (t);
485 size =
sizeof(short);
488 size =
sizeof(
unsigned short);
494 size =
sizeof(
unsigned int);
497 size =
sizeof(float);
500 size =
sizeof(double);
510 LOGERR(
"no such type: '%d'\n", type);
520 : in(data_file), tagtable(table), name(groupname), entry_id(0)
530 LOGVAR(
"TagGroup::read()");
536 nr = fread(&ntags,
sizeof(ntags), 1,
in); nr++;
540 LOGVAR(
"DM3: ntags = %d\n", ntags);
544 for (
int i = 0; i < ntags; i++) {
546 err = tag_entry.
read(nodata);
571 : in(data_file), tagtable(table), parent_group(parent), name(
"")
581 LOGVAR(
"TagEntry::read()");
587 nr = fread(&tag_type,
sizeof(
char), 1,
in); nr++;
590 LOGERR(
"TagEntry::read() invalid tag type: %d", tag_type);
595 nr = fread(&name_len,
sizeof(
short), 1,
in); nr++;
599 tmp_name =
new char[name_len + 1];
600 nr = fread(tmp_name, name_len, 1,
in); nr++;
601 tmp_name[name_len] =
'\0';
605 name_len =
static_cast < short >(parent_name.size() + 4);
606 tmp_name =
new char[name_len + 1];
610 name = string(tmp_name);
617 LOGVAR(
"\ntag name: '%s', len: %d, type: '%s'",
622 err = tag_data.
read(nodata);
626 err = group.
read(nodata);
668 if (fread(buf,
sizeof(buf), 1,
file) != 1) {
676 int byte_order = buf[2];
678 if (byte_order == 0) {
688 LOGDEBUG(
"dm3 ver = %d, image size = %d, is_big_endian = %d",
702 const int *data =
static_cast < const int *
>(first_block);
704 int img_ver = data[0];
705 int img_size = data[1];
706 int byte_order = data[2];
717 if (byte_order != 0 && byte_order != 1) {
736 if(image_index == -1) {
744 root_group.read(
true);
750 int xlen = 0, ylen = 0;
770 dict[
"microscope_voltage"]=(float)dict[
"DM3.voltage"];
772 dict[
"microscope_cs"]=(float)dict[
"DM3.cs"];
781 if ((
float)dict[
"DM3.actual_mag"] >0.0) {
782 float apix=10000.0*(float)dict[
"DM3.pixel_size"]/(
float)dict[
"DM3.actual_mag"];
804 root_group.read(
false);
811 int xlen = 0, ylen = 0, x0 = 0, y0 = 0;
820 int xlast = x0 + xlen;
821 int ylast = y0 + ylen;
824 bool flip_vertical =
true;
826 for (
int iy = y0; iy < ylast; iy++) {
828 off = (y0 + ylast - 1 - iy) * nx;
834 for (
int ix = x0; ix < xlast; ix++) {
837 rdata[k] = (float) ((
char *) data)[off + ix];
840 rdata[k] = (float) ((
unsigned char *) data)[off + ix];
843 rdata[k] = (float) ((
short *) data)[off + ix];
846 rdata[k] = (float) ((
unsigned short *) data)[off + ix];
849 rdata[k] = (float) ((
int *) data)[off + ix];
852 rdata[k] = (float) ((
unsigned int *) data)[off + ix];
855 rdata[k] = (float) ((
float *) data)[off + ix];
858 string desc = string(
"unsupported DM3 data type") +
877 LOGWARN(
"DM3 write is not supported.");
885 LOGWARN(
"DM3 write is not supported.");
927 const char *str =
"unknown";
936 case TagData::USHORT:
937 str =
"unsigned short";
940 str =
"unsigned int";
945 case TagData::DOUBLE:
948 case TagData::BOOLEAN:
957 case TagData::STRUCT:
960 case TagData::STRING:
974 const char *str =
"unknown";
977 case TagEntry::GROUP_TAG:
980 case TagEntry::DATA_TAG:
993 return "SIGNED_INT16_DATA";
997 return "COMPLEX8_DATA";
999 return "OBSELETE_DATA";
1001 return "PACKED_DATA";
1003 return "UNSIGNED_INT8_DATA";
1005 return "SIGNED_INT32_DATA";
1009 return "SIGNED_INT8_DATA";
1011 return "UNSIGNED_INT16_DATA";
1013 return "UNSIGNED_INT32_DATA";
1015 return "REAL8_DATA";
1017 return "COMPLEX16_DATA";
1019 return "BINARY_DATA";
1021 return "RGB_UINT8_0_DATA";
1023 return "RGB_UINT8_1_DATA";
1025 return "RGB_UINT16_DATA";
1027 return "RGB_FLOAT32_DATA";
1029 return "RGB_FLOAT64_DATA";
1031 return "RGBA_UINT8_0_DATA";
1033 return "RGBA_UINT8_1_DATA";
1035 return "RGBA_UINT8_2_DATA";
1037 return "RGBA_UINT8_3_DATA";
1039 return "RGBA_UINT16_DATA";
1041 return "RGBA_FLOAT32_DATA";
1043 return "RGBA_FLOAT64_DATA";
1045 return "POINT2_SINT16_0_DATA";
1047 return "POINT2_SINT16_1_DATA";
1049 return "POINT2_SINT32_0_DATA";
1051 return "POINT2_FLOAT32_0_DATA";
1053 return "RECT_SINT16_1_DATA";
1055 return "RECT_SINT32_1_DATA";
1057 return "RECT_FLOAT32_1_DATA";
1059 return "RECT_FLOAT32_0_DATA";
1061 return "SIGNED_INT64_DATA";
1063 return "UNSIGNED_INT64_DATA";
1067 return "Unknown Type";
static bool is_host_big_endian()
static void become_big_endian(T *data, size_t n=1)
convert data from host byte order to big endian order.
DM3IO(const string &fname, IOMode rw_mode=READ_ONLY)
Gatan::TagTable * tagtable
static bool is_valid(const void *first_block)
Dict is a dictionary to store <string, EMObject> pair.
EMDataType
Image pixel data type used in EMAN.
static void get_region_origins(const Region *area, int *p_x0, int *p_y0, int *p_z0=0, int nz=1, int image_index=0)
Get a region's original locations.
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.
int read_array_data(vector< int >item_types, bool nodata=false)
string read_string(int size)
int read_any(bool nodata=false)
TagData(FILE *data_file, TagTable *tagtable, const string &tagname)
vector< int > read_array_types()
string read_native(bool is_value_stored)
vector< int > read_struct_types()
int read(bool nodata=false)
int read(bool nodata=false)
TagEntry(FILE *data_file, TagTable *tagtable, TagGroup *parent_group)
TagGroup(FILE *data_file, TagTable *tagtable, const string &groupname)
int read(bool nodata=false)
static const char * IMAGE_HEIGHT_TAG
vector< int > datatype_list
int get_int(const string &name)
double get_double(const string &name)
string get_string(const string &name)
void become_host_endian(T *data, int n=1)
void add(const string &name, const string &value)
static const char * IMAGE_THUMB_INDEX_TAG
static const char * IMAGE_WIDTH_TAG
void set_thumb_index(int i)
void set_endian(bool big_endian)
void add_data(char *data)
float get_float(const string &name)
vector< char * > data_list
static const char * IMAGE_DATATYPE_TAG
std::map< string, string > tags
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.
virtual bool is_image_big_endian()=0
Is this image in big endian or not.
IntSize is used to describe a 1D, 2D or 3D rectangular size in integers.
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
#define ImageReadException(filename, desc)
#define OutofRangeException(low, high, input, objname)
#define NullPointerException(desc)
int to_em_datatype(int gatan_datatype)
const char * to_str(Gatan::TagData::Type type)
int portable_fseek(FILE *fp, off_t offset, int whence)