dm3io.cpp

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 //              LOGDEBUG("  %s: %s", (*p).first.c_str(), (*p).second.c_str());
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 // string tag data are stored in unicode
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         //single image format, index can only be zero
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 //tagtable->dump();
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         //single image format, index can only be zero
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 

Generated on Thu Nov 17 12:42:57 2011 for EMAN2 by  doxygen 1.4.7