00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <cstring>
00037
00038 #include "dm3io.h"
00039 #include "portable_fileio.h"
00040 #include "geometry.h"
00041
00042 using namespace EMAN;
00043 using namespace EMAN::Gatan;
00044
00045 const char *TagTable::IMAGE_WIDTH_TAG = "Dimensions #0";
00046 const char *TagTable::IMAGE_HEIGHT_TAG = "Dimensions #1";
00047 const char *TagTable::IMAGE_DATATYPE_TAG = "DataType";
00048 const char *TagTable::IMAGE_THUMB_INDEX_TAG = "ImageIndex";
00049
00050 TagTable::TagTable()
00051 : img_index(0), is_big_endian(true)
00052 {
00053 }
00054
00055 TagTable::~TagTable()
00056 {
00057 for (unsigned int i = 0; i < data_list.size(); i++) {
00058 if (data_list[i]) {
00059 delete[]data_list[i];
00060 data_list[i] = 0;
00061 }
00062 }
00063 }
00064
00065
00066 void TagTable::add(const string & name, const string & value)
00067 {
00068 const char *value_str = value.c_str();
00069
00070 if (name == IMAGE_WIDTH_TAG) {
00071 x_list.push_back(atoi(value_str));
00072 }
00073 else if (name == IMAGE_HEIGHT_TAG) {
00074 y_list.push_back(atoi(value_str));
00075 }
00076 else if (name == IMAGE_DATATYPE_TAG) {
00077 datatype_list.push_back(atoi(value_str));
00078 }
00079 else if (name == IMAGE_THUMB_INDEX_TAG) {
00080 set_thumb_index(atoi(value_str));
00081 }
00082 else {
00083 tags[name] = value;
00084 }
00085 }
00086
00087 void TagTable::add_data(char *data)
00088 {
00089 if (!data) {
00090 throw NullPointerException("DM3 data is NULL");
00091 }
00092 else {
00093 data_list.push_back(data);
00094 }
00095 }
00096
00097 string TagTable::get_string(const string & name)
00098 {
00099 return tags[name];
00100 }
00101
00102 int TagTable::get_int(const string & name)
00103 {
00104 return atoi(tags[name].c_str());
00105 }
00106
00107 float TagTable::get_float(const string & name)
00108 {
00109 return static_cast < float >(atof(tags[name].c_str()));
00110 }
00111
00112 double TagTable::get_double(const string & name)
00113 {
00114 return atof(tags[name].c_str());
00115 }
00116
00117 void TagTable::dump() const
00118 {
00119 map < string, string >::const_iterator p;
00120
00121 for (p = tags.begin(); p != tags.end(); p++) {
00122
00123 printf(" %s: %s\n", (*p).first.c_str(), (*p).second.c_str());
00124 }
00125 }
00126
00127 int TagTable::get_xsize() const
00128 {
00129 return x_list[img_index];
00130 }
00131
00132 int TagTable::get_ysize() const
00133 {
00134 return y_list[img_index];
00135 }
00136
00137 int TagTable::get_datatype() const
00138 {
00139 return datatype_list[img_index];
00140 }
00141
00142 char *TagTable::get_data() const
00143 {
00144 return data_list[img_index];
00145 }
00146
00147 void TagTable::set_thumb_index(int i)
00148 {
00149 if (i != 0 && i != 1) {
00150 throw OutofRangeException(0, 1, i, "image index");
00151 }
00152 else {
00153 if (i == 0) {
00154 img_index = 1;
00155 }
00156 else {
00157 img_index = 0;
00158 }
00159 }
00160 }
00161
00162
00163 TagData::TagData(FILE * data_file, TagTable * table, const string & tagname)
00164 : in(data_file), tagtable(table), name(tagname), tag_type(UNKNOWN)
00165 {
00166 }
00167
00168 TagData::~TagData()
00169 {
00170 }
00171
00172 string TagData::read_native(bool is_value_stored)
00173 {
00174 size_t sz = typesize();
00175 char val_str[32];
00176
00177 if (tag_type == SHORT) {
00178 short val = 0;
00179 fread(&val, sz, 1, in);
00180 tagtable->become_host_endian(&val);
00181 sprintf(val_str, "%d", val);
00182 }
00183 else if (tag_type == USHORT) {
00184 unsigned short val = 0;
00185 fread(&val, sz, 1, in);
00186 tagtable->become_host_endian(&val);
00187 sprintf(val_str, "%d", val);
00188 }
00189 else if (tag_type == INT) {
00190 int val = 0;
00191 fread(&val, sz, 1, in);
00192 tagtable->become_host_endian(&val);
00193 sprintf(val_str, "%d", val);
00194 }
00195 else if (tag_type == CHAR || tag_type == OCTET) {
00196 char val = 0;
00197 fread(&val, sz, 1, in);
00198 sprintf(val_str, "%d", val);
00199 }
00200 else if (tag_type == BOOLEAN) {
00201 bool val = false;
00202 fread(&val, sz, 1, in);
00203 tagtable->become_host_endian(&val);
00204 sprintf(val_str, "%d", val);
00205 }
00206 else if (tag_type == UINT) {
00207 unsigned int val = 0;
00208 fread(&val, sz, 1, in);
00209 tagtable->become_host_endian(&val);
00210 sprintf(val_str, "%d", (int) val);
00211 }
00212 else if (tag_type == FLOAT) {
00213 float val = 0;
00214 fread(&val, sz, 1, in);
00215 tagtable->become_host_endian(&val);
00216 sprintf(val_str, "%f", val);
00217 }
00218 else if (tag_type == DOUBLE) {
00219 double val = 0;
00220 fread(&val, sz, 1, in);
00221 tagtable->become_host_endian(&val);
00222 sprintf(val_str, "%10e", val);
00223 }
00224 else {
00225 LOGERR("invalid tag type: '%d'", tag_type);
00226 exit(1);
00227 }
00228
00229 if (is_value_stored) {
00230 tagtable->add(name, val_str);
00231 }
00232
00233 LOGVAR("value = '%s'", val_str);
00234
00235 return string(val_str);
00236 }
00237
00238
00239 vector < int >TagData::read_array_types()
00240 {
00241 LOGVAR("TagData::read_array_types()");
00242
00243 int array_type = 0;
00244 fread(&array_type, sizeof(array_type), 1, in);
00245
00246 ByteOrder::become_big_endian(&array_type);
00247
00248 LOGVAR("array data type = '%s'", Gatan::to_str((Type) array_type));
00249
00250 vector < int >item_types;
00251
00252 if (array_type == STRUCT) {
00253 item_types = read_struct_types();
00254 }
00255 else if (array_type == ARRAY) {
00256 item_types = read_array_types();
00257 LOGERR("DM3: don't know how to handle this array type");
00258 }
00259 else {
00260 item_types.push_back(array_type);
00261 }
00262
00263 return item_types;
00264 }
00265
00266
00267
00268 string TagData::read_string(int size)
00269 {
00270 if (size <= 0) {
00271 return string("");
00272 }
00273
00274 unsigned short *buf = new unsigned short[size];
00275 char *str = new char[size + 1];
00276
00277 fread(buf, size * sizeof(unsigned short), 1, in);
00278 tagtable->become_host_endian < unsigned short >(buf, size);
00279
00280 for (int i = 0; i < size; i++) {
00281 str[i] = static_cast < char >(buf[i]);
00282 }
00283
00284 str[size] = '\0';
00285 string str1 = string(str);
00286
00287 if( str )
00288 {
00289 delete[]str;
00290 str = 0;
00291 }
00292 if( buf )
00293 {
00294 delete[]buf;
00295 buf = 0;
00296 }
00297
00298 return str1;
00299 }
00300
00301
00302 int TagData::read_array_data(vector < int >item_types, bool nodata)
00303 {
00304 ENTERFUNC;
00305 if (item_types.size() == 0) {
00306 LOGERR("DM3 item types cannot be empty");
00307 return 1;
00308 }
00309
00310 int err = 0;
00311 int array_size = 0;
00312
00313 fread(&array_size, sizeof(array_size), 1, in);
00314 ByteOrder::become_big_endian(&array_size);
00315
00316 LOGVAR("array size = %d\n", array_size);
00317
00318 size_t item_size = 0;
00319 for (size_t i = 0; i < item_types.size(); i++) {
00320 item_size += typesize(item_types[i]);
00321 }
00322
00323 LOGVAR("%s array item size = %d\n", name.c_str(), item_size);
00324
00325 size_t buf_size = item_size * array_size;
00326
00327 if (item_types.size() == 1 && item_types[0] == USHORT) {
00328 string val = read_string(array_size);
00329 tagtable->add(name, val);
00330 LOGVAR("value: %s", val.c_str());
00331 }
00332 else if (!nodata && name == "Data") {
00333 char *data = new char[buf_size];
00334 fread(data, buf_size, 1, in);
00335
00336 if (item_size == sizeof(short)) {
00337 tagtable->become_host_endian((short *) data, array_size);
00338 }
00339 else if (item_size == sizeof(int)) {
00340 tagtable->become_host_endian((int *) data, array_size);
00341 }
00342 else if (item_size == sizeof(double)) {
00343 tagtable->become_host_endian((double *) data, array_size);
00344 }
00345 else {
00346 LOGERR("cannot handle this type of DM3 image data");
00347 return 1;
00348 }
00349
00350 tagtable->add_data(data);
00351 }
00352 else {
00353 portable_fseek(in, buf_size, SEEK_CUR);
00354 }
00355 EXITFUNC;
00356 return err;
00357 }
00358
00359 vector < int >TagData::read_struct_types()
00360 {
00361 LOGVAR("TagData::read_struct_types()");
00362
00363 unsigned int namelength = 0;
00364 unsigned int nfields = 0;
00365
00366 fread(&namelength, sizeof(namelength), 1, in);
00367 ByteOrder::become_big_endian(&namelength);
00368
00369 fread(&nfields, sizeof(nfields), 1, in);
00370 ByteOrder::become_big_endian(&nfields);
00371
00372 LOGVAR("namelength = %d\n", namelength);
00373 LOGVAR("num fields = %d\n", nfields);
00374
00375 vector < int >field_types;
00376
00377 for (unsigned int i = 0; i < nfields; i++) {
00378 fread(&namelength, sizeof(namelength), 1, in);
00379 ByteOrder::become_big_endian(&namelength);
00380
00381 int field_type = 0;
00382 fread(&field_type, sizeof(field_type), 1, in);
00383 ByteOrder::become_big_endian(&field_type);
00384
00385 LOGVAR("%dth namelength = %d, type = '%s'",
00386 i, namelength, Gatan::to_str((Type) field_type));
00387 field_types.push_back(field_type);
00388 }
00389
00390 return field_types;
00391 }
00392
00393
00394
00395 int TagData::read_any(bool nodata)
00396 {
00397 int err = 0;
00398
00399 fread(&tag_type, sizeof(tag_type), 1, in);
00400 ByteOrder::become_big_endian(&tag_type);
00401 LOGVAR("tag type = '%s'\n", Gatan::to_str((Type) tag_type));
00402
00403 if (tag_type == ARRAY) {
00404 vector < int >item_types = read_array_types();
00405 err = read_array_data(item_types, nodata);
00406 }
00407 else if (tag_type == STRUCT) {
00408 vector < int >field_types = read_struct_types();
00409
00410 for (unsigned int i = 0; i < field_types.size(); i++) {
00411 tag_type = static_cast < Type > (field_types[i]);
00412 string val = read_native(false);
00413 char int_str[32];
00414 sprintf(int_str, " #%d", i);
00415 string fieldname = name + string(int_str);
00416 tagtable->add(fieldname, val);
00417 }
00418 }
00419 else if (tag_type == STRING) {
00420 int str_sz = 0;
00421 fread(&str_sz, sizeof(str_sz), 1, in);
00422 ByteOrder::become_big_endian(&str_sz);
00423
00424 char *val = new char[str_sz + 1];
00425 fread(val, str_sz, 1, in);
00426 val[str_sz] = '\0';
00427 string val_str = string(val);
00428 if( val )
00429 {
00430 delete[]val;
00431 val = 0;
00432 }
00433
00434 tagtable->add(name, val_str);
00435 }
00436 else {
00437 read_native(true);
00438 }
00439
00440 return err;
00441 }
00442
00443 int TagData::read(bool nodata)
00444 {
00445 LOGVAR("TagData::read()");
00446 int err = 0;
00447
00448 const char *DATA_TYPE_MARK = "%%%%";
00449 const size_t mark_sz = strlen(DATA_TYPE_MARK);
00450 char *mark = new char[mark_sz + 1];
00451 fread(mark, mark_sz, 1, in);
00452 mark[mark_sz] = '\0';
00453
00454 if (strcmp(mark, DATA_TYPE_MARK) != 0) {
00455 LOGERR("data type label has been changed from '%s' to '%s'",
00456 DATA_TYPE_MARK, mark);
00457 return 1;
00458 }
00459
00460 if( mark )
00461 {
00462 delete[]mark;
00463 mark = 0;
00464 }
00465
00466 int encoded_types_size = 0;
00467 fread(&encoded_types_size, sizeof(int), 1, in);
00468 ByteOrder::become_big_endian(&encoded_types_size);
00469
00470 LOGVAR("encoded types size = %d\n", encoded_types_size);
00471
00472 err = read_any(nodata);
00473
00474 return err;
00475 }
00476
00477
00478 size_t TagData::typesize() const
00479 {
00480 return typesize((int) tag_type);
00481 }
00482
00483 size_t TagData::typesize(int t) const
00484 {
00485 size_t size = 0;
00486 Type type = static_cast < Type > (t);
00487
00488 switch (type) {
00489 case SHORT:
00490 size = sizeof(short);
00491 break;
00492 case USHORT:
00493 size = sizeof(unsigned short);
00494 break;
00495 case INT:
00496 size = sizeof(int);
00497 break;
00498 case UINT:
00499 size = sizeof(unsigned int);
00500 break;
00501 case FLOAT:
00502 size = sizeof(float);
00503 break;
00504 case DOUBLE:
00505 size = sizeof(double);
00506 break;
00507 case BOOLEAN:
00508 size = sizeof(bool);
00509 break;
00510 case CHAR:
00511 case OCTET:
00512 size = sizeof(char);
00513 break;
00514 default:
00515 LOGERR("no such type: '%d'\n", type);
00516 break;
00517 }
00518
00519 return size;
00520 }
00521
00523
00524 TagGroup::TagGroup(FILE * data_file, TagTable * table, const string & groupname)
00525 : in(data_file), tagtable(table), name(groupname), entry_id(0)
00526 {
00527 }
00528
00529 TagGroup::~TagGroup()
00530 {
00531 }
00532
00533 int TagGroup::read(bool nodata)
00534 {
00535 LOGVAR("TagGroup::read()");
00536
00537 int ntags = 0;
00538 portable_fseek(in, sizeof(char) * 2, SEEK_CUR);
00539 fread(&ntags, sizeof(ntags), 1, in);
00540 ByteOrder::become_big_endian(&ntags);
00541 LOGVAR("DM3: ntags = %d\n", ntags);
00542
00543 int err = 0;
00544
00545 for (int i = 0; i < ntags; i++) {
00546 TagEntry tag_entry(in, tagtable, this);
00547 err = tag_entry.read(nodata);
00548
00549 if (err) {
00550 break;
00551 }
00552 }
00553
00554 return err;
00555 }
00556
00557 string TagGroup::get_name() const
00558 {
00559 return name;
00560 }
00561
00562 int TagGroup::get_entry_id()
00563 {
00564 int id = entry_id;
00565 entry_id++;
00566 return id;
00567 }
00568
00569
00570
00572
00573 TagEntry::TagEntry(FILE * data_file, TagTable * table, TagGroup * parent)
00574 : in(data_file), tagtable(table), parent_group(parent), name("")
00575 {
00576 }
00577
00578 TagEntry::~TagEntry()
00579 {
00580 }
00581
00582
00583 int TagEntry::read(bool nodata)
00584 {
00585 LOGVAR("TagEntry::read()");
00586 int err = 0;
00587 char tag_type = 0;
00588 char *tmp_name = 0;
00589
00590 fread(&tag_type, sizeof(char), 1, in);
00591
00592 if (tag_type != GROUP_TAG && tag_type != DATA_TAG) {
00593 LOGERR("TagEntry::read() invalid tag type: %d", tag_type);
00594 return 1;
00595 }
00596
00597 short name_len = 0;
00598 fread(&name_len, sizeof(short), 1, in);
00599 ByteOrder::become_big_endian(&name_len);
00600
00601 if (name_len != 0) {
00602 tmp_name = new char[name_len + 1];
00603 fread(tmp_name, name_len, 1, in);
00604 tmp_name[name_len] = '\0';
00605 }
00606 else {
00607 string parent_name = parent_group->get_name();
00608 name_len = static_cast < short >(parent_name.size() + 4);
00609 tmp_name = new char[name_len + 1];
00610 sprintf(tmp_name, "%s #%d", parent_name.c_str(), parent_group->get_entry_id());
00611 }
00612
00613 name = string(tmp_name);
00614 if( tmp_name )
00615 {
00616 delete[]tmp_name;
00617 tmp_name = 0;
00618 }
00619
00620 LOGVAR("\ntag name: '%s', len: %d, type: '%s'",
00621 name.c_str(), name_len, Gatan::to_str((EntryType) tag_type));
00622
00623 if (tag_type == DATA_TAG) {
00624 TagData tag_data(in, tagtable, name);
00625 err = tag_data.read(nodata);
00626 }
00627 else if (tag_type == GROUP_TAG) {
00628 TagGroup group(in, tagtable, name);
00629 err = group.read(nodata);
00630 }
00631
00632 return err;
00633 }
00634
00635
00637
00638 DM3IO::DM3IO(const string & dm3_filename, IOMode rw)
00639 : filename(dm3_filename), rw_mode(rw), dm3file(0), initialized(false)
00640 {
00641 is_big_endian = ByteOrder::is_host_big_endian();
00642 tagtable = new TagTable();
00643 }
00644
00645 DM3IO::~DM3IO()
00646 {
00647 if (dm3file) {
00648 fclose(dm3file);
00649 dm3file = 0;
00650 }
00651 if (tagtable) {
00652 delete tagtable;
00653 tagtable = 0;
00654 }
00655 }
00656
00657 void DM3IO::init()
00658 {
00659 ENTERFUNC;
00660 if (initialized) {
00661 return;
00662 }
00663 initialized = true;
00664
00665 if (rw_mode != READ_ONLY) {
00666 throw ImageReadException(filename, "only support DM3 read-only");
00667 }
00668
00669 dm3file = sfopen(filename, READ_ONLY);
00670
00671 int buf[NUM_ID_INT];
00672 if (fread(buf, sizeof(buf), 1, dm3file) != 1) {
00673 throw ImageReadException(filename, "read first block of DM3 file");
00674 }
00675
00676 if (!is_valid(&buf)) {
00677 throw ImageReadException(filename, "invalid DM3 file");
00678 }
00679
00680 int byte_order = buf[2];
00681
00682 if (byte_order == 0) {
00683 is_big_endian = true;
00684 }
00685 else {
00686 is_big_endian = false;
00687 }
00688
00689 tagtable->set_endian(is_big_endian);
00690 ByteOrder::become_big_endian(buf, 3);
00691
00692 LOGDEBUG("dm3 ver = %d, image size = %d, is_big_endian = %d",
00693 buf[0], buf[1], (int) is_big_endian);
00694
00695 EXITFUNC;
00696 }
00697
00698
00699
00700 bool DM3IO::is_valid(const void *first_block)
00701 {
00702 ENTERFUNC;
00703
00704 if (!first_block) {
00705 return false;
00706 }
00707
00708 const int *data = static_cast < const int *>(first_block);
00709
00710 int img_ver = data[0];
00711 int img_size = data[1];
00712 int byte_order = data[2];
00713
00714 ByteOrder::become_big_endian(&img_ver);
00715
00716 if (img_ver != 3) {
00717 return false;
00718 }
00719
00720 ByteOrder::become_big_endian(&img_size);
00721 ByteOrder::become_big_endian(&byte_order);
00722
00723 if (byte_order != 0 && byte_order != 1) {
00724 return false;
00725 }
00726
00727 return true;
00728 }
00729
00730 bool DM3IO::is_image_big_endian()
00731 {
00732 init();
00733 return is_big_endian;
00734 }
00735
00736 int DM3IO::read_header(Dict & dict, int image_index, const Region * area, bool)
00737 {
00738 ENTERFUNC;
00739 int err = 0;
00740
00741
00742 if(image_index == -1) {
00743 image_index = 0;
00744 }
00745 image_index = 0;
00746 check_read_access(image_index);
00747
00748 portable_fseek(dm3file, NUM_ID_INT * sizeof(int), SEEK_SET);
00749 TagGroup root_group(dm3file, tagtable, "");
00750 root_group.read(true);
00751
00752 int nx = tagtable->get_xsize();
00753 int ny = tagtable->get_ysize();
00754
00755 check_region(area, IntSize(nx, ny));
00756 int xlen = 0, ylen = 0;
00757 EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
00758
00759 dict["nx"] = xlen;
00760 dict["ny"] = ylen;
00761 dict["nz"] = 1;
00762
00763 dict["DM3.acq_date"] = tagtable->get_string("Acquisition Date");
00764 dict["DM3.acq_time"] = tagtable->get_string("Acquisition Time");
00765 dict["DM3.source"] = tagtable->get_string("Source");
00766 dict["DM3.exposure_number"] = tagtable->get_int("Exposure Number");
00767 dict["DM3.exposure_time"] = tagtable->get_double("Exposure (s)");
00768 dict["DM3.zoom"] = tagtable->get_double("Zoom");
00769 dict["DM3.antiblooming"] = tagtable->get_int("Antiblooming");
00770 dict["DM3.indicated_mag"] = tagtable->get_double("Indicated Magnification");
00771 dict["DM3.actual_mag"] = tagtable->get_double("Actual Magnification");
00772 dict["DM3.pixel_size"] = tagtable->get_double("Pixel Size (um) #0");
00773 dict["DM3.name"] = tagtable->get_string("Name");
00774
00775 dict["DM3.voltage"] = tagtable->get_double("Voltage")/1000.0;
00776 dict["microscope_voltage"]=(float)dict["DM3.voltage"];
00777 dict["DM3.cs"] = tagtable->get_double("Cs(mm)");
00778 dict["microscope_cs"]=(float)dict["DM3.cs"];
00779
00780 dict["DM3.frame_type"] = tagtable->get_string("Processing");
00781 dict["DM3.camera_x"] = tagtable->get_int("Active Size (pixels) #0");
00782 dict["DM3.camera_y"] = tagtable->get_int("Active Size (pixels) #1");
00783 dict["DM3.binning_x"] = tagtable->get_int("Binning #0");
00784 dict["DM3.binning_y"] = tagtable->get_int("Binning #1");
00785 dict["datatype"] = to_em_datatype(tagtable->get_datatype());
00786
00787 if ((float)dict["DM3.actual_mag"] >0.0) {
00788 float apix=10000.0*(float)dict["DM3.pixel_size"]/(float)dict["DM3.actual_mag"];
00789 dict["apix_x"]=apix;
00790 dict["apix_y"]=apix;
00791 dict["apix_z"]=apix;
00792 }
00793
00794
00795
00796 EXITFUNC;
00797 return err;
00798 }
00799
00800 int DM3IO::read_data(float *rdata, int image_index, const Region * area, bool)
00801 {
00802 ENTERFUNC;
00803
00804 image_index = 0;
00805 check_read_access(image_index, rdata);
00806
00807 portable_fseek(dm3file, NUM_ID_INT * sizeof(int), SEEK_SET);
00808
00809 TagGroup root_group(dm3file, tagtable, "");
00810 root_group.read(false);
00811
00812 int nx = tagtable->get_xsize();
00813 int ny = tagtable->get_ysize();
00814
00815 check_region(area, IntSize(nx, ny));
00816
00817 int xlen = 0, ylen = 0, x0 = 0, y0 = 0;
00818 EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
00819 EMUtil::get_region_origins(area, &x0, &y0);
00820
00821 char *data = tagtable->get_data();
00822 int data_type = tagtable->get_datatype();
00823
00824 int k = 0;
00825 for (int i = y0; i < y0 + ylen; i++) {
00826 for (int j = x0; j < x0 + xlen; j++) {
00827 switch (data_type) {
00828 case Gatan::DataType::SIGNED_INT8_DATA:
00829 rdata[k] = (float) ((char *) data)[i * nx + j];
00830 break;
00831 case Gatan::DataType::UNSIGNED_INT8_DATA:
00832 rdata[k] = (float) ((unsigned char *) data)[i * nx + j];
00833 break;
00834 case Gatan::DataType::SIGNED_INT16_DATA:
00835 rdata[k] = (float) ((short *) data)[i * nx + j];
00836 break;
00837 case Gatan::DataType::UNSIGNED_INT16_DATA:
00838 rdata[k] = (float) ((unsigned short *) data)[i * nx + j];
00839 break;
00840 case Gatan::DataType::SIGNED_INT32_DATA:
00841 rdata[k] = (float) ((int *) data)[i * nx + j];
00842 break;
00843 case Gatan::DataType::UNSIGNED_INT32_DATA:
00844 rdata[k] = (float) ((unsigned int *) data)[i * nx + j];
00845 break;
00846 default:
00847 string desc = string("unsupported DM3 data type") +
00848 string(Gatan::to_str((Gatan::DataType::GatanDataType) data_type));
00849 throw ImageReadException(filename, desc);
00850 }
00851 k++;
00852 }
00853 }
00854 EXITFUNC;
00855 return 0;
00856 }
00857
00858 bool DM3IO::is_complex_mode()
00859 {
00860 return false;
00861 }
00862
00863 int DM3IO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00864 {
00865 ENTERFUNC;
00866 LOGWARN("DM3 write is not supported.");
00867 EXITFUNC;
00868 return 1;
00869 }
00870
00871 int DM3IO::write_data(float *, int, const Region* , EMUtil::EMDataType, bool)
00872 {
00873 ENTERFUNC;
00874 LOGWARN("DM3 write is not supported.");
00875 EXITFUNC;
00876 return 1;
00877 }
00878
00879 void DM3IO::flush()
00880 {
00881 }
00882
00883 int Gatan::to_em_datatype(int gatan_datatype)
00884 {
00885 DataType::GatanDataType type = static_cast < DataType::GatanDataType > (gatan_datatype);
00886 int t = 0;
00887
00888 switch (type) {
00889 case Gatan::DataType::SIGNED_INT8_DATA:
00890 t = EMUtil::EM_CHAR;
00891 break;
00892 case Gatan::DataType::UNSIGNED_INT8_DATA:
00893 t = EMUtil::EM_UCHAR;
00894 break;
00895 case Gatan::DataType::SIGNED_INT16_DATA:
00896 t = EMUtil::EM_SHORT;
00897 break;
00898 case Gatan::DataType::UNSIGNED_INT16_DATA:
00899 t = EMUtil::EM_USHORT;
00900 break;
00901 case Gatan::DataType::SIGNED_INT32_DATA:
00902 t = EMUtil::EM_INT;
00903 break;
00904 case Gatan::DataType::UNSIGNED_INT32_DATA:
00905 t = EMUtil::EM_UINT;
00906 break;
00907 default:
00908 t = EMUtil::EM_UNKNOWN;
00909 }
00910
00911 return t;
00912 }
00913
00914
00915 const char *Gatan::to_str(TagData::Type type)
00916 {
00917 const char *str = "unknown";
00918
00919 switch (type) {
00920 case TagData::SHORT:
00921 str = "short";
00922 break;
00923 case TagData::INT:
00924 str = "int";
00925 break;
00926 case TagData::USHORT:
00927 str = "unsigned short";
00928 break;
00929 case TagData::UINT:
00930 str = "unsigned int";
00931 break;
00932 case TagData::FLOAT:
00933 str = "float";
00934 break;
00935 case TagData::DOUBLE:
00936 str = "double";
00937 break;
00938 case TagData::BOOLEAN:
00939 str = "boolean";
00940 break;
00941 case TagData::CHAR:
00942 str = "char";
00943 break;
00944 case TagData::OCTET:
00945 str = "octet";
00946 break;
00947 case TagData::STRUCT:
00948 str = "struct";
00949 break;
00950 case TagData::STRING:
00951 str = "string";
00952 break;
00953 case TagData::ARRAY:
00954 str = "array";
00955 break;
00956 default:
00957 str = "unknown";
00958 }
00959 return str;
00960 }
00961
00962 const char *Gatan::to_str(TagEntry::EntryType type)
00963 {
00964 const char *str = "unknown";
00965
00966 switch (type) {
00967 case TagEntry::GROUP_TAG:
00968 str = "Group";
00969 break;
00970 case TagEntry::DATA_TAG:
00971 str = "Data";
00972 break;
00973 default:
00974 str = "unknown";
00975 }
00976 return str;
00977 }
00978
00979
00980 const char *Gatan::to_str(Gatan::DataType::GatanDataType type)
00981 {
00982 switch (type) {
00983 case Gatan::DataType::SIGNED_INT16_DATA:
00984 return "SIGNED_INT16_DATA";
00985 case Gatan::DataType::REAL4_DATA:
00986 return "REAL4_DATA";
00987 case Gatan::DataType::COMPLEX8_DATA:
00988 return "COMPLEX8_DATA";
00989 case Gatan::DataType::OBSELETE_DATA:
00990 return "OBSELETE_DATA";
00991 case Gatan::DataType::PACKED_DATA:
00992 return "PACKED_DATA";
00993 case Gatan::DataType::UNSIGNED_INT8_DATA:
00994 return "UNSIGNED_INT8_DATA";
00995 case Gatan::DataType::SIGNED_INT32_DATA:
00996 return "SIGNED_INT32_DATA";
00997 case Gatan::DataType::RGB_DATA:
00998 return "RGB_DATA";
00999 case Gatan::DataType::SIGNED_INT8_DATA:
01000 return "SIGNED_INT8_DATA";
01001 case Gatan::DataType::UNSIGNED_INT16_DATA:
01002 return "UNSIGNED_INT16_DATA";
01003 case Gatan::DataType::UNSIGNED_INT32_DATA:
01004 return "UNSIGNED_INT32_DATA";
01005 case Gatan::DataType::REAL8_DATA:
01006 return "REAL8_DATA";
01007 case Gatan::DataType::COMPLEX16_DATA:
01008 return "COMPLEX16_DATA";
01009 case Gatan::DataType::BINARY_DATA:
01010 return "BINARY_DATA";
01011 case Gatan::DataType::RGB_UINT8_0_DATA:
01012 return "RGB_UINT8_0_DATA";
01013 case Gatan::DataType::RGB_UINT8_1_DATA:
01014 return "RGB_UINT8_1_DATA";
01015 case Gatan::DataType::RGB_UINT16_DATA:
01016 return "RGB_UINT16_DATA";
01017 case Gatan::DataType::RGB_FLOAT32_DATA:
01018 return "RGB_FLOAT32_DATA";
01019 case Gatan::DataType::RGB_FLOAT64_DATA:
01020 return "RGB_FLOAT64_DATA";
01021 case Gatan::DataType::RGBA_UINT8_0_DATA:
01022 return "RGBA_UINT8_0_DATA";
01023 case Gatan::DataType::RGBA_UINT8_1_DATA:
01024 return "RGBA_UINT8_1_DATA";
01025 case Gatan::DataType::RGBA_UINT8_2_DATA:
01026 return "RGBA_UINT8_2_DATA";
01027 case Gatan::DataType::RGBA_UINT8_3_DATA:
01028 return "RGBA_UINT8_3_DATA";
01029 case Gatan::DataType::RGBA_UINT16_DATA:
01030 return "RGBA_UINT16_DATA";
01031 case Gatan::DataType::RGBA_FLOAT32_DATA:
01032 return "RGBA_FLOAT32_DATA";
01033 case Gatan::DataType::RGBA_FLOAT64_DATA:
01034 return "RGBA_FLOAT64_DATA";
01035 case Gatan::DataType::POINT2_SINT16_0_DATA:
01036 return "POINT2_SINT16_0_DATA";
01037 case Gatan::DataType::POINT2_SINT16_1_DATA:
01038 return "POINT2_SINT16_1_DATA";
01039 case Gatan::DataType::POINT2_SINT32_0_DATA:
01040 return "POINT2_SINT32_0_DATA";
01041 case Gatan::DataType::POINT2_FLOAT32_0_DATA:
01042 return "POINT2_FLOAT32_0_DATA";
01043 case Gatan::DataType::RECT_SINT16_1_DATA:
01044 return "RECT_SINT16_1_DATA";
01045 case Gatan::DataType::RECT_SINT32_1_DATA:
01046 return "RECT_SINT32_1_DATA";
01047 case Gatan::DataType::RECT_FLOAT32_1_DATA:
01048 return "RECT_FLOAT32_1_DATA";
01049 case Gatan::DataType::RECT_FLOAT32_0_DATA:
01050 return "RECT_FLOAT32_0_DATA";
01051 case Gatan::DataType::SIGNED_INT64_DATA:
01052 return "SIGNED_INT64_DATA";
01053 case Gatan::DataType::UNSIGNED_INT64_DATA:
01054 return "UNSIGNED_INT64_DATA";
01055 default:
01056 break;
01057 }
01058 return "Unknown Type";
01059 }
01060