EMAN2
dm3io.cpp
Go to the documentation of this file.
1/*
2 * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
3 * Copyright (c) 2000-2006 Baylor College of Medicine
4 *
5 * This software is issued under a joint BSD/GNU license. You may use the
6 * source code in this file under either license. However, note that the
7 * complete EMAN2 and SPARX software packages have some GPL dependencies,
8 * so you are responsible for compliance with the licenses of these packages
9 * if you opt to use BSD licensing. The warranty disclaimer below holds
10 * in either instance.
11 *
12 * This complete copyright notice must be included in any revised version of the
13 * source code. Additional authorship citations may be added, but existing
14 * author citations must be preserved.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 * */
31
32#include <cstring>
33
34#include "dm3io.h"
35#include "portable_fileio.h"
36#include "geometry.h"
37
38using namespace EMAN;
39using namespace EMAN::Gatan;
40
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";
45
46TagTable::TagTable()
47 : img_index(0), is_big_endian(true)
48{
49}
50
52{
53 for (unsigned int i = 0; i < data_list.size(); i++) {
54 if (data_list[i]) {
55 delete [] data_list[i];
56 data_list[i] = 0;
57 }
58 }
59}
60
61void TagTable::add(const string & name, const string & value)
62{
63 const char *value_str = value.c_str();
64
65 if (name == IMAGE_WIDTH_TAG) {
66 x_list.push_back(atoi(value_str));
67 }
68 else if (name == IMAGE_HEIGHT_TAG) {
69 y_list.push_back(atoi(value_str));
70 }
71 else if (name == IMAGE_DATATYPE_TAG) {
72 datatype_list.push_back(atoi(value_str));
73 }
74 else if (name == IMAGE_THUMB_INDEX_TAG) {
75 set_thumb_index(atoi(value_str));
76 }
77 else {
78 tags[name] = value;
79 }
80}
81
82void TagTable::add_data(char *data)
83{
84 if (!data) {
85 throw NullPointerException("DM3 data is NULL");
86 }
87 else {
88 data_list.push_back(data);
89 }
90}
91
92string TagTable::get_string(const string & name)
93{
94 return tags[name];
95}
96
97int TagTable::get_int(const string & name)
98{
99 return atoi(tags[name].c_str());
100}
101
102float TagTable::get_float(const string & name)
103{
104 return static_cast < float >(atof(tags[name].c_str()));
105}
106
107double TagTable::get_double(const string & name)
108{
109 return atof(tags[name].c_str());
110}
111
112void TagTable::dump() const
113{
114 map < string, string >::const_iterator p;
115
116 for (p = tags.begin(); p != tags.end(); p++) {
117// LOGDEBUG(" %s: %s", (*p).first.c_str(), (*p).second.c_str());
118 printf(" %s: %s\n", (*p).first.c_str(), (*p).second.c_str());
119 }
120}
121
123{
124 return x_list[img_index];
125}
126
128{
129 return y_list[img_index];
130}
131
133{
134 return datatype_list[img_index];
135}
136
138{
139 return data_list[img_index];
140}
141
143{
144 if (i != 0 && i != 1) {
145 throw OutofRangeException(0, 1, i, "image index");
146 }
147 else {
148 if (i == 0) {
149 img_index = 1;
150 }
151 else {
152 img_index = 0;
153 }
154 }
155}
156
157TagData::TagData(FILE * data_file, TagTable * table, const string & tagname)
158 : in(data_file), tagtable(table), name(tagname), tag_type(UNKNOWN)
159{
160}
161
163{
164}
165
166string TagData::read_native(bool is_value_stored)
167{
168 size_t sz = typesize();
169 size_t nr;
170 char val_str[32];
171
172 if (tag_type == SHORT) {
173 short val = 0;
174 nr = fread(&val, sz, 1, in); nr++;
176 sprintf(val_str, "%d", val);
177 }
178 else if (tag_type == USHORT) {
179 unsigned short val = 0;
180 nr = fread(&val, sz, 1, in); nr++;
182 sprintf(val_str, "%d", val);
183 }
184 else if (tag_type == INT) {
185 int val = 0;
186 nr = fread(&val, sz, 1, in); nr++;
188 sprintf(val_str, "%d", val);
189 }
190 else if (tag_type == CHAR || tag_type == OCTET) {
191 char val = 0;
192 nr = fread(&val, sz, 1, in); nr++;
193 sprintf(val_str, "%d", val);
194 }
195 else if (tag_type == BOOLEAN) {
196 bool val = false;
197 nr = fread(&val, sz, 1, in); nr++;
199 sprintf(val_str, "%d", val);
200 }
201 else if (tag_type == UINT) {
202 unsigned int val = 0;
203 nr = fread(&val, sz, 1, in); nr++;
205 sprintf(val_str, "%d", (int) val);
206 }
207 else if (tag_type == FLOAT) {
208 float val = 0;
209 nr = fread(&val, sz, 1, in); nr++;
211 sprintf(val_str, "%f", val);
212 }
213 else if (tag_type == DOUBLE) {
214 double val = 0;
215 nr = fread(&val, sz, 1, in); nr++;
217 sprintf(val_str, "%10e", val);
218 }
219 else {
220 LOGERR("invalid tag type: '%d'", tag_type);
221 exit(1);
222 }
223
224 if (is_value_stored) {
225 tagtable->add(name, val_str);
226 }
227
228 LOGVAR("value = '%s'", val_str);
229
230 return string(val_str);
231}
232
234{
235 LOGVAR("TagData::read_array_types()");
236
237 int array_type = 0;
238 size_t nr;
239 nr = fread(&array_type, sizeof(array_type), 1, in); nr++;
240
241 ByteOrder::become_big_endian(&array_type);
242
243 LOGVAR("array data type = '%s'", Gatan::to_str((Type) array_type));
244
245 vector < int >item_types;
246
247 if (array_type == STRUCT) {
248 item_types = read_struct_types();
249 }
250 else if (array_type == ARRAY) {
251 item_types = read_array_types();
252 LOGERR("DM3: don't know how to handle this array type");
253 }
254 else {
255 item_types.push_back(array_type);
256 }
257
258 return item_types;
259}
260
261// string tag data are stored in unicode
262
263string TagData::read_string(int size)
264{
265 if (size <= 0) {
266 return string("");
267 }
268
269 unsigned short *buf = new unsigned short[size];
270 char *str = new char[size + 1];
271
272 size_t nr;
273 nr = fread(buf, size * sizeof(unsigned short), 1, in); nr++;
274 tagtable->become_host_endian < unsigned short >(buf, size);
275
276 for (int i = 0; i < size; i++) {
277 str[i] = static_cast < char >(buf[i]);
278 }
279
280 str[size] = '\0';
281 string str1 = string(str);
282
283 if (str) {
284 delete [] str;
285 str = NULL;
286 }
287
288 if (buf) {
289 delete [] buf;
290 buf = NULL;
291 }
292
293 return str1;
294}
295
296int TagData::read_array_data(vector < int >item_types, bool nodata)
297{
298 ENTERFUNC;
299 if (item_types.size() == 0) {
300 LOGERR("DM3 item types cannot be empty");
301 return 1;
302 }
303
304 int err = 0;
305 int array_size = 0;
306
307 size_t nr;
308 nr = fread(&array_size, sizeof(array_size), 1, in); nr++;
309 ByteOrder::become_big_endian(&array_size);
310
311 LOGVAR("array size = %d\n", array_size);
312
313 size_t item_size = 0;
314 for (size_t i = 0; i < item_types.size(); i++) {
315 item_size += typesize(item_types[i]);
316 }
317
318 LOGVAR("%s array item size = %d\n", name.c_str(), item_size);
319
320 size_t buf_size = item_size * array_size;
321
322 if (item_types.size() == 1 && item_types[0] == USHORT && nodata) {
323 string val = read_string(array_size);
324 tagtable->add(name, val);
325 LOGVAR("value: %s", val.c_str());
326 }
327 else if (!nodata && name == "Data") {
328 char *data = new char[buf_size];
329 nr = fread(data, buf_size, 1, in); nr++;
330
331 if (item_size == sizeof(short)) {
332 tagtable->become_host_endian((short *) data, array_size);
333 }
334 else if (item_size == sizeof(int)) {
335 tagtable->become_host_endian((int *) data, array_size);
336 }
337 else if (item_size == sizeof(double)) {
338 tagtable->become_host_endian((double *) data, array_size);
339 }
340 else {
341 LOGERR("cannot handle this type of DM3 image data");
342 return 1;
343 }
344
345 tagtable->add_data(data);
346 }
347 else {
348 portable_fseek(in, buf_size, SEEK_CUR);
349 }
350 EXITFUNC;
351 return err;
352}
353
355{
356 LOGVAR("TagData::read_struct_types()");
357
358 unsigned int namelength = 0;
359 unsigned int nfields = 0;
360
361 size_t nr;
362 nr = fread(&namelength, sizeof(namelength), 1, in); nr++;
363 ByteOrder::become_big_endian(&namelength);
364
365 nr = fread(&nfields, sizeof(nfields), 1, in); nr++;
367
368 LOGVAR("namelength = %d\n", namelength);
369 LOGVAR("num fields = %d\n", nfields);
370
371 vector < int >field_types;
372
373 for (unsigned int i = 0; i < nfields; i++) {
374 nr = fread(&namelength, sizeof(namelength), 1, in); nr++;
375 ByteOrder::become_big_endian(&namelength);
376
377 int field_type = 0;
378 nr = fread(&field_type, sizeof(field_type), 1, in); nr++;
379 ByteOrder::become_big_endian(&field_type);
380
381 LOGVAR("%dth namelength = %d, type = '%s'",
382 i, namelength, Gatan::to_str((Type) field_type));
383 field_types.push_back(field_type);
384 }
385
386 return field_types;
387}
388
389int TagData::read_any(bool nodata)
390{
391 int err = 0;
392
393 size_t nr;
394 nr = fread(&tag_type, sizeof(tag_type), 1, in); nr++;
396 LOGVAR("tag type = '%s'\n", Gatan::to_str((Type) tag_type));
397
398 if (tag_type == ARRAY) {
399 vector < int >item_types = read_array_types();
400 err = read_array_data(item_types, nodata);
401 }
402 else if (tag_type == STRUCT) {
403 vector < int >field_types = read_struct_types();
404
405 for (unsigned int i = 0; i < field_types.size(); i++) {
406 tag_type = static_cast < Type > (field_types[i]);
407 string val = read_native(false);
408 char int_str[32];
409 sprintf(int_str, " #%d", i);
410 string fieldname = name + string(int_str);
411 tagtable->add(fieldname, val);
412 }
413 }
414 else if (tag_type == STRING) {
415 int str_sz = 0;
416 nr = fread(&str_sz, sizeof(str_sz), 1, in); nr++;
418
419 char *val = new char[str_sz + 1];
420 nr = fread(val, str_sz, 1, in); nr++;
421 val[str_sz] = '\0';
422 string val_str = string(val);
423 if( val )
424 {
425 delete[]val;
426 val = 0;
427 }
428
429 tagtable->add(name, val_str);
430 }
431 else {
432 read_native(true);
433 }
434
435 return err;
436}
437
438int TagData::read(bool nodata)
439{
440 LOGVAR("TagData::read()");
441 int err = 0;
442
443 const char *DATA_TYPE_MARK = "%%%%";
444 const size_t mark_sz = strlen(DATA_TYPE_MARK);
445 char *mark = new char[mark_sz + 1];
446
447 size_t nr;
448 nr = fread(mark, mark_sz, 1, in); nr++;
449 mark[mark_sz] = '\0';
450
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);
454 return 1;
455 }
456
457 if (mark) {
458 delete [] mark;
459 mark = 0;
460 }
461
462 int encoded_types_size = 0;
463 nr = fread(&encoded_types_size, sizeof(int), 1, in); nr++;
464 ByteOrder::become_big_endian(&encoded_types_size);
465
466 LOGVAR("encoded types size = %d\n", encoded_types_size);
467
468 err = read_any(nodata);
469
470 return err;
471}
472
473size_t TagData::typesize() const
474{
475 return typesize((int) tag_type);
476}
477
478size_t TagData::typesize(int t) const
479{
480 size_t size = 0;
481 Type type = static_cast < Type > (t);
482
483 switch (type) {
484 case SHORT:
485 size = sizeof(short);
486 break;
487 case USHORT:
488 size = sizeof(unsigned short);
489 break;
490 case INT:
491 size = sizeof(int);
492 break;
493 case UINT:
494 size = sizeof(unsigned int);
495 break;
496 case FLOAT:
497 size = sizeof(float);
498 break;
499 case DOUBLE:
500 size = sizeof(double);
501 break;
502 case BOOLEAN:
503 size = sizeof(bool);
504 break;
505 case CHAR:
506 case OCTET:
507 size = sizeof(char);
508 break;
509 default:
510 LOGERR("no such type: '%d'\n", type);
511 break;
512 }
513
514 return size;
515}
516
518
519TagGroup::TagGroup(FILE * data_file, TagTable * table, const string & groupname)
520 : in(data_file), tagtable(table), name(groupname), entry_id(0)
521{
522}
523
525{
526}
527
528int TagGroup::read(bool nodata)
529{
530 LOGVAR("TagGroup::read()");
531
532 int ntags = 0;
533 portable_fseek(in, sizeof(char) * 2, SEEK_CUR);
534
535 size_t nr;
536 nr = fread(&ntags, sizeof(ntags), 1, in); nr++;
537
539
540 LOGVAR("DM3: ntags = %d\n", ntags);
541
542 int err = 0;
543
544 for (int i = 0; i < ntags; i++) {
545 TagEntry tag_entry(in, tagtable, this);
546 err = tag_entry.read(nodata);
547
548 if (err) {
549 break;
550 }
551 }
552
553 return err;
554}
555
556string TagGroup::get_name() const
557{
558 return name;
559}
560
562{
563 int id = entry_id;
564 entry_id++;
565 return id;
566}
567
569
570TagEntry::TagEntry(FILE * data_file, TagTable * table, TagGroup * parent)
571 : in(data_file), tagtable(table), parent_group(parent), name("")
572{
573}
574
576{
577}
578
579int TagEntry::read(bool nodata)
580{
581 LOGVAR("TagEntry::read()");
582 int err = 0;
583 char tag_type = 0;
584 char *tmp_name = 0;
585
586 size_t nr;
587 nr = fread(&tag_type, sizeof(char), 1, in); nr++;
588
589 if (tag_type != GROUP_TAG && tag_type != DATA_TAG) {
590 LOGERR("TagEntry::read() invalid tag type: %d", tag_type);
591 return 1;
592 }
593
594 short name_len = 0;
595 nr = fread(&name_len, sizeof(short), 1, in); nr++;
597
598 if (name_len != 0) {
599 tmp_name = new char[name_len + 1];
600 nr = fread(tmp_name, name_len, 1, in); nr++;
601 tmp_name[name_len] = '\0';
602 }
603 else {
604 string parent_name = parent_group->get_name();
605 name_len = static_cast < short >(parent_name.size() + 4);
606 tmp_name = new char[name_len + 1];
607 sprintf(tmp_name, "%s #%d", parent_name.c_str(), parent_group->get_entry_id());
608 }
609
610 name = string(tmp_name);
611
612 if (tmp_name) {
613 delete [] tmp_name;
614 tmp_name = 0;
615 }
616
617 LOGVAR("\ntag name: '%s', len: %d, type: '%s'",
618 name.c_str(), name_len, Gatan::to_str((EntryType) tag_type));
619
620 if (tag_type == DATA_TAG) {
621 TagData tag_data(in, tagtable, name);
622 err = tag_data.read(nodata);
623 }
624 else if (tag_type == GROUP_TAG) {
625 TagGroup group(in, tagtable, name);
626 err = group.read(nodata);
627 }
628
629 return err;
630}
631
633
634DM3IO::DM3IO(const string & fname, IOMode rw)
635 : ImageIO(fname, rw)
636{
638 tagtable = new TagTable();
639}
640
642{
643 if (file) {
644 fclose(file);
645 file = 0;
646 }
647 if (tagtable) {
648 delete tagtable;
649 tagtable = 0;
650 }
651}
652
653void DM3IO::init()
654{
655 ENTERFUNC;
656 if (initialized) {
657 return;
658 }
659 initialized = true;
660
661 if (rw_mode != READ_ONLY) {
662 throw ImageReadException(filename, "only support DM3 read-only");
663 }
664
666
667 int buf[NUM_ID_INT];
668 if (fread(buf, sizeof(buf), 1, file) != 1) {
669 throw ImageReadException(filename, "read first block of DM3 file");
670 }
671
672 if (!is_valid(&buf)) {
673 throw ImageReadException(filename, "invalid DM3 file");
674 }
675
676 int byte_order = buf[2];
677
678 if (byte_order == 0) {
679 is_big_endian = true;
680 }
681 else {
682 is_big_endian = false;
683 }
684
687
688 LOGDEBUG("dm3 ver = %d, image size = %d, is_big_endian = %d",
689 buf[0], buf[1], (int) is_big_endian);
690
691 EXITFUNC;
692}
693
694bool DM3IO::is_valid(const void *first_block)
695{
696 ENTERFUNC;
697
698 if (!first_block) {
699 return false;
700 }
701
702 const int *data = static_cast < const int *>(first_block);
703
704 int img_ver = data[0];
705 int img_size = data[1];
706 int byte_order = data[2];
707
709
710 if (img_ver != 3) {
711 return false;
712 }
713
715 ByteOrder::become_big_endian(&byte_order);
716
717 if (byte_order != 0 && byte_order != 1) {
718 return false;
719 }
720
721 return true;
722}
723
725{
726 init();
727 return is_big_endian;
728}
729
730int DM3IO::read_header(Dict & dict, int image_index, const Region * area, bool)
731{
732 ENTERFUNC;
733 int err = 0;
734
735 //single image format, index can only be zero
736 if(image_index == -1) {
737 image_index = 0;
738 }
739 image_index = 0;
740 check_read_access(image_index);
741
742 portable_fseek(file, NUM_ID_INT * sizeof(int), SEEK_SET);
743 TagGroup root_group(file, tagtable, "");
744 root_group.read(true);
745
746 int nx = tagtable->get_xsize();
747 int ny = tagtable->get_ysize();
748
749 check_region(area, IntSize(nx, ny));
750 int xlen = 0, ylen = 0;
751 EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
752
753 dict["nx"] = xlen;
754 dict["ny"] = ylen;
755 dict["nz"] = 1;
756
757 dict["DM3.acq_date"] = tagtable->get_string("Acquisition Date");
758 dict["DM3.acq_time"] = tagtable->get_string("Acquisition Time");
759 dict["DM3.source"] = tagtable->get_string("Source");
760 dict["DM3.exposure_number"] = tagtable->get_int("Exposure Number");
761 dict["DM3.exposure_time"] = tagtable->get_double("Exposure (s)");
762 dict["DM3.zoom"] = tagtable->get_double("Zoom");
763 dict["DM3.antiblooming"] = tagtable->get_int("Antiblooming");
764 dict["DM3.indicated_mag"] = tagtable->get_double("Indicated Magnification");
765 dict["DM3.actual_mag"] = tagtable->get_double("Actual Magnification");
766 dict["DM3.pixel_size"] = tagtable->get_double("Pixel Size (um) #0");
767 dict["DM3.name"] = tagtable->get_string("Name");
768
769 dict["DM3.voltage"] = tagtable->get_double("Voltage")/1000.0;
770 dict["microscope_voltage"]=(float)dict["DM3.voltage"];
771 dict["DM3.cs"] = tagtable->get_double("Cs(mm)");
772 dict["microscope_cs"]=(float)dict["DM3.cs"];
773
774 dict["DM3.frame_type"] = tagtable->get_string("Processing");
775 dict["DM3.camera_x"] = tagtable->get_int("Active Size (pixels) #0");
776 dict["DM3.camera_y"] = tagtable->get_int("Active Size (pixels) #1");
777 dict["DM3.binning_x"] = tagtable->get_int("Binning #0");
778 dict["DM3.binning_y"] = tagtable->get_int("Binning #1");
779 dict["datatype"] = to_em_datatype(tagtable->get_datatype());
780
781 if ((float)dict["DM3.actual_mag"] >0.0) {
782 float apix=10000.0*(float)dict["DM3.pixel_size"]/(float)dict["DM3.actual_mag"];
783 dict["apix_x"]=apix;
784 dict["apix_y"]=apix;
785 dict["apix_z"]=apix;
786 }
787
788// tagtable->dump();
789
790 EXITFUNC;
791 return err;
792}
793
794int DM3IO::read_data(float *rdata, int image_index, const Region * area, bool)
795{
796 ENTERFUNC;
797 //single image format, index can only be zero
798 image_index = 0;
799 check_read_access(image_index, rdata);
800
801 portable_fseek(file, NUM_ID_INT * sizeof(int), SEEK_SET);
802
803 TagGroup root_group(file, tagtable, "");
804 root_group.read(false);
805
806 int nx = tagtable->get_xsize();
807 int ny = tagtable->get_ysize();
808
809 check_region(area, IntSize(nx, ny));
810
811 int xlen = 0, ylen = 0, x0 = 0, y0 = 0;
812 EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
813 EMUtil::get_region_origins(area, &x0, &y0);
814
815 char *data = tagtable->get_data();
816 int data_type = tagtable->get_datatype();
817
818 int k = 0;
819 int off = 0;
820 int xlast = x0 + xlen;
821 int ylast = y0 + ylen;
822
823// bool flip_vertical = (getenv ("FLIP_VERTICAL") != NULL);
824 bool flip_vertical = true;
825
826 for (int iy = y0; iy < ylast; iy++) {
827 if (flip_vertical) {
828 off = (y0 + ylast - 1 - iy) * nx;
829 }
830 else {
831 off = iy * nx;
832 }
833
834 for (int ix = x0; ix < xlast; ix++) {
835 switch (data_type) {
837 rdata[k] = (float) ((char *) data)[off + ix];
838 break;
840 rdata[k] = (float) ((unsigned char *) data)[off + ix];
841 break;
843 rdata[k] = (float) ((short *) data)[off + ix];
844 break;
846 rdata[k] = (float) ((unsigned short *) data)[off + ix];
847 break;
849 rdata[k] = (float) ((int *) data)[off + ix];
850 break;
852 rdata[k] = (float) ((unsigned int *) data)[off + ix];
853 break;
855 rdata[k] = (float) ((float *) data)[off + ix];
856 break;
857 default:
858 string desc = string("unsupported DM3 data type") +
860 throw ImageReadException(filename, desc);
861 }
862 k++;
863 }
864 }
865 EXITFUNC;
866 return 0;
867}
868
870{
871 return false;
872}
873
874int DM3IO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
875{
876 ENTERFUNC;
877 LOGWARN("DM3 write is not supported.");
878 EXITFUNC;
879 return 1;
880}
881
882int DM3IO::write_data(float *, int, const Region* , EMUtil::EMDataType, bool)
883{
884 ENTERFUNC;
885 LOGWARN("DM3 write is not supported.");
886 EXITFUNC;
887 return 1;
888}
889
890void DM3IO::flush()
891{
892}
893
894int Gatan::to_em_datatype(int gatan_datatype)
895{
896 DataType::GatanDataType type = static_cast < DataType::GatanDataType > (gatan_datatype);
897 int t = 0;
898
899 switch (type) {
901 t = EMUtil::EM_CHAR;
902 break;
905 break;
908 break;
911 break;
913 t = EMUtil::EM_INT;
914 break;
916 t = EMUtil::EM_UINT;
917 break;
918 default:
920 }
921
922 return t;
923}
924
926{
927 const char *str = "unknown";
928
929 switch (type) {
930 case TagData::SHORT:
931 str = "short";
932 break;
933 case TagData::INT:
934 str = "int";
935 break;
936 case TagData::USHORT:
937 str = "unsigned short";
938 break;
939 case TagData::UINT:
940 str = "unsigned int";
941 break;
942 case TagData::FLOAT:
943 str = "float";
944 break;
945 case TagData::DOUBLE:
946 str = "double";
947 break;
948 case TagData::BOOLEAN:
949 str = "boolean";
950 break;
951 case TagData::CHAR:
952 str = "char";
953 break;
954 case TagData::OCTET:
955 str = "octet";
956 break;
957 case TagData::STRUCT:
958 str = "struct";
959 break;
960 case TagData::STRING:
961 str = "string";
962 break;
963 case TagData::ARRAY:
964 str = "array";
965 break;
966 default:
967 str = "unknown";
968 }
969 return str;
970}
971
973{
974 const char *str = "unknown";
975
976 switch (type) {
977 case TagEntry::GROUP_TAG:
978 str = "Group";
979 break;
980 case TagEntry::DATA_TAG:
981 str = "Data";
982 break;
983 default:
984 str = "unknown";
985 }
986 return str;
987}
988
990{
991 switch (type) {
993 return "SIGNED_INT16_DATA";
995 return "REAL4_DATA";
997 return "COMPLEX8_DATA";
999 return "OBSELETE_DATA";
1001 return "PACKED_DATA";
1003 return "UNSIGNED_INT8_DATA";
1005 return "SIGNED_INT32_DATA";
1007 return "RGB_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";
1064 default:
1065 break;
1066 }
1067 return "Unknown Type";
1068}
#define rdata(i)
Definition: analyzer.cpp:592
static bool is_host_big_endian()
Definition: byteorder.cpp:40
static void become_big_endian(T *data, size_t n=1)
convert data from host byte order to big endian order.
Definition: byteorder.h:112
DM3IO(const string &fname, IOMode rw_mode=READ_ONLY)
Definition: dm3io.cpp:634
@ NUM_ID_INT
Definition: dm3io.h:253
Gatan::TagTable * tagtable
Definition: dm3io.h:257
static bool is_valid(const void *first_block)
Definition: dm3io.cpp:694
bool is_big_endian
Definition: dm3io.h:256
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
EMDataType
Image pixel data type used in EMAN.
Definition: emutil.h:92
@ EM_UCHAR
Definition: emutil.h:95
@ EM_UNKNOWN
Definition: emutil.h:93
@ EM_USHORT
Definition: emutil.h:97
@ EM_SHORT
Definition: emutil.h:96
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.
Definition: emutil.cpp:891
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.
Definition: emutil.cpp:860
int read_array_data(vector< int >item_types, bool nodata=false)
Definition: dm3io.cpp:296
string read_string(int size)
Definition: dm3io.cpp:263
int read_any(bool nodata=false)
Definition: dm3io.cpp:389
TagData(FILE *data_file, TagTable *tagtable, const string &tagname)
Definition: dm3io.cpp:157
vector< int > read_array_types()
Definition: dm3io.cpp:233
size_t typesize() const
Definition: dm3io.cpp:473
string read_native(bool is_value_stored)
Definition: dm3io.cpp:166
TagTable * tagtable
Definition: dm3io.h:131
vector< int > read_struct_types()
Definition: dm3io.cpp:354
int read(bool nodata=false)
Definition: dm3io.cpp:438
int read(bool nodata=false)
Definition: dm3io.cpp:579
TagEntry(FILE *data_file, TagTable *tagtable, TagGroup *parent_group)
Definition: dm3io.cpp:570
TagGroup * parent_group
Definition: dm3io.h:172
TagTable * tagtable
Definition: dm3io.h:171
TagTable * tagtable
Definition: dm3io.h:149
TagGroup(FILE *data_file, TagTable *tagtable, const string &groupname)
Definition: dm3io.cpp:519
int read(bool nodata=false)
Definition: dm3io.cpp:528
string get_name() const
Definition: dm3io.cpp:556
char * get_data() const
Definition: dm3io.cpp:137
vector< int > x_list
Definition: dm3io.h:87
static const char * IMAGE_HEIGHT_TAG
Definition: dm3io.h:78
int get_datatype() const
Definition: dm3io.cpp:132
vector< int > datatype_list
Definition: dm3io.h:89
int get_int(const string &name)
Definition: dm3io.cpp:97
double get_double(const string &name)
Definition: dm3io.cpp:107
string get_string(const string &name)
Definition: dm3io.cpp:92
void become_host_endian(T *data, int n=1)
Definition: dm3io.h:65
void add(const string &name, const string &value)
Definition: dm3io.cpp:61
static const char * IMAGE_THUMB_INDEX_TAG
Definition: dm3io.h:80
static const char * IMAGE_WIDTH_TAG
Definition: dm3io.h:77
void set_thumb_index(int i)
Definition: dm3io.cpp:142
void set_endian(bool big_endian)
Definition: dm3io.h:71
void dump() const
Definition: dm3io.cpp:112
void add_data(char *data)
Definition: dm3io.cpp:82
int get_xsize() const
Definition: dm3io.cpp:122
int get_ysize() const
Definition: dm3io.cpp:127
float get_float(const string &name)
Definition: dm3io.cpp:102
vector< char * > data_list
Definition: dm3io.h:90
vector< int > y_list
Definition: dm3io.h:88
static const char * IMAGE_DATATYPE_TAG
Definition: dm3io.h:79
std::map< string, string > tags
Definition: dm3io.h:86
ImageIO classes are designed for reading/writing various electron micrography image formats,...
Definition: imageio.h:127
IOMode rw_mode
Definition: imageio.h:353
string filename
Definition: imageio.h:352
void check_region(const Region *area, const FloatSize &max_size, bool is_new_file=false, bool inbounds_only=true)
Validate image I/O region.
Definition: imageio.cpp:58
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.
bool initialized
Definition: imageio.h:355
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.
Definition: imageio.cpp:135
void check_read_access(int image_index)
Validate 'image_index' in file reading.
Definition: imageio.cpp:95
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.
FILE * file
Definition: imageio.h:354
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.
Definition: geometry.h:49
Region defines a 2D or 3D rectangular region specified by its origin coordinates and all edges' sizes...
Definition: geometry.h:497
#define ImageReadException(filename, desc)
Definition: exception.h:204
#define OutofRangeException(low, high, input, objname)
Definition: exception.h:334
#define NullPointerException(desc)
Definition: exception.h:241
#define LOGDEBUG
Definition: log.h:55
#define LOGWARN
Definition: log.h:53
#define LOGERR
Definition: log.h:51
#define ENTERFUNC
Definition: log.h:48
#define LOGVAR
Definition: log.h:57
#define EXITFUNC
Definition: log.h:49
int to_em_datatype(int gatan_datatype)
Definition: dm3io.cpp:894
const char * to_str(Gatan::TagData::Type type)
Definition: dm3io.cpp:925
E2Exception class.
Definition: aligner.h:40
int portable_fseek(FILE *fp, off_t offset, int whence)