Changeset 1750

Show
Ignore:
Timestamp:
01/11/10 23:38:27 (2 years ago)
Author:
andreas
Message:

backported big/little endian mrc export from dng

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/qt_gui/src/io/lib/SConscript

    r1610 r1750  
    88image_format_conversion.cc 
    99convert_vax_data.h 
     10converting_streams.hh 
     11convert.hh 
    1012""") 
    1113 
     
    2426io_nanoscope.cc 
    2527convert_vax_data.c 
     28convert.cc 
    2629""") 
    2730 
  • branches/qt_gui/src/io/lib/image_format.cc

    r1604 r1750  
    3030  encoding_(IEEE), 
    3131  format_("auto"), 
    32   subimage_(-1) 
     32  subimage_(-1), 
     33  byte_order_(IPLT_LITTLE_ENDIAN) 
    3334{ 
    3435  string lformatstring=formatstring; 
    35   std::transform(lformatstring.begin(),lformatstring.end(),lformatstring.begin(),tolower); 
    3636  bool set_depth_=false; 
    3737  string subformat(""); 
     
    8989  if(subformat.find("v")!=string::npos) { 
    9090    encoding_=VAX; 
     91    byte_order_=IPLT_VAX_DATA; 
     92  } 
     93  if(subformat.find("e")!=string::npos) { 
     94    byte_order_=IPLT_LITTLE_ENDIAN; 
     95  } 
     96  if(subformat.find("E")!=string::npos) { 
     97    byte_order_=IPLT_BIG_ENDIAN; 
    9198  } 
    9299 
     
    109116} 
    110117 
     118unsigned int ImageFormat::GetByteOrder() const 
     119{ 
     120  return byte_order_;; 
     121} 
     122  
    111123unsigned int ImageFormat::GetBitDepth() const 
    112124{ 
  • branches/qt_gui/src/io/lib/image_format.hh

    r1604 r1750  
    2020 
    2121#include <iplt/base.hh> 
    22  
     22#include "convert.hh" 
    2323 
    2424namespace iplt { namespace io { 
     
    3535  unsigned int GetBitDepth() const; 
    3636  unsigned int GetEncoding() const; 
     37  unsigned int GetByteOrder() const; 
    3738  string GetFormat() const; 
    3839  int GetSubImage() const; 
     
    5152  string format_; 
    5253  int subimage_; 
     54  unsigned int byte_order_; 
    5355}; 
    5456 
  • branches/qt_gui/src/io/lib/io_mrc.cc

    r1647 r1750  
    1616#include <boost/scoped_array.hpp> 
    1717#include <iplt/progress.hh> 
     18#include <boost/algorithm/string.hpp> 
     19#include <boost/format.hpp> 
    1820 
    1921#include <cstdio> 
     
    2224 
    2325#include <iplt/normalizer_impl.hh> 
     26#include <iplt/alg/normalizer_factory.hh> 
    2427#include <iplt/util.hh> 
    2528 
     
    2831 
    2932#include "io_mrc.hh" 
     33#include "converting_streams.hh" 
     34#include <boost/filesystem/operations.hpp> 
    3035 
    3136namespace iplt { namespace io { 
     
    7075*/ 
    7176 
    72 template <typename B, bool swap_flag, bool ancient_float_flag> 
     77bool mrc_plugin::MatchContent(unsigned char* header) 
     78
     79  if( 
     80     header[208]=='M' &&   
     81     header[209]=='A' && 
     82     header[210]=='P' 
     83     ){ 
     84      return true; 
     85  } 
     86  return false; 
     87
     88bool mrc_plugin::MatchType(const string& type) 
     89
     90  if(type=="mrc" || type=="ccp4") { 
     91    return true; 
     92  } 
     93  return false; 
     94
     95bool mrc_plugin::MatchSuffix(const string& suffix) 
     96
     97    if(suffix==".mrc" || suffix==".ccp4" || suffix==".map") { 
     98      return true; 
     99    } 
     100    return false; 
     101
     102 
     103namespace detail{ 
     104 
     105class header_base { 
     106public: 
     107  header_base(): 
     108    nc(0),nr(0),ns(0), 
     109    mode(0), 
     110    ncstart(0),nrstart(0),nsstart(0), 
     111    nx(0),ny(0),nz(0), 
     112    x(0.0),y(0.0),z(0.0), 
     113    alpha(0.0),beta(0.0),gamma(0.0), 
     114    mapc(1),mapr(2),maps(3), 
     115    amin(0.0),amax(0.0),amean(0.0), 
     116    ispg(0), 
     117    nsymbt(0), 
     118    nlabel(1), 
     119    label() 
     120  { 
     121    for(unsigned int i=0;i<800;++i) 
     122    { 
     123      label[i]=' '; 
     124    } 
     125  } 
     126  header_base(const ConstImageHandle& im): 
     127    nc(), 
     128    nr(static_cast<int>(im.GetExtent().GetSize().GetHeight())), 
     129    ns(static_cast<int>(im.GetExtent().GetSize().GetDepth())), 
     130    mode(), 
     131    ncstart(im.GetExtent().GetStart()[0]), 
     132    nrstart(im.GetExtent().GetStart()[1]), 
     133    nsstart(im.GetExtent().GetStart()[2]), 
     134    nx(static_cast<int>(im.GetExtent().GetSize().GetWidth())), 
     135    ny(static_cast<int>(im.GetExtent().GetSize().GetHeight())), 
     136    nz(static_cast<int>(im.GetExtent().GetSize().GetDepth())), 
     137    x(), 
     138    y(), 
     139    z(), 
     140    alpha(90.0),beta(90.0),gamma(90.0), 
     141    mapc(1),mapr(2),maps(3), 
     142    amin(0.0),amax(0.0),amean(0.0), 
     143    ispg(0), 
     144    nsymbt(0), 
     145    nlabel(1), 
     146    label() 
     147  { 
     148    if(im.GetType()==REAL){ 
     149      nc=static_cast<int>(im.GetExtent().GetSize().GetWidth()); 
     150      mode=2; 
     151      x=im.GetExtent().GetSize().GetWidth()*im.GetSpatialSampling()[0]; 
     152      y=im.GetExtent().GetSize().GetHeight()*im.GetSpatialSampling()[1]; 
     153      z=im.GetExtent().GetSize().GetDepth()*im.GetSpatialSampling()[2]; 
     154    }else{ 
     155      nc=static_cast<int>(im.GetExtent().GetSize().GetWidth()/2 +1); 
     156      mode=4; 
     157      x=1.0; 
     158      y=1.0; 
     159      z=1.0; 
     160    } 
     161    iplt::alg::Stat stat; 
     162    im.Apply(stat); 
     163    amin=stat.GetMinimum(); 
     164    amax=stat.GetMaximum(); 
     165    amean=stat.GetMean(); 
     166    for(unsigned int i=0;i<800;++i) 
     167    { 
     168      label[i]=' '; 
     169    } 
     170  } 
     171  template<int CONVERSIONTYPE> 
     172  void WriteCommonData(BinaryOStream<CONVERSIONTYPE>& out) const 
     173  { 
     174    out << nc << nr << ns; 
     175    out << mode; 
     176    out << ncstart << nrstart << nsstart; 
     177    out << nx << ny << nz; 
     178    out << x << y << z << alpha << beta << gamma; 
     179    out << mapc << mapr << maps; 
     180    out << amin << amax << amean; 
     181    out << ispg; 
     182    out << nsymbt; 
     183  } 
     184  template<int CONVERSIONTYPE> 
     185  void WriteLabel(BinaryOStream<CONVERSIONTYPE>& out) const 
     186  { 
     187    out << nlabel; 
     188    out.write(label,800); 
     189  } 
     190  template<int CONVERSIONTYPE> 
     191  void ReadCommonData(BinaryIStream<CONVERSIONTYPE>& in) 
     192  { 
     193    in >> nc >> nr >> ns; 
     194    in >> mode; 
     195    in >> ncstart >> nrstart >> nsstart; 
     196    in >> nx >> ny >> nz; 
     197    in >> x >> y >> z >> alpha >> beta >> gamma; 
     198    in >> mapc >> mapr >> maps; 
     199    in >> amin >> amax >> amean; 
     200    in >> ispg; 
     201    in >> nsymbt; 
     202  } 
     203  template<int CONVERSIONTYPE> 
     204  void ReadLabel(BinaryIStream<CONVERSIONTYPE>& in) 
     205  { 
     206    in >> nlabel; 
     207    in.read(label,800); 
     208  } 
     209  void Print() 
     210  { 
     211    mlog(1) << "ncrs: " << nc << " " << nr << " " << ns << std::endl ; 
     212    mlog(1) << "mode " << mode << std::endl ; 
     213    mlog(1) << "nxyz: " << nx << " " << ny << " " << nz << std::endl ; 
     214    mlog(1) << "cell: " << x << " " << y << " " << z ; 
     215    mlog(1) << alpha << " " << beta << " " << gamma << std::endl ; 
     216    mlog(1) << "order: " << mapc << mapr << maps << std::endl ; 
     217    mlog(1) << "sg: " << ispg << " " << nsymbt << std::endl ; 
     218    mlog(1) << "nlabel: " << nlabel << std::endl ; 
     219  } 
     220 
     221  int nc,nr,ns; 
     222  int mode; 
     223  int ncstart,nrstart,nsstart; 
     224  int nx,ny,nz; 
     225  float x,y,z; 
     226  float alpha,beta,gamma; 
     227  int mapc,mapr,maps; 
     228  float amin,amax,amean; 
     229  int ispg; 
     230  int nsymbt; 
     231  int nlabel; 
     232  char label[800]; 
     233}; 
     234 
     235// mrc old style header 
     236class mrc_header: public header_base 
     237
     238public: 
     239  mrc_header(): 
     240    header_base(), 
     241    xorigin(0.0), 
     242    yorigin(0.0) 
     243  { 
     244  } 
     245  mrc_header(const ConstImageHandle& im): 
     246    header_base(im), 
     247    xorigin(0.0), // todo determine origin 
     248    yorigin(0.0) 
     249  { 
     250  } 
     251  void Print() 
     252  { 
     253    mlog(1) << "mrc header" << std::endl ; 
     254    header_base::Print(); 
     255    mlog(1) << "ori: " << xorigin << " " << yorigin << std::endl ; 
     256  } 
     257  static int DetermineDataFormat( std::istream& f) 
     258  { 
     259    float x; 
     260    unsigned int mapc; 
     261    BinaryIStream<IPLT_LITTLE_ENDIAN> bs(f); 
     262    bs.seekg(10*4,std::ios::beg); // seek to x 
     263    bs >> x; 
     264    bs.seekg(5*4,std::ios::cur); // seek to mapc 
     265    bs >> mapc; 
     266    bs.seekg(0,std::ios::beg); // seek to beginning 
     267    if(mapc<1 || mapc>3) { 
     268      // try byte swapping 
     269      Convert<IPLT_BIG_ENDIAN,unsigned int>::FromIP(&mapc); 
     270      if(mapc<1 || mapc>3) { 
     271        throw(Error("error reading mrc file (even tried byte-swapping")); 
     272      } 
     273      return IPLT_BIG_ENDIAN; 
     274    }else if(x>0.0 || x<1.0) { 
     275      Convert<IPLT_VAX_DATA,float>::FromIP(&x); 
     276      if(x<1.0) { 
     277        mlog(4) << "suspicious floating Point value in mrc header" << std::endl ; 
     278        return IPLT_LITTLE_ENDIAN; 
     279      }else{ 
     280        return IPLT_VAX_DATA; 
     281      } 
     282    } 
     283    return IPLT_LITTLE_ENDIAN; 
     284  } 
     285 
     286  float xorigin,yorigin; 
     287}; 
     288 
     289template<int CONVERSIONTYPE> 
     290BinaryOStream<CONVERSIONTYPE>& operator<< (BinaryOStream<CONVERSIONTYPE>& out, const mrc_header& h ) 
     291
     292  h.WriteCommonData(out); 
     293  char dummy[116]; 
     294  for(int i=0;i<116;i++) dummy[i]=0; 
     295  out.write(dummy,116); 
     296  out << h.xorigin << h.yorigin; 
     297  h.WriteLabel(out); 
     298  return  out; 
     299
     300 
     301template<int CONVERSIONTYPE> 
     302BinaryIStream<CONVERSIONTYPE>& operator>> (BinaryIStream<CONVERSIONTYPE>& in, mrc_header& h) 
     303
     304  h.ReadCommonData(in); 
     305  in.seekg(116,std::ios::cur); 
     306  in >> h.xorigin >> h.yorigin; 
     307  h.ReadLabel(in); 
     308 
     309  if(h.nc<1) h.nc=1; 
     310  if(h.nr<1) h.nr=1; 
     311  if(h.ns<1) h.ns=1; 
     312 
     313  // skip symm info, seek to start of actual data 
     314  if(h.nsymbt>0){ 
     315    in.seekg(h.nsymbt,std::ios::cur); 
     316  } 
     317  return in; 
     318
     319 
     320 
     321 
     322class ccp4_header: public header_base { 
     323public: 
     324  ccp4_header(): 
     325    header_base(), 
     326    lskflag(), 
     327    skwmat(), 
     328    skwtrn(), 
     329    ox(0.0), 
     330    oy(0.0), 
     331    oz(0.0), 
     332    arms() 
     333  { 
     334  } 
     335  ccp4_header(const ConstImageHandle& im): 
     336    header_base(im), 
     337    lskflag(), 
     338    skwmat(), 
     339    skwtrn(), 
     340    ox(0.0), 
     341    oy(0.0), 
     342    oz(0.0), 
     343    arms() 
     344  { 
     345    lskflag=0; 
     346    for(unsigned int i=0;i<9;++i){ 
     347      skwmat[i]=0.0; 
     348    } 
     349    for(unsigned int i=0;i<3;++i){ 
     350      skwtrn[i]=0.0; 
     351    } 
     352    arms = 0.1; 
     353  } 
     354 
     355static int DetermineDataFormat( std::istream& f) 
     356
     357  char machst[4]; 
     358  // from the ccp4 documentation 
     359  // The machine stamp is a 32-bit quantity containing a set of four `nibbles' 
     360  // (half-bytes)---only half the space is used. Each nibble is a number 
     361  // specifying the representation of (in C terms) double (d) , float (f), 
     362  // int (i) and unsigned char (c) types. Thus each stamp is of the form 
     363  // 0xdfic0000. The values for the floating point nibbles may be taken from the 
     364  // list (following HDF): 
     365  // 1        Big-endian ieee 
     366  // 2        VAX 
     367  // 3        Cray 
     368  // 4        Little-endian ieee 
     369  // 5        Convex native 
     370  // 6        Fijitsu VP 
     371  f.seekg(53*4,std::ios::beg); // seek to machine stamp 
     372  f.read(machst,4); 
     373  f.seekg(0,std::ios::beg); // seek to beginning 
     374  char float_machst= machst[0] & 0x0f; 
     375  if(float_machst == 1){ 
     376    mlog(5) << "CCP4Import: reading big endian data" <<std::endl; 
     377    return IPLT_BIG_ENDIAN; 
     378  }else if(float_machst == 2){ 
     379    mlog(5) << "CCP4Import: reading vax data" <<std::endl; 
     380    return IPLT_VAX_DATA; 
     381  }else if(float_machst == 4){ 
     382    mlog(5) << "CCP4Import: reading little endian data" <<std::endl; 
     383    return IPLT_LITTLE_ENDIAN; 
     384  } else{ 
     385    throw(Error("CCP4Import: Cray, Convex native and Fijitsu VP formats are not supported.")); 
     386  } 
     387
     388 
     389     
     390  void Print() 
     391  { 
     392    using boost::format; 
     393    namespace bf = boost::filesystem; 
     394 
     395    mlog(1) << "ccp4 header:" <<std::endl; 
     396    header_base::Print(); 
     397    mlog(1) << " arms: " << arms <<std::endl; 
     398  } 
     399 
     400  int lskflag; 
     401  float skwmat[9]; 
     402  float skwtrn[3]; 
     403  float ox,oy,oz; 
     404  float arms; 
     405}; 
     406 
     407 
     408 
     409 
     410template <int CONVERSIONTYPE> 
     411BinaryIStream<CONVERSIONTYPE>& operator>> (BinaryIStream<CONVERSIONTYPE>& in, ccp4_header& header) 
     412
     413  header.ReadCommonData(in); 
     414  in >> header.lskflag; 
     415  in >> header.skwmat[0] >> header.skwmat[1] >> header.skwmat[2]; 
     416  in >> header.skwmat[3] >> header.skwmat[4] >> header.skwmat[5]; 
     417  in >> header.skwmat[6] >> header.skwmat[7] >> header.skwmat[8]; 
     418  in >> header.skwtrn[0] >> header.skwtrn[1] >> header.skwtrn[2]; 
     419  in.seekg(48,std::ios::cur); 
     420  in >> header.ox >> header.oy >> header.oz; 
     421  in.seekg(8,std::ios::cur); // skip map and machst 
     422  in >> header.arms; 
     423  header.ReadLabel(in); 
     424 
     425  if(header.nx<1) header.nx=1; 
     426  if(header.ny<1) header.ny=1; 
     427  if(header.nz<1) header.nz=1; 
     428 
     429  // skip symm info, seek to start of actual data 
     430  if(header.nsymbt>0) 
     431    in.seekg(header.nsymbt,std::ios::cur); 
     432  return in; 
     433
     434template <int CONVERSIONTYPE> 
     435BinaryOStream<CONVERSIONTYPE>& operator<< (BinaryOStream<CONVERSIONTYPE>& out, ccp4_header& header) 
     436
     437  header.WriteCommonData(out); 
     438  out << header.lskflag; 
     439  out << header.skwmat[0] << header.skwmat[1] << header.skwmat[2]; 
     440  out << header.skwmat[3] << header.skwmat[4] << header.skwmat[5]; 
     441  out << header.skwmat[6] << header.skwmat[7] << header.skwmat[8]; 
     442  out << header.skwtrn[0] << header.skwtrn[1] << header.skwtrn[2]; 
     443  char dummy[48]; 
     444  for(unsigned int i=0;i<48;++i){ 
     445    dummy[i]=0; 
     446  } 
     447  out.write(dummy,48); 
     448  out << header.ox << header.oy << header.oz; 
     449  out.write("MAP",4); 
     450  char machst[4]={0x44,0x41,0x00,0x00};// little endian 
     451  if(CONVERSIONTYPE==IPLT_VAX_DATA){ 
     452     machst[0]=0x22; 
     453     machst[1]=0x41; 
     454  }else if(CONVERSIONTYPE==IPLT_BIG_ENDIAN){ 
     455     machst[0]=0x11; 
     456     machst[1]=0x11; 
     457  } 
     458  out.write(reinterpret_cast<char*>(&machst),4); 
     459  out << header.arms; 
     460  header.WriteLabel(out); 
     461  return out; 
     462
     463 
     464 
     465template <typename B,int CONVERSIONTYPE> 
     466void real_filler(image_state::RealSpatialImageState& isi, 
     467                 BinaryIStream<CONVERSIONTYPE>& f, 
     468                 const header_base& header) 
     469
     470  int mapc=header.mapc-1; 
     471  int mapr=header.mapr-1; 
     472  int maps=header.maps-1; 
     473 
     474  Point pnt; 
     475  char this_dummy; //create dummy variable to give to Progress as this 
     476  Progress::Instance().Register(&this_dummy,header.ns*header.nr,100); 
     477  for(int is=0;is<header.ns;++is) { 
     478    pnt[maps]=header.nsstart+is; 
     479    for(int ir=0;ir<header.nr;++ir) { 
     480      pnt[mapr]=header.nrstart+ir; 
     481      for(int ic=0;ic<header.nc;++ic) { 
     482        pnt[mapc]=header.ncstart+ic; 
     483        B tmp; 
     484        f >> tmp; 
     485        isi.Value(pnt) = static_cast<Real>(tmp); 
     486      } 
     487      Progress::Instance().AdvanceProgress(&this_dummy); 
     488    } 
     489  } 
     490  Progress::Instance().DeRegister(&this_dummy); 
     491
     492 
     493template <typename B,int CONVERSIONTYPE> 
    73494void complex_filler(image_state::ComplexHalfFrequencyImageState& isi, 
    74             FilePtr& fhandle, 
    75             const mrc_header& header, 
    76             double scale) 
    77 
    78   if(header.mx&0x1 || header.my&0x1) { 
     495                    BinaryIStream<CONVERSIONTYPE> & fhandle, 
     496                    header_base& header) 
     497
     498  int mapc=header.mapc-1; 
     499  int mapr=header.mapr-1; 
     500  int maps=header.maps-1; 
     501  B real, imag; 
     502  if(header.nx & 0x1 || header.ny & 0x1) { 
    79503    throw Error("Only EVENxEVEN MRC half-complex format supported"); 
    80504  } 
    81505  // always assume hcomplex (!) 
    82   if((header.nx-1)*2 == header.ny) { 
     506  if((header.nc-1)*2 == header.nr) { 
    83507    char this_dummy; //create dummy variable to give to Progress as this 
    84     Progress::Instance().Register(&this_dummy,header.nz*header.ny,100); 
    85  
    86     boost::scoped_array<B> rawp(new B[header.nx*2]); 
    87     for(int sz=0;sz<header.nz;++sz) { 
    88       int pz = sz>header.nz/2 ? header.nz-sz : sz; 
    89       int sy=header.ny; 
    90       int cy=0; 
     508    Progress::Instance().Register(&this_dummy,header.ns*header.nr,100); 
     509    Point p; 
     510    for(int ss=0;ss<header.ns;++ss) { 
     511      p[maps] = ss>header.ns/2 ? header.ns-ss : ss; 
     512      int sr=header.nr; 
     513      int cr=0; 
    91514      // first half 
    92       for(;sy>header.ny/2;--sy,++cy) { 
    93         int py = sy-header.ny/2; 
    94         fread(rawp.get(),sizeof(B)*2,header.nx,fhandle); 
    95         if(swap_flag) { 
    96           util::swap_buf<B>(rawp.get(),header.nx*2); 
    97     } 
    98     if(ancient_float_flag) { 
    99       VaxToIEEE<B>(rawp.get(),header.nx*2); 
    100     } 
    101         int sx=0; 
    102         for(;sx<header.nx-1;sx++) { 
     515      for(;sr>header.nr/2;--sr,++cr) { 
     516        p[mapr] = sr-header.nr/2; 
     517        int sc=0; 
     518        for(;sc<header.nc-1;sc++) { 
     519          p[mapc]=-sc; 
    103520          // complex conjugate 
    104           isi.Value(Point(-sx,py,pz))=Complex(scale*double(rawp.get()[sx*2]),-scale*double(rawp.get()[sx*2+1])); 
    105           //mlog(5) << " " << Point(-sx,py,pz) << " <- " << Point(sx,cy,sz) << "*" << " " << isi.Value(Point(-sx,py,pz)) << std::endl; 
     521          fhandle >> real >> imag; 
     522          isi.Value(p)=Complex(Real(real),-Real(imag)); 
     523          mlog(5) << " " << p  << " " << isi.Value(p) << std::endl ; 
    106524        } 
    107         if(sy==header.ny) { 
    108           isi.Value(Point(py,header.ny/2,pz))=Complex(scale*double(rawp.get()[sx*2]),scale*double(rawp.get()[sx*2+1])); 
    109           //mlog(5) << "+" << Point(py,header.ny/2,pz) << " <- " << Point(sx,cy,sz) << " " << " " << isi.Value(Point(py,header.ny/2,pz)) << std::endl; 
     525        if(sr==header.nr) { 
     526        // why set point (py,header.ny/2,pz)? 
     527        //  isi.Value(Point(py,header.ny/2,pz))=scale*Complex(Real(real),Real(imag)); 
     528        //  mlog(5) << "+" << Point(py,header.ny/2,pz) << " <- " << Point(sx,cy,sz) << " " << " " << isi.Value(Point(py,header.ny/2,pz)) << std::endl ; 
     529          p[mapc]=p[header.mapr]; 
     530          p[mapr]=header.nr/2; 
     531          isi.Value(p)=Complex(Real(real),Real(imag)); 
     532          mlog(5) << "+" << p << " " << isi.Value(p) << std::endl ; 
    110533        } 
    111         Progress::Instance().AdvanceProgress(&this_dummy);  
    112       } 
    113       // second half, sy starts at header.ny/2 
    114       for(;sy>0;--sy,++cy) { 
    115         fread(rawp.get(),sizeof(B)*2,header.nx,fhandle)
    116         if(swap_flag) 
    117           util::swap_buf<B>(rawp.get(),header.nx*2); 
    118         int sx=0
    119         for(;sx<header.nx-1;++sx) { 
    120           isi.Value(Point(sx,header.ny/2-sy,sz))=Complex(scale*double(rawp.get()[sx*2]),scale*double(rawp.get()[sx*2+1])); 
    121           //mlog(5) << " " << Point(sx,header.ny/2-sy,sz) << " <- " << Point(sx,cy,sz) << " " << isi.Value(Point(sx,header.ny/2-sy,sz)) << std::endl
     534        Progress::Instance().AdvanceProgress(&this_dummy); 
     535      } 
     536      // second half, sr starts at header.nr/2 
     537      for(;sr>0;--sr,++cr) { 
     538        p[mapr]=header.nr/2-sr
     539        int sc=0; 
     540        for(;sc<header.nc-1;++sc) { 
     541          p[mapc]=sc
     542          fhandle >> real >> imag; 
     543          isi.Value(p)=Complex(Real(real),Real(imag)); 
     544          mlog(5) << " " << p << " " << isi.Value(p) << std::endl
    122545        } 
    123         isi.Value(Point(sx,header.ny/2-sy,sz))=Complex(scale*double(rawp.get()[sx*2]),-scale*double(rawp.get()[sx*2+1])); 
    124         //mlog(5) << " " << Point(sx,header.ny/2-sy,sz) << " <- " << Point(sx,cy,sz) << "*" << isi.Value(Point(sx,header.ny/2-sy,sz)) << std::endl; 
    125         Progress::Instance().AdvanceProgress(&this_dummy);  
    126       } 
    127       // set second half of y=0 and y=ny/2 line 
    128       for(int sx=1;sx<header.nx-1;++sx) { 
    129         isi.Value(Point(-sx,0,sz))=std::conj(isi.Value(Point(sx,0,sz))); 
    130         //mlog(5) << " " << Point(-sx,0,sz) << " <- " << Point(sx,0,sz) << "**" << std::endl; 
    131         isi.Value(Point(sx,header.ny/2,sz))=std::conj(isi.Value(Point(-sx,header.ny/2,sz))); 
    132         //mlog(5) << " " << Point(sx,header.ny/2,sz) << " <- " << Point(-sx,header.ny/2,sz) << "**" << std::endl; 
     546        p[mapc]=sc; 
     547        isi.Value(p)=Complex(Real(real),-Real(imag)); 
     548        mlog(5) << " " << p << " " << isi.Value(p) << std::endl ; 
     549        Progress::Instance().AdvanceProgress(&this_dummy); 
     550      } 
     551      // set second half of r=0 and r=nr/2 line 
     552      for(int sc=1;sc<header.nc-1;++sc) { 
     553        p[mapc]=sc; 
     554        p[mapr]=0; 
     555        p[maps]=ss; 
     556        isi.Value(Point(-p[0],p[1],p[2]))=std::conj(isi.Value(p)); 
     557        mlog(5) << " " << Point(-p[0],p[1],p[2]) << " <- " << p << "**" << std::endl ; 
     558        p[mapr]=header.nr/2; 
     559        isi.Value(p)=std::conj(isi.Value(Point(-p[0],p[1],p[2]))); 
     560        mlog(5) << " " << p << " <- " << Point(-p[0],p[1],p[2]) << "**" << std::endl ; 
    133561      } 
    134562    } 
    135563    Progress::Instance().DeRegister(&this_dummy); 
    136   } else if(header.nx*2 == header.ny+1) { 
     564  } else if(header.nc*2 == header.nr+1) { 
    137565    throw Error("Half Complex Format NX = (NY+1)/2 not supported"); 
    138566  } else { 
     
    140568  } 
    141569} 
    142    
    143 template <typename B, bool swap_flag, bool ancient_float_flag>   
    144 void real_filler(image_state::RealSpatialImageState& isi, 
    145          FilePtr& fhandle, 
    146          const mrc_header& header, 
    147          double scale) 
    148 
    149   boost::scoped_array<B> rawp(new B[header.nx]); 
    150    
     570 
     571template <typename B,int CONVERSIONTYPE> 
     572void real_dumper(BinaryOStream<CONVERSIONTYPE>& f, header_base& header, const ConstImageHandle& image, const ImageFormat&  formatmrc,const  NormalizerPtr& norm) 
     573
     574  image_state::RealSpatialImageState *isr=dynamic_cast<image_state::RealSpatialImageState*>(image.ImageStatePtr().get()); 
     575  if(! isr){ 
     576    throw(Error("MRC/CCP4 export: dynamic cast failed in real dumper.")); 
     577  } 
     578  int mapc=header.mapc-1; 
     579  int mapr=header.mapr-1; 
     580  int maps=header.maps-1; 
     581 
     582 
     583  Point pnt; 
    151584  char this_dummy; //create dummy variable to give to Progress as this 
    152   Progress::Instance().Register(&this_dummy,header.nz*header.ny,100); 
    153   for(int sz=0;sz<header.nz;sz++) { 
    154     for(int sy=0;sy<header.ny;sy++) { 
    155        
    156       fread(rawp.get(),sizeof(B),header.nx,fhandle); 
    157        
    158       if(swap_flag) { 
    159     util::swap_buf<B>(rawp.get(),header.nx); 
    160       } 
    161        
    162       if(ancient_float_flag) { 
    163     VaxToIEEE<B>(rawp.get(),header.nx); 
    164       } 
    165  
    166       for(int sx=0;sx<header.nx;sx++) { 
    167         isi.Value(Index(sx,sy,sz)) = scale*static_cast<Real>(rawp[sx]); 
    168       } 
    169       Progress::Instance().AdvanceProgress(&this_dummy);  
     585  Progress::Instance().Register(&this_dummy,header.ns*header.nr,100); 
     586  Point start=image.GetExtent().GetStart(); 
     587  for(int ss=0;ss<header.ns;++ss) { 
     588    pnt[maps]=header.nsstart+ss; 
     589    for(int sr=0;sr<header.nr;++sr) { 
     590      pnt[mapr]=header.nrstart+sr; 
     591      for(int sc=0;sc<header.nc;++sc) { 
     592        pnt[mapc]=header.ncstart+sc; 
     593        f << static_cast<B>(norm->Convert(isr->Value(pnt))); 
     594      } 
     595      Progress::Instance().AdvanceProgress(&this_dummy); 
    170596    } 
    171597  } 
     
    173599} 
    174600 
    175  
    176 template <typename B> 
    177 void dump_real_to_file(FilePtr& f, mrc_header& header, const ConstImageHandle& image, const NormalizerPtr& norm) 
    178 
    179   boost::scoped_array<B> rawp(new B[header.nx]); 
    180   image_state::RealSpatialImageState *isr=dynamic_cast<image_state::RealSpatialImageState*>(image.ImageStatePtr().get()); 
    181  
     601template <typename B,int CONVERSIONTYPE> 
     602void complex_dumper(BinaryOStream<CONVERSIONTYPE>& f, 
     603                    header_base& header, 
     604                    const ConstImageHandle& image, 
     605                    const ImageFormat&  formatmrc, 
     606                    const  NormalizerPtr& norm) 
     607
     608  int mapc=header.mapc-1; 
     609  int mapr=header.mapr-1; 
     610  int maps=header.maps-1; 
     611 
     612 
     613  image_state::ComplexHalfFrequencyImageState *isc=dynamic_cast<image_state::ComplexHalfFrequencyImageState*>(image.ImageStatePtr().get()); 
     614  if(! isc){ 
     615    throw(Error("MRC/CCP4 export: dynamic cast failed in complex dumper.")); 
     616  } 
    182617  char this_dummy; //create dummy variable to give to Progress as this 
    183   Progress::Instance().Register(&this_dummy,header.nz*header.ny,100); 
    184   Point start=image.GetExtent().GetStart(); 
    185   for(int sz=0;sz<header.nz;++sz) { 
    186     for(int sy=0;sy<header.ny;++sy) { 
    187        for(int sx=0;sx<header.nx;++sx) { 
    188          Point p=Point(sx,sy,sz)+start; 
    189          rawp[sx] = static_cast<B>(norm->Convert(isr->Value(p))); 
    190        } 
    191        fwrite(rawp.get(),sizeof(B),header.nx,f); 
    192        Progress::Instance().AdvanceProgress(&this_dummy);  
     618  Progress::Instance().Register(&this_dummy,header.ns*header.nr,100); 
     619  Point pnt; 
     620  for(int ss=0;ss<header.ns;++ss) { 
     621    pnt[maps]=ss; 
     622    // first half 
     623    int sr=0; 
     624    for(;sr<header.nr/2;++sr) { 
     625      pnt[mapr]=header.nr/2-sr; 
     626      for(int sc=0;sc<header.nc-1;++sc) { 
     627        pnt[mapc]=-sc; 
     628        Complex val = conj(norm->Convert(isc->Value(pnt))); 
     629        f << static_cast<B>(val.real()) << static_cast<B>(val.imag()); 
     630        mlog(5) << " " << pnt  << " " << val << std::endl ; 
     631      } 
     632      f << static_cast<B>(0.0) << static_cast<B>(0.0); 
     633      Progress::Instance().AdvanceProgress(&this_dummy); 
     634    } 
     635    // second half 
     636    for(;sr<header.nr;++sr) { 
     637      pnt[mapr]=sr-header.nr/2; 
     638      int sc=0; 
     639      for(;sc<header.nc-1;++sc) { 
     640        pnt[mapc]=sc; 
     641        Complex  val =norm->Convert(isc->Value(pnt)); 
     642        f << static_cast<B>(val.real()) << static_cast<B>(val.imag()); 
     643        mlog(5) << " " << pnt << " " << val << std::endl ; 
     644      } 
     645      pnt[mapc]=sc; 
     646      Complex  val = norm->Convert(conj(isc->Value(pnt))); 
     647      f << static_cast<B>(val.real()) << static_cast<B>(val.imag()); 
     648      mlog(5) << " " << pnt << " " << val << std::endl ; 
     649      Progress::Instance().AdvanceProgress(&this_dummy); 
    193650    } 
    194651  } 
     
    196653} 
    197654 
    198 template <typename B> 
    199 void dump_cmplx_to_file(FilePtr& f, mrc_header& header, const ConstImageHandle& image, const NormalizerPtr& norm) 
    200 
    201   boost::scoped_array<B> rawp(new B[header.nx]); 
    202   image_state::ComplexHalfFrequencyImageState *isc=dynamic_cast<image_state::ComplexHalfFrequencyImageState*>(image.ImageStatePtr().get()); 
    203   char this_dummy; //create dummy variable to give to Progress as this 
    204   Progress::Instance().Register(&this_dummy,header.nz*header.ny,100); 
    205   for(int sz=0;sz<header.nz;++sz) { 
    206     // first half 
    207     int sy=0; 
    208     for(;sy<header.ny/2;++sy) { 
    209       for(int sx=0;sx<header.nx-1;++sx) { 
    210         Point p=Point(-sx,header.ny/2-sy,sz); 
    211         rawp[sx] = conj(norm->Convert(isc->Value(p))); 
    212         //mlog(5) << " " << p << "* -> " << Point(sx,sy,sz) << " " << rawp[sx] << std::endl; 
    213       } 
    214       fwrite(rawp.get(),sizeof(B),header.nx,f); 
    215       Progress::Instance().AdvanceProgress(&this_dummy);  
    216     } 
    217     // second half 
    218     for(;sy<header.ny;++sy) { 
    219       int sx=0; 
    220       for(;sx<header.nx-1;++sx) { 
    221         Point p=Point(sx,sy-header.ny/2,sz); 
    222         rawp[sx] = norm->Convert(isc->Value(p)); 
    223         //mlog(5) << " " << p << " -> " << Point(sx,sy,sz) << " " << rawp[sx] << std::endl; 
    224       } 
    225       Point p=Point(sx,sy-header.ny/2,sz); 
    226       rawp[sx] = norm->Convert(conj(isc->Value(p))); 
    227       //mlog(5) << " " << p << "* -> " << Point(sx,sy,sz) << " " << rawp[sx] << std::endl; 
    228        
    229       fwrite(rawp.get(),sizeof(B),header.nx,f); 
    230       Progress::Instance().AdvanceProgress(&this_dummy);  
    231     } 
    232   } 
    233   Progress::Instance().DeRegister(&this_dummy); 
    234 
    235  
    236 } // anon ns 
    237  
    238 bool mrc_plugin::MatchContent(unsigned char* header) 
    239 
    240   return false; 
    241 
    242 bool mrc_plugin::MatchType(const string& type) 
    243 
    244   if(type=="mrc") { 
    245     return true; 
    246   } 
    247   return false; 
    248 
    249 bool mrc_plugin::MatchSuffix(const string& suffix) 
    250 
    251     if(suffix==".mrc") { 
    252       return true; 
    253     } 
    254     return false; 
    255 
    256  
    257  
    258 bool mrc_plugin::Import(const path& location, ImageHandle& image,  const ImageFormat& format) 
    259 
    260   const string& filename = location.string(); 
    261   FILE *ff; 
    262   std::ostringstream mesg; 
    263  
    264   if((ff=fopen(filename.c_str(),"r"))==NULL) { 
    265     throw(Error("error opening " + filename + " for reading")); 
    266   } 
    267  
    268   FilePtr f(ff); 
    269  
    270   bool swap_flag=false; 
    271   bool ancient_flag=false; 
    272   mrc_header header; 
    273   prep_load(header,f, swap_flag, ancient_flag); 
    274  
     655template<class HEADER,int CONVERSIONTYPE> 
     656void import_helper(ImageHandle& image, std::istream& in, const ImageFormat& format) 
     657
     658  BinaryIStream<CONVERSIONTYPE> f(in); 
     659  HEADER header; 
     660  f >> header; 
    275661  if(header.mode==5) header.mode=0; 
    276  
    277   if(Verbosity::GetLevel()>=4) { 
    278     dump_header(header); 
    279   } 
    280    
    281   if(header.nz>1) { 
    282     throw(Error("3D mrc format not implemented yet")); 
    283   } 
    284    
    285662  if(header.mode==3 || header.mode==4) { 
    286663    // always assume half-complex mode 
    287664    image.Reset(Size((header.nx-1)*2,header.ny,header.nz),COMPLEX,HALF_FREQUENCY); 
    288      
    289665    if(image_state::ComplexHalfFrequencyImageState *cs=dynamic_cast<image_state::ComplexHalfFrequencyImageState*>(image.ImageStatePtr().get())) { 
    290        
    291666      if (header.mode==3) { 
    292     // ushort has normalization 
    293     if(swap_flag) { 
    294       if(ancient_flag) { 
    295         complex_filler<ushort,true,true>(*cs,f,header,1.0); 
    296       } else { 
    297         complex_filler<ushort,true,false>(*cs,f,header,1.0); 
    298       } 
    299     } else { 
    300       if(ancient_flag) { 
    301         complex_filler<ushort,false,true>(*cs,f,header,1.0); 
    302       } else { 
    303         complex_filler<ushort,false,false>(*cs,f,header,1.0); 
    304       } 
    305     } 
     667        detail::complex_filler<ushort,CONVERSIONTYPE>(*cs,f,header); 
    306668      } else if(header.mode==4) { 
    307     // explicit float does not have normalization 
    308     if(swap_flag) { 
    309       if(ancient_flag) { 
    310         complex_filler<float,true,true>(*cs,f,header,1.0); 
    311       } else { 
    312         complex_filler<float,true,false>(*cs,f,header,1.0); 
    313       } 
    314     } else { 
    315       if(ancient_flag) { 
    316         complex_filler<float,false,true>(*cs,f,header,1.0); 
    317       } else { 
    318         complex_filler<float,false,false>(*cs,f,header,1.0); 
    319       } 
    320     } 
     669        detail::complex_filler<float,CONVERSIONTYPE>(*cs,f,header); 
    321670      } 
    322671    } else { 
     
    324673    } 
    325674  } else if (header.mode>=0 && header.mode<=2) { 
    326     image.Reset(Extent(Point(0,0,0),Size(header.nx,header.ny,header.nz)),REAL,SPATIAL); 
     675    Size msize; 
     676    msize[header.mapc-1]=header.nc; 
     677    msize[header.mapr-1]=header.nr; 
     678    msize[header.maps-1]=header.ns; 
     679    Point mstart; 
     680    mstart[header.mapc-1]=header.ncstart; 
     681    mstart[header.mapr-1]=header.nrstart; 
     682    mstart[header.maps-1]=header.nsstart; 
     683    image.Reset(Extent(mstart,msize),REAL,SPATIAL); 
     684    if(header.x>0.0 && header.y >0.0 && header.z > 0){ 
     685      image.SetSpatialSampling(geom::Vec3(static_cast<Real>(header.x)/static_cast<Real>(header.nx), 
     686                                          static_cast<Real>(header.y)/static_cast<Real>(header.ny), 
     687                                          static_cast<Real>(header.z)/static_cast<Real>(header.nz))); 
     688    }else{ 
     689      mlog(1) << "Suspicious dell dimensions found. Cannot set sampling." ; 
     690    } 
     691    mlog(1) << "resulting image extent: " << image.GetExtent() << std::endl ; 
     692    image.Reset(Extent(mstart,msize),REAL,SPATIAL); 
    327693    if(image_state::RealSpatialImageState *rs=dynamic_cast<image_state::RealSpatialImageState*>(image.ImageStatePtr().get())) { 
    328694      if(header.mode==0) { 
    329     if(swap_flag) { 
    330       if(ancient_flag) { 
    331         real_filler<uchar,true,true>(*rs,f,header,1.0); 
    332       } else { 
    333         real_filler<uchar,true,false>(*rs,f,header,1.0); 
    334       } 
    335     } else { 
    336       if(ancient_flag) { 
    337         real_filler<uchar,false,true>(*rs,f,header,1.0); 
    338       } else { 
    339         real_filler<uchar,false,false>(*rs,f,header,1.0); 
    340       } 
    341     } 
     695        detail::real_filler<uchar,CONVERSIONTYPE>(*rs,f,header); 
    342696      } else if(header.mode==1) { 
    343     if(swap_flag) { 
    344       if(ancient_flag) { 
    345         real_filler<unsigned short,true,true>(*rs,f,header,1.0); 
    346       } else { 
    347         real_filler<unsigned short,true,false>(*rs,f,header,1.0); 
    348       } 
    349     } else { 
    350       if(ancient_flag) { 
    351         real_filler<unsigned short,false,true>(*rs,f,header,1.0); 
    352       } else { 
    353         real_filler<unsigned short,false,false>(*rs,f,header,1.0); 
    354       } 
    355     } 
     697        detail::real_filler<unsigned short,CONVERSIONTYPE>(*rs,f,header); 
    356698      } else if(header.mode==2) { 
    357     if(swap_flag) { 
    358       if(ancient_flag) { 
    359         real_filler<float,true,true>(*rs,f,header,1.0); 
    360       } else { 
    361         real_filler<float,true,false>(*rs,f,header,1.0); 
    362       } 
    363     } else { 
    364       if(ancient_flag) { 
    365         real_filler<float,false,true>(*rs,f,header,1.0); 
    366       } else { 
    367         real_filler<float,false,false>(*rs,f,header,1.0); 
    368       } 
    369     } 
     699        detail::real_filler<float,CONVERSIONTYPE>(*rs,f,header); 
    370700      } 
    371701    } else { 
    372       throw Error("internal error in MRC io: expected RealSpatialImageState"); 
     702      throw Error("internal error in MRC/CCP4 io: expected RealSpatialImageState"); 
    373703    } 
    374704  } else { 
    375     mesg.str(""); 
    376     mesg << "mrc_load: unknown mode type " << header.mode; 
     705    ::iplt::string message_string; 
     706    std::ostringstream mesg(message_string); 
     707    mesg << "MRC/CCP4 import: unknown data type: " << header.mode; 
    377708    throw Error(mesg.str()); 
    378709  } 
    379  
    380   return true; 
    381 
    382  
    383  
    384 bool mrc_plugin::Export(const path& location, const ConstImageHandle& image,  const ImageFormat& format,const  NormalizerPtr& nptr) 
    385 
    386   const string& filename=location.string(); 
    387   FILE *ff; 
    388  
    389   if((ff=fopen(filename.c_str(),"w"))==NULL) { 
    390     throw(Error("error opening " + filename + " for writing")); 
    391   } 
    392  
    393   FilePtr f(ff); 
    394  
    395   mrc_header header; 
    396  
     710
     711 
     712template<class HEADER> 
     713void import_endianess_switcher(ImageHandle& image, 
     714                             std::istream& f, 
     715                             const ImageFormat& format) 
     716
     717   
     718  switch(HEADER::DetermineDataFormat(f)){ 
     719  case IPLT_BIG_ENDIAN: 
     720   import_helper<HEADER,IPLT_BIG_ENDIAN>(image,f,format); 
     721   break; 
     722  case IPLT_LITTLE_ENDIAN: 
     723   import_helper<HEADER,IPLT_LITTLE_ENDIAN>(image,f,format); 
     724   break; 
     725  case IPLT_VAX_DATA: 
     726   import_helper<HEADER,IPLT_VAX_DATA>(image,f,format); 
     727   break; 
     728  } 
     729
     730 
     731template<class HEADER,int CONVERSIONTYPE> 
     732void export_helper(const ConstImageHandle& image, 
     733                                    std::ostream& out, 
     734                                    const ImageFormat& format, 
     735                                    const  NormalizerPtr& nptr) 
     736
     737  BinaryOStream<CONVERSIONTYPE> f(out); 
     738  HEADER header(image); 
     739 
     740  f << header; 
    397741  if(image.GetType()==REAL) { 
    398     fill_header(header, image, 2, false, nptr); 
    399     fwrite(&header,sizeof(mrc_header),1,f); 
    400     dump_real_to_file<float>(f,header,image,nptr); 
     742    detail::real_dumper<float,CONVERSIONTYPE>(f,header,image,format,nptr); 
    401743  } else { 
    402744    if(image.GetDomain()==HALF_FREQUENCY){ 
    403       fill_header(header, image, 4, true, nptr); 
    404       fwrite(&header,sizeof(mrc_header),1,f); 
    405       dump_cmplx_to_file< std::complex<float> >(f,header,image,nptr); 
     745      detail::complex_dumper<float,CONVERSIONTYPE>(f,header,image,format,nptr); 
    406746    } else { 
    407       throw(Error("full complex export not supported for mrc")); 
    408     } 
    409   } 
    410  
    411   if(Verbosity::GetLevel()>=4) { 
    412     dump_header(header); 
    413   } 
    414  
    415   return true; 
    416 
    417  
    418 // private methods 
    419  
    420 void mrc_plugin::prep_load(mrc_header &header, FilePtr& f, bool &swap_flag, bool &ancient_flag)  
    421 
    422   fread(&header,sizeof(mrc_header),1,f); 
    423    
    424   if(header.mapc<1 || header.mapc>3) { 
    425     // try byte swapping 
    426     util::swap_int(&header.mapc,3); 
    427     swap_flag=true; 
    428     if(header.mapc<1 || header.mapc>3) { 
    429       fclose(f); 
    430       throw(Error("error reading mrc file (even tried byte-swapping")); 
    431     } 
    432   } 
    433  
    434   if(header.x>0.0) { 
    435     if(header.x<1.0) { 
    436       VaxToIEEE<float>(&header.x,6); 
    437       ancient_flag=true; 
    438       if(header.x<1.0) { 
    439     mlog(2) << "suspicious floating point value in mrc header" << std::endl; 
    440       } 
    441     } 
    442   } 
    443  
    444   if(swap_flag) { 
    445     mlog(4) << "auto-swapping bytes for mrc_load" << std::endl; 
    446     util::swap_int(&header.mode,1); 
    447     util::swap_int(&header.nx,3); 
    448     util::swap_int(&header.nxstart,3); 
    449     util::swap_int(&header.mx,3); 
    450     util::swap_float(&header.x,6); 
    451     util::swap_float(&header.amin,3); 
    452     util::swap_int(&header.ispg,2); 
    453     util::swap_int(header.extra,29); 
    454     util::swap_float(&header.xorigin,2); 
    455     util::swap_int(&header.nlabel,1); 
    456   } 
    457   if(ancient_flag) { 
    458     mlog(4) << "auto-converting from vax to ieee for mrc_load" << std::endl; 
    459     VaxToIEEE<int>(&header.mapc,3); 
    460     VaxToIEEE<int>(&header.mode,1); 
    461     VaxToIEEE<int>(&header.nx,3); 
    462     VaxToIEEE<int>(&header.nxstart,3); 
    463     VaxToIEEE<int>(&header.mx,3); 
    464     //VaxToIEEE<float>(&header.x,6); // done above 
    465     VaxToIEEE<float>(&header.amin,3); 
    466     VaxToIEEE<int>(&header.ispg,2); 
    467     VaxToIEEE<int>(header.extra,29); 
    468     VaxToIEEE<float>(&header.xorigin,2); 
    469     VaxToIEEE<int>(&header.nlabel,1); 
    470   } 
    471    
    472   if(header.nx<1) header.nx=1; 
    473   if(header.ny<1) header.ny=1; 
    474   if(header.nz<1) header.nz=1; 
    475    
    476   // skip symm info, seek to start of actual data 
    477   if(header.nsymbt>0) 
    478     fseek(f,header.nsymbt,SEEK_CUR); 
    479 
    480  
    481 void mrc_plugin::fill_header(mrc_header& header,const ConstImageHandle& image, int mode, bool hcomplex_flag,const  NormalizerPtr& nptr) 
    482 
    483   if(hcomplex_flag) { 
    484     header.nx = image.GetSize().GetWidth()/2+1; 
    485   } else { 
    486     header.nx = image.GetSize().GetWidth(); 
    487   } 
    488   header.ny = image.GetSize().GetHeight(); 
    489   header.nz = image.GetSize().GetDepth(); 
    490    
    491   header.mode = mode; 
    492    
    493   header.nxstart=0;  header.nystart=0;  header.nzstart=0; 
    494  
    495   header.mx = image.GetSize().GetWidth();  header.my=header.ny;  header.mz=header.nz; 
    496  
    497   header.x=0.0;  header.y=0.0;  header.z=0.0; 
    498  
    499   header.alpha=0.0;  header.beta=0.0;  header.gamma=0.0; 
    500  
    501   header.mapc=1; header.mapr=2; header.maps=3; 
    502  
    503   alg::Stat stat; 
    504   image.Apply(stat); 
    505   header.amin=nptr->Convert(stat.GetMinimum()); header.amax=nptr->Convert(stat.GetMaximum()); header.amean=nptr->Convert(stat.GetMean()); 
    506  
    507   header.ispg=0; 
    508  
    509   header.nsymbt=0; 
    510  
    511   for(int i=0;i<29;i++) header.extra[i]=0; 
    512    
    513   header.xorigin=image.GetSpatialOrigin()[0]; header.yorigin=image.GetSpatialOrigin()[1]; 
    514  
    515   header.nlabel=1; 
    516    
    517   for(int i=0;i<800;i++) header.label[i]=20; 
    518 
    519  
    520 void mrc_plugin::dump_header(const mrc_header& h) 
    521 
    522   mlog(4) << "mrc header" << std::endl; 
    523   mlog(4) << "n: " << h.nx << " " << h.ny << " " << h.nz << std::endl; 
    524   mlog(4) << "mode " << h.mode << std::endl; 
    525   mlog(4) << "m: " << h.mx << " " << h.my << " " << h.mz << std::endl; 
    526   mlog(4) << "cell: " << h.x << " " << h.y << " " << h.z; 
    527   mlog(4) << h.alpha << " " << h.beta << " " << h.gamma << std::endl; 
    528   mlog(4) << "order: " << h.mapc << h.mapr << h.maps << std::endl; 
    529   mlog(4) << "sg: " << h.ispg << " " << h.nsymbt << std::endl; 
    530   mlog(4) << "ori: " << h.xorigin << " " << h.yorigin << std::endl; 
    531   mlog(4) << "nlabel: " << h.nlabel << std::endl; 
    532   for(int i=0;i<29;++i) { 
    533     //mlog(4) << "extra " << i << " " << h.extra[i] << std::endl; 
    534   } 
    535 
     747      throw(Error("MRC/CCP4 export: full complex export not supported.")); 
     748    } 
     749  } 
     750
     751 
     752template<class HEADER> 
     753void export_endianess_switcher(const ConstImageHandle& image, 
     754                                std::ostream& f, 
     755                                const ImageFormat& format, 
     756                                const  NormalizerPtr& nptr) 
     757
     758 
     759switch(format.GetByteOrder()){ 
     760  case IPLT_BIG_ENDIAN: 
     761    export_helper<HEADER,IPLT_BIG_ENDIAN>(image,f,format,nptr); 
     762    break; 
     763  case IPLT_LITTLE_ENDIAN: 
     764    export_helper<HEADER,IPLT_LITTLE_ENDIAN>(image,f,format,nptr); 
     765    break; 
     766  case IPLT_VAX_DATA: 
     767    export_helper<HEADER,IPLT_VAX_DATA>(image,f,format,nptr); 
     768    break; 
     769  } 
     770
     771 
     772} //ns detail 
     773} //ns common 
     774 
     775namespace bf = boost::filesystem; 
     776 
     777bool mrc_plugin::Import(const path& location, ImageHandle& image,  const ImageFormat& format) 
     778
     779  boost::filesystem:: 
     780  ifstream infile(location, std::ios::binary); 
     781  if(!infile) 
     782  { 
     783    throw Error("could not open "+location.string()); 
     784  } 
     785  is_file_=true; 
     786  extension_=location.extension(); 
     787  Import(infile,image,format); 
     788  infile.close(); 
     789  return true; //placeholder 
     790
     791 
     792void mrc_plugin::Import(std::istream& loc, ImageHandle& image,  const ImageFormat& format) 
     793
     794   unsigned char header[256]; 
     795   loc.read(reinterpret_cast<char*>(&header),256); 
     796   loc.seekg(0, std::ios::beg); 
     797   if (MatchContent(header) == true) { 
     798     mlog(5) << "mrc io: importing new style format" <<std::endl; 
     799     detail::import_endianess_switcher<detail::ccp4_header>(image,loc,format); 
     800   } else { 
     801     mlog(5) << "mrc io: importing old style format" <<std::endl; 
     802     detail::import_endianess_switcher<detail::mrc_header>(image,loc,format); 
     803   } 
     804
     805 
     806bool mrc_plugin::Export(const path& loc,const ConstImageHandle& image,  const ImageFormat& format,const  NormalizerPtr& nptr)  
     807
     808  bf::ofstream outfile(loc, std::ios::binary); 
     809  if(!outfile) 
     810  { 
     811    throw Error("could not open "+loc.string()); 
     812  } 
     813  is_file_=true; 
     814  extension_=loc.extension(); 
     815  Export(outfile,image,format,nptr); 
     816  outfile.close(); 
     817  return true; //placeholder 
     818
     819 
     820 
     821void mrc_plugin::Export(std::ostream& loc,const ConstImageHandle& sh,   const ImageFormat& format,const  NormalizerPtr& nptr)  
     822
     823 mlog(5) << "mrc io: exporting new style format" <<std::endl; 
     824 detail::export_endianess_switcher<detail::ccp4_header>(sh,loc,format,nptr); 
     825
     826 
     827 
     828 
    536829 
    537830double mrc_plugin::GetMinimum(const ImageFormat& format) const 
  • branches/qt_gui/src/io/lib/io_mrc.hh

    r1647 r1750  
    2222namespace iplt { namespace io { 
    2323 
    24 namespace { 
    25  
    26 struct mrc_header { 
    27   int nx,ny,nz; // nr of columns, rows and sections 
    28   int mode; // data format 
    29   int nxstart,nystart,nzstart;  // column, row and section offset 
    30   int mx,my,mz;  // logical size, used for hcomplex format 
    31   float x,y,z,alpha,beta,gamma; // cell constans 
    32   int mapc,mapr,maps; // axis to column/row/section 
    33   float amin,amax,amean; // min, max and mean data value 
    34   int ispg; // spacegroup (should be 0 for images) 
    35   int nsymbt; // number of bytes used for symmetry op 
    36   int extra[29]; // extra stuff 
    37   float xorigin,yorigin; 
    38   int nlabel; 
    39   char label[800]; 
    40 }; 
    41  
    42 } // anon ns 
    4324 
    4425class mrc_plugin: public ImageIOPlugin { 
     
    4930  virtual bool Import(const path& location, ImageHandle& i, const ImageFormat& format); 
    5031  virtual bool Export(const path& location, const ConstImageHandle& i, const ImageFormat& format,const  NormalizerPtr& nptr); 
     32  virtual void Import(std::istream& loc, ImageHandle& i, const ImageFormat& format); 
     33  virtual void Export(std::ostream& loc, const ConstImageHandle& i, const ImageFormat& format,const  NormalizerPtr& nptr); 
    5134  virtual double GetMinimum(const ImageFormat& format) const; 
    5235  virtual double GetMaximum(const ImageFormat& format) const; 
    5336private: 
    54   void prep_load(mrc_header& header, FilePtr& f, bool& swap_flag, bool& ancient_flag); 
    55   void fill_header(mrc_header& header,const ConstImageHandle& image, int mode, bool hcomplex_flag,const  NormalizerPtr& nptr)
    56   void dump_header(const mrc_header& h)
     37 
     38  mutable bool is_file_
     39  mutable string extension_
    5740}; 
    5841