Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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

Generated on Tue May 25 17:34:08 2010 for EMAN2 by  doxygen 1.4.4