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 && nodata) {
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
00538 int ntags = 0;
00539 portable_fseek(in, sizeof(char) * 2, SEEK_CUR);
00540
00541 fread(&ntags, sizeof(ntags), 1, in);
00542
00543 ByteOrder::become_big_endian(&ntags);
00544
00545 LOGVAR("DM3: ntags = %d\n", ntags);
00546
00547 int err = 0;
00548
00549 for (int i = 0; i < ntags; i++) {
00550 TagEntry tag_entry(in, tagtable, this);
00551 err = tag_entry.read(nodata);
00552
00553 if (err) {
00554 break;
00555 }
00556 }
00557
00558 return err;
00559 }
00560
00561 string TagGroup::get_name() const
00562 {
00563 return name;
00564 }
00565
00566 int TagGroup::get_entry_id()
00567 {
00568 int id = entry_id;
00569 entry_id++;
00570 return id;
00571 }
00572
00573
00574
00576
00577 TagEntry::TagEntry(FILE * data_file, TagTable * table, TagGroup * parent)
00578 : in(data_file), tagtable(table), parent_group(parent), name("")
00579 {
00580 }
00581
00582 TagEntry::~TagEntry()
00583 {
00584 }
00585
00586
00587 int TagEntry::read(bool nodata)
00588 {
00589 LOGVAR("TagEntry::read()");
00590 int err = 0;
00591 char tag_type = 0;
00592 char *tmp_name = 0;
00593
00594 fread(&tag_type, sizeof(char), 1, in);
00595
00596 if (tag_type != GROUP_TAG && tag_type != DATA_TAG) {
00597 LOGERR("TagEntry::read() invalid tag type: %d", tag_type);
00598 return 1;
00599 }
00600
00601 short name_len = 0;
00602 fread(&name_len, sizeof(short), 1, in);
00603 ByteOrder::become_big_endian(&name_len);
00604
00605 if (name_len != 0) {
00606 tmp_name = new char[name_len + 1];
00607 fread(tmp_name, name_len, 1, in);
00608 tmp_name[name_len] = '\0';
00609 }
00610 else {
00611 string parent_name = parent_group->get_name();
00612 name_len = static_cast < short >(parent_name.size() + 4);
00613 tmp_name = new char[name_len + 1];
00614 sprintf(tmp_name, "%s #%d", parent_name.c_str(), parent_group->get_entry_id());
00615 }
00616
00617 name = string(tmp_name);
00618 if( tmp_name )
00619 {
00620 delete[]tmp_name;
00621 tmp_name = 0;
00622 }
00623
00624 LOGVAR("\ntag name: '%s', len: %d, type: '%s'",
00625 name.c_str(), name_len, Gatan::to_str((EntryType) tag_type));
00626
00627 if (tag_type == DATA_TAG) {
00628 TagData tag_data(in, tagtable, name);
00629 err = tag_data.read(nodata);
00630 }
00631 else if (tag_type == GROUP_TAG) {
00632 TagGroup group(in, tagtable, name);
00633 err = group.read(nodata);
00634 }
00635
00636 return err;
00637 }
00638
00639
00641
00642 DM3IO::DM3IO(const string & dm3_filename, IOMode rw)
00643 : filename(dm3_filename), rw_mode(rw), dm3file(0), initialized(false)
00644 {
00645 is_big_endian = ByteOrder::is_host_big_endian();
00646 tagtable = new TagTable();
00647 }
00648
00649 DM3IO::~DM3IO()
00650 {
00651 if (dm3file) {
00652 fclose(dm3file);
00653 dm3file = 0;
00654 }
00655 if (tagtable) {
00656 delete tagtable;
00657 tagtable = 0;
00658 }
00659 }
00660
00661 void DM3IO::init()
00662 {
00663 ENTERFUNC;
00664 if (initialized) {
00665 return;
00666 }
00667 initialized = true;
00668
00669 if (rw_mode != READ_ONLY) {
00670 throw ImageReadException(filename, "only support DM3 read-only");
00671 }
00672
00673 dm3file = sfopen(filename, READ_ONLY);
00674
00675 int buf[NUM_ID_INT];
00676 if (fread(buf, sizeof(buf), 1, dm3file) != 1) {
00677 throw ImageReadException(filename, "read first block of DM3 file");
00678 }
00679
00680 if (!is_valid(&buf)) {
00681 throw ImageReadException(filename, "invalid DM3 file");
00682 }
00683
00684 int byte_order = buf[2];
00685
00686 if (byte_order == 0) {
00687 is_big_endian = true;
00688 }
00689 else {
00690 is_big_endian = false;
00691 }
00692
00693 tagtable->set_endian(is_big_endian);
00694 ByteOrder::become_big_endian(buf, 3);
00695
00696 LOGDEBUG("dm3 ver = %d, image size = %d, is_big_endian = %d",
00697 buf[0], buf[1], (int) is_big_endian);
00698
00699 EXITFUNC;
00700 }
00701
00702
00703
00704 bool DM3IO::is_valid(const void *first_block)
00705 {
00706 ENTERFUNC;
00707
00708 if (!first_block) {
00709 return false;
00710 }
00711
00712 const int *data = static_cast < const int *>(first_block);
00713
00714 int img_ver = data[0];
00715 int img_size = data[1];
00716 int byte_order = data[2];
00717
00718 ByteOrder::become_big_endian(&img_ver);
00719
00720 if (img_ver != 3) {
00721 return false;
00722 }
00723
00724 ByteOrder::become_big_endian(&img_size);
00725 ByteOrder::become_big_endian(&byte_order);
00726
00727 if (byte_order != 0 && byte_order != 1) {
00728 return false;
00729 }
00730
00731 return true;
00732 }
00733
00734 bool DM3IO::is_image_big_endian()
00735 {
00736 init();
00737 return is_big_endian;
00738 }
00739
00740 int DM3IO::read_header(Dict & dict, int image_index, const Region * area, bool)
00741 {
00742 ENTERFUNC;
00743 int err = 0;
00744
00745
00746 if(image_index == -1) {
00747 image_index = 0;
00748 }
00749 image_index = 0;
00750 check_read_access(image_index);
00751
00752 portable_fseek(dm3file, NUM_ID_INT * sizeof(int), SEEK_SET);
00753 TagGroup root_group(dm3file, tagtable, "");
00754 root_group.read(true);
00755
00756 int nx = tagtable->get_xsize();
00757 int ny = tagtable->get_ysize();
00758
00759 check_region(area, IntSize(nx, ny));
00760 int xlen = 0, ylen = 0;
00761 EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
00762
00763 dict["nx"] = xlen;
00764 dict["ny"] = ylen;
00765 dict["nz"] = 1;
00766
00767 dict["DM3.acq_date"] = tagtable->get_string("Acquisition Date");
00768 dict["DM3.acq_time"] = tagtable->get_string("Acquisition Time");
00769 dict["DM3.source"] = tagtable->get_string("Source");
00770 dict["DM3.exposure_number"] = tagtable->get_int("Exposure Number");
00771 dict["DM3.exposure_time"] = tagtable->get_double("Exposure (s)");
00772 dict["DM3.zoom"] = tagtable->get_double("Zoom");
00773 dict["DM3.antiblooming"] = tagtable->get_int("Antiblooming");
00774 dict["DM3.indicated_mag"] = tagtable->get_double("Indicated Magnification");
00775 dict["DM3.actual_mag"] = tagtable->get_double("Actual Magnification");
00776 dict["DM3.pixel_size"] = tagtable->get_double("Pixel Size (um) #0");
00777 dict["DM3.name"] = tagtable->get_string("Name");
00778
00779 dict["DM3.voltage"] = tagtable->get_double("Voltage")/1000.0;
00780 dict["microscope_voltage"]=(float)dict["DM3.voltage"];
00781 dict["DM3.cs"] = tagtable->get_double("Cs(mm)");
00782 dict["microscope_cs"]=(float)dict["DM3.cs"];
00783
00784 dict["DM3.frame_type"] = tagtable->get_string("Processing");
00785 dict["DM3.camera_x"] = tagtable->get_int("Active Size (pixels) #0");
00786 dict["DM3.camera_y"] = tagtable->get_int("Active Size (pixels) #1");
00787 dict["DM3.binning_x"] = tagtable->get_int("Binning #0");
00788 dict["DM3.binning_y"] = tagtable->get_int("Binning #1");
00789 dict["datatype"] = to_em_datatype(tagtable->get_datatype());
00790
00791 if ((float)dict["DM3.actual_mag"] >0.0) {
00792 float apix=10000.0*(float)dict["DM3.pixel_size"]/(float)dict["DM3.actual_mag"];
00793 dict["apix_x"]=apix;
00794 dict["apix_y"]=apix;
00795 dict["apix_z"]=apix;
00796 }
00797
00798
00799
00800 EXITFUNC;
00801 return err;
00802 }
00803
00804 int DM3IO::read_data(float *rdata, int image_index, const Region * area, bool)
00805 {
00806 ENTERFUNC;
00807
00808 image_index = 0;
00809 check_read_access(image_index, rdata);
00810
00811 portable_fseek(dm3file, NUM_ID_INT * sizeof(int), SEEK_SET);
00812
00813 TagGroup root_group(dm3file, tagtable, "");
00814 root_group.read(false);
00815
00816 int nx = tagtable->get_xsize();
00817 int ny = tagtable->get_ysize();
00818
00819 check_region(area, IntSize(nx, ny));
00820
00821 int xlen = 0, ylen = 0, x0 = 0, y0 = 0;
00822 EMUtil::get_region_dims(area, nx, &xlen, ny, &ylen);
00823 EMUtil::get_region_origins(area, &x0, &y0);
00824
00825 char *data = tagtable->get_data();
00826 int data_type = tagtable->get_datatype();
00827
00828 int k = 0;
00829
00830 for (int i = y0; i < y0 + ylen; i++) {
00831 for (int j = x0; j < x0 + xlen; j++) {
00832 switch (data_type) {
00833 case Gatan::DataType::SIGNED_INT8_DATA:
00834 rdata[k] = (float) ((char *) data)[i * nx + j];
00835 break;
00836 case Gatan::DataType::UNSIGNED_INT8_DATA:
00837 rdata[k] = (float) ((unsigned char *) data)[i * nx + j];
00838 break;
00839 case Gatan::DataType::SIGNED_INT16_DATA:
00840 rdata[k] = (float) ((short *) data)[i * nx + j];
00841 break;
00842 case Gatan::DataType::UNSIGNED_INT16_DATA:
00843 rdata[k] = (float) ((unsigned short *) data)[i * nx + j];
00844 break;
00845 case Gatan::DataType::SIGNED_INT32_DATA:
00846 rdata[k] = (float) ((int *) data)[i * nx + j];
00847 break;
00848 case Gatan::DataType::UNSIGNED_INT32_DATA:
00849 rdata[k] = (float) ((unsigned int *) data)[i * nx + j];
00850 break;
00851 case Gatan::DataType::REAL4_DATA:
00852 rdata[k] = (float) ((float *) data)[i * nx + j];
00853 break;
00854 default:
00855 string desc = string("unsupported DM3 data type") +
00856 string(Gatan::to_str((Gatan::DataType::GatanDataType) data_type));
00857 throw ImageReadException(filename, desc);
00858 }
00859 k++;
00860 }
00861 }
00862 EXITFUNC;
00863 return 0;
00864 }
00865
00866 bool DM3IO::is_complex_mode()
00867 {
00868 return false;
00869 }
00870
00871 int DM3IO::write_header(const Dict &, int, const Region* , EMUtil::EMDataType, bool)
00872 {
00873 ENTERFUNC;
00874 LOGWARN("DM3 write is not supported.");
00875 EXITFUNC;
00876 return 1;
00877 }
00878
00879 int DM3IO::write_data(float *, int, const Region* , EMUtil::EMDataType, bool)
00880 {
00881 ENTERFUNC;
00882 LOGWARN("DM3 write is not supported.");
00883 EXITFUNC;
00884 return 1;
00885 }
00886
00887 void DM3IO::flush()
00888 {
00889 }
00890
00891 int Gatan::to_em_datatype(int gatan_datatype)
00892 {
00893 DataType::GatanDataType type = static_cast < DataType::GatanDataType > (gatan_datatype);
00894 int t = 0;
00895
00896 switch (type) {
00897 case Gatan::DataType::SIGNED_INT8_DATA:
00898 t = EMUtil::EM_CHAR;
00899 break;
00900 case Gatan::DataType::UNSIGNED_INT8_DATA:
00901 t = EMUtil::EM_UCHAR;
00902 break;
00903 case Gatan::DataType::SIGNED_INT16_DATA:
00904 t = EMUtil::EM_SHORT;
00905 break;
00906 case Gatan::DataType::UNSIGNED_INT16_DATA:
00907 t = EMUtil::EM_USHORT;
00908 break;
00909 case Gatan::DataType::SIGNED_INT32_DATA:
00910 t = EMUtil::EM_INT;
00911 break;
00912 case Gatan::DataType::UNSIGNED_INT32_DATA:
00913 t = EMUtil::EM_UINT;
00914 break;
00915 default:
00916 t = EMUtil::EM_UNKNOWN;
00917 }
00918
00919 return t;
00920 }
00921
00922
00923 const char *Gatan::to_str(TagData::Type type)
00924 {
00925 const char *str = "unknown";
00926
00927 switch (type) {
00928 case TagData::SHORT:
00929 str = "short";
00930 break;
00931 case TagData::INT:
00932 str = "int";
00933 break;
00934 case TagData::USHORT:
00935 str = "unsigned short";
00936 break;
00937 case TagData::UINT:
00938 str = "unsigned int";
00939 break;
00940 case TagData::FLOAT:
00941 str = "float";
00942 break;
00943 case TagData::DOUBLE:
00944 str = "double";
00945 break;
00946 case TagData::BOOLEAN:
00947 str = "boolean";
00948 break;
00949 case TagData::CHAR:
00950 str = "char";
00951 break;
00952 case TagData::OCTET:
00953 str = "octet";
00954 break;
00955 case TagData::STRUCT:
00956 str = "struct";
00957 break;
00958 case TagData::STRING:
00959 str = "string";
00960 break;
00961 case TagData::ARRAY:
00962 str = "array";
00963 break;
00964 default:
00965 str = "unknown";
00966 }
00967 return str;
00968 }
00969
00970 const char *Gatan::to_str(TagEntry::EntryType type)
00971 {
00972 const char *str = "unknown";
00973
00974 switch (type) {
00975 case TagEntry::GROUP_TAG:
00976 str = "Group";
00977 break;
00978 case TagEntry::DATA_TAG:
00979 str = "Data";
00980 break;
00981 default:
00982 str = "unknown";
00983 }
00984 return str;
00985 }
00986
00987
00988 const char *Gatan::to_str(Gatan::DataType::GatanDataType type)
00989 {
00990 switch (type) {
00991 case Gatan::DataType::SIGNED_INT16_DATA:
00992 return "SIGNED_INT16_DATA";
00993 case Gatan::DataType::REAL4_DATA:
00994 return "REAL4_DATA";
00995 case Gatan::DataType::COMPLEX8_DATA:
00996 return "COMPLEX8_DATA";
00997 case Gatan::DataType::OBSELETE_DATA:
00998 return "OBSELETE_DATA";
00999 case Gatan::DataType::PACKED_DATA:
01000 return "PACKED_DATA";
01001 case Gatan::DataType::UNSIGNED_INT8_DATA:
01002 return "UNSIGNED_INT8_DATA";
01003 case Gatan::DataType::SIGNED_INT32_DATA:
01004 return "SIGNED_INT32_DATA";
01005 case Gatan::DataType::RGB_DATA:
01006 return "RGB_DATA";
01007 case Gatan::DataType::SIGNED_INT8_DATA:
01008 return "SIGNED_INT8_DATA";
01009 case Gatan::DataType::UNSIGNED_INT16_DATA:
01010 return "UNSIGNED_INT16_DATA";
01011 case Gatan::DataType::UNSIGNED_INT32_DATA:
01012 return "UNSIGNED_INT32_DATA";
01013 case Gatan::DataType::REAL8_DATA:
01014 return "REAL8_DATA";
01015 case Gatan::DataType::COMPLEX16_DATA:
01016 return "COMPLEX16_DATA";
01017 case Gatan::DataType::BINARY_DATA:
01018 return "BINARY_DATA";
01019 case Gatan::DataType::RGB_UINT8_0_DATA:
01020 return "RGB_UINT8_0_DATA";
01021 case Gatan::DataType::RGB_UINT8_1_DATA:
01022 return "RGB_UINT8_1_DATA";
01023 case Gatan::DataType::RGB_UINT16_DATA:
01024 return "RGB_UINT16_DATA";
01025 case Gatan::DataType::RGB_FLOAT32_DATA:
01026 return "RGB_FLOAT32_DATA";
01027 case Gatan::DataType::RGB_FLOAT64_DATA:
01028 return "RGB_FLOAT64_DATA";
01029 case Gatan::DataType::RGBA_UINT8_0_DATA:
01030 return "RGBA_UINT8_0_DATA";
01031 case Gatan::DataType::RGBA_UINT8_1_DATA:
01032 return "RGBA_UINT8_1_DATA";
01033 case Gatan::DataType::RGBA_UINT8_2_DATA:
01034 return "RGBA_UINT8_2_DATA";
01035 case Gatan::DataType::RGBA_UINT8_3_DATA:
01036 return "RGBA_UINT8_3_DATA";
01037 case Gatan::DataType::RGBA_UINT16_DATA:
01038 return "RGBA_UINT16_DATA";
01039 case Gatan::DataType::RGBA_FLOAT32_DATA:
01040 return "RGBA_FLOAT32_DATA";
01041 case Gatan::DataType::RGBA_FLOAT64_DATA:
01042 return "RGBA_FLOAT64_DATA";
01043 case Gatan::DataType::POINT2_SINT16_0_DATA:
01044 return "POINT2_SINT16_0_DATA";
01045 case Gatan::DataType::POINT2_SINT16_1_DATA:
01046 return "POINT2_SINT16_1_DATA";
01047 case Gatan::DataType::POINT2_SINT32_0_DATA:
01048 return "POINT2_SINT32_0_DATA";
01049 case Gatan::DataType::POINT2_FLOAT32_0_DATA:
01050 return "POINT2_FLOAT32_0_DATA";
01051 case Gatan::DataType::RECT_SINT16_1_DATA:
01052 return "RECT_SINT16_1_DATA";
01053 case Gatan::DataType::RECT_SINT32_1_DATA:
01054 return "RECT_SINT32_1_DATA";
01055 case Gatan::DataType::RECT_FLOAT32_1_DATA:
01056 return "RECT_FLOAT32_1_DATA";
01057 case Gatan::DataType::RECT_FLOAT32_0_DATA:
01058 return "RECT_FLOAT32_0_DATA";
01059 case Gatan::DataType::SIGNED_INT64_DATA:
01060 return "SIGNED_INT64_DATA";
01061 case Gatan::DataType::UNSIGNED_INT64_DATA:
01062 return "UNSIGNED_INT64_DATA";
01063 default:
01064 break;
01065 }
01066 return "Unknown Type";
01067 }
01068