diskio_meat.hpp
Go to the documentation of this file.
00001 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
00002 // Copyright (C) 2008-2011 Conrad Sanderson
00003 // Copyright (C) 2009-2010 Ian Cullinan
00004 // 
00005 // This file is part of the Armadillo C++ library.
00006 // It is provided without any warranty of fitness
00007 // for any purpose. You can redistribute this file
00008 // and/or modify it under the terms of the GNU
00009 // Lesser General Public License (LGPL) as published
00010 // by the Free Software Foundation, either version 3
00011 // of the License or (at your option) any later version.
00012 // (see http://www.opensource.org/licenses for more info)
00013 
00014 
00017 
00018 
00024 template<typename eT>
00025 inline
00026 std::string
00027 diskio::gen_txt_header(const Mat<eT>& x)
00028   {
00029   arma_type_check(( is_supported_elem_type<eT>::value == false ));
00030 
00031   arma_ignore(x);
00032   
00033   if(is_u8<eT>::value == true)
00034     {
00035     return std::string("ARMA_MAT_TXT_IU001");
00036     }
00037   else
00038   if(is_s8<eT>::value == true)
00039     {
00040     return std::string("ARMA_MAT_TXT_IS001");
00041     }
00042   else
00043   if(is_u16<eT>::value == true)
00044     {
00045     return std::string("ARMA_MAT_TXT_IU002");
00046     }
00047   else
00048   if(is_s16<eT>::value == true)
00049     {
00050     return std::string("ARMA_MAT_TXT_IS002");
00051     }
00052   else
00053   if(is_u32<eT>::value == true)
00054     {
00055     return std::string("ARMA_MAT_TXT_IU004");
00056     }
00057   else
00058   if(is_s32<eT>::value == true)
00059     {
00060     return std::string("ARMA_MAT_TXT_IS004");
00061     }
00062 #if defined(ARMA_64BIT_WORD)
00063   else
00064   if(is_u64<eT>::value == true)
00065     {
00066     return std::string("ARMA_MAT_TXT_IU008");
00067     }
00068   else
00069   if(is_s64<eT>::value == true)
00070     {
00071     return std::string("ARMA_MAT_TXT_IS008");
00072     }
00073 #endif
00074   else
00075   if(is_float<eT>::value == true)
00076     {
00077     return std::string("ARMA_MAT_TXT_FN004");
00078     }
00079   else
00080   if(is_double<eT>::value == true)
00081     {
00082     return std::string("ARMA_MAT_TXT_FN008");
00083     }
00084   else
00085   if(is_complex_float<eT>::value == true)
00086     {
00087     return std::string("ARMA_MAT_TXT_FC008");
00088     }
00089   else
00090   if(is_complex_double<eT>::value == true)
00091     {
00092     return std::string("ARMA_MAT_TXT_FC016");
00093     }
00094   else
00095     {
00096     return std::string();
00097     }
00098   
00099   }
00100 
00101 
00102 
00108 template<typename eT>
00109 inline
00110 std::string
00111 diskio::gen_bin_header(const Mat<eT>& x)
00112   {
00113   arma_type_check(( is_supported_elem_type<eT>::value == false ));
00114   
00115   arma_ignore(x);
00116   
00117   if(is_u8<eT>::value == true)
00118     {
00119     return std::string("ARMA_MAT_BIN_IU001");
00120     }
00121   else
00122   if(is_s8<eT>::value == true)
00123     {
00124     return std::string("ARMA_MAT_BIN_IS001");
00125     }
00126   else
00127   if(is_u16<eT>::value == true)
00128     {
00129     return std::string("ARMA_MAT_BIN_IU002");
00130     }
00131   else
00132   if(is_s16<eT>::value == true)
00133     {
00134     return std::string("ARMA_MAT_BIN_IS002");
00135     }
00136   else
00137   if(is_u32<eT>::value == true)
00138     {
00139     return std::string("ARMA_MAT_BIN_IU004");
00140     }
00141   else
00142   if(is_s32<eT>::value == true)
00143     {
00144     return std::string("ARMA_MAT_BIN_IS004");
00145     }
00146 #if defined(ARMA_64BIT_WORD)
00147   else
00148   if(is_u64<eT>::value == true)
00149     {
00150     return std::string("ARMA_MAT_BIN_IU008");
00151     }
00152   else
00153   if(is_s64<eT>::value == true)
00154     {
00155     return std::string("ARMA_MAT_BIN_IS008");
00156     }
00157 #endif
00158   else
00159   if(is_float<eT>::value == true)
00160     {
00161     return std::string("ARMA_MAT_BIN_FN004");
00162     }
00163   else
00164   if(is_double<eT>::value == true)
00165     {
00166     return std::string("ARMA_MAT_BIN_FN008");
00167     }
00168   else
00169   if(is_complex_float<eT>::value == true)
00170     {
00171     return std::string("ARMA_MAT_BIN_FC008");
00172     }
00173   else
00174   if(is_complex_double<eT>::value == true)
00175     {
00176     return std::string("ARMA_MAT_BIN_FC016");
00177     }
00178   else
00179     {
00180     return std::string();
00181     }
00182   
00183   }
00184 
00185 
00186 
00192 template<typename eT>
00193 inline
00194 std::string
00195 diskio::gen_txt_header(const Cube<eT>& x)
00196   {
00197   arma_type_check(( is_supported_elem_type<eT>::value == false ));
00198   
00199   arma_ignore(x);
00200 
00201   if(is_u8<eT>::value == true)
00202     {
00203     return std::string("ARMA_CUB_TXT_IU001");
00204     }
00205   else
00206   if(is_s8<eT>::value == true)
00207     {
00208     return std::string("ARMA_CUB_TXT_IS001");
00209     }
00210   else
00211   if(is_u16<eT>::value == true)
00212     {
00213     return std::string("ARMA_CUB_TXT_IU002");
00214     }
00215   else
00216   if(is_s16<eT>::value == true)
00217     {
00218     return std::string("ARMA_CUB_TXT_IS002");
00219     }
00220   else
00221   if(is_u32<eT>::value == true)
00222     {
00223     return std::string("ARMA_CUB_TXT_IU004");
00224     }
00225   else
00226   if(is_s32<eT>::value == true)
00227     {
00228     return std::string("ARMA_CUB_TXT_IS004");
00229     }
00230 #if defined(ARMA_64BIT_WORD)
00231   else
00232   if(is_u64<eT>::value == true)
00233     {
00234     return std::string("ARMA_CUB_TXT_IU008");
00235     }
00236   else
00237   if(is_s64<eT>::value == true)
00238     {
00239     return std::string("ARMA_CUB_TXT_IS008");
00240     }
00241 #endif
00242   else
00243   if(is_float<eT>::value == true)
00244     {
00245     return std::string("ARMA_CUB_TXT_FN004");
00246     }
00247   else
00248   if(is_double<eT>::value == true)
00249     {
00250     return std::string("ARMA_CUB_TXT_FN008");
00251     }
00252   else
00253   if(is_complex_float<eT>::value == true)
00254     {
00255     return std::string("ARMA_CUB_TXT_FC008");
00256     }
00257   else
00258   if(is_complex_double<eT>::value == true)
00259     {
00260     return std::string("ARMA_CUB_TXT_FC016");
00261     }
00262   else
00263     {
00264     return std::string();
00265     }
00266   
00267   }
00268 
00269 
00270 
00276 template<typename eT>
00277 inline
00278 std::string
00279 diskio::gen_bin_header(const Cube<eT>& x)
00280   {
00281   arma_type_check(( is_supported_elem_type<eT>::value == false ));
00282   
00283   arma_ignore(x);
00284   
00285   if(is_u8<eT>::value == true)
00286     {
00287     return std::string("ARMA_CUB_BIN_IU001");
00288     }
00289   else
00290   if(is_s8<eT>::value == true)
00291     {
00292     return std::string("ARMA_CUB_BIN_IS001");
00293     }
00294   else
00295   if(is_u16<eT>::value == true)
00296     {
00297     return std::string("ARMA_CUB_BIN_IU002");
00298     }
00299   else
00300   if(is_s16<eT>::value == true)
00301     {
00302     return std::string("ARMA_CUB_BIN_IS002");
00303     }
00304   else
00305   if(is_u32<eT>::value == true)
00306     {
00307     return std::string("ARMA_CUB_BIN_IU004");
00308     }
00309   else
00310   if(is_s32<eT>::value == true)
00311     {
00312     return std::string("ARMA_CUB_BIN_IS004");
00313     }
00314 #if defined(ARMA_64BIT_WORD)
00315   else
00316   if(is_u64<eT>::value == true)
00317     {
00318     return std::string("ARMA_CUB_BIN_IU008");
00319     }
00320   else
00321   if(is_s64<eT>::value == true)
00322     {
00323     return std::string("ARMA_CUB_BIN_IS008");
00324     }
00325 #endif
00326   else
00327   if(is_float<eT>::value == true)
00328     {
00329     return std::string("ARMA_CUB_BIN_FN004");
00330     }
00331   else
00332   if(is_double<eT>::value == true)
00333     {
00334     return std::string("ARMA_CUB_BIN_FN008");
00335     }
00336   else
00337   if(is_complex_float<eT>::value == true)
00338     {
00339     return std::string("ARMA_CUB_BIN_FC008");
00340     }
00341   else
00342   if(is_complex_double<eT>::value == true)
00343     {
00344     return std::string("ARMA_CUB_BIN_FC016");
00345     }
00346   else
00347     {
00348     return std::string();
00349     }
00350   
00351   }
00352 
00353 
00354 
00355 inline
00356 file_type
00357 diskio::guess_file_type(std::istream& f)
00358   {
00359   arma_extra_debug_sigprint();
00360   
00361   f.clear();
00362   const std::fstream::pos_type pos1 = f.tellg();
00363   
00364   f.clear();
00365   f.seekg(0, ios::end);
00366   
00367   f.clear();
00368   const std::fstream::pos_type pos2 = f.tellg();
00369   
00370   const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
00371   
00372   f.clear();
00373   f.seekg(pos1);
00374   
00375   podarray<unsigned char> data(N);
00376   
00377   unsigned char* ptr = data.memptr();
00378   
00379   f.clear();
00380   f.read( reinterpret_cast<char*>(ptr), std::streamsize(N) );
00381   
00382   const bool load_okay = f.good();
00383   
00384   f.clear();
00385   f.seekg(pos1);
00386   
00387   bool has_binary = false;
00388   bool has_comma  = false;
00389   
00390   if(load_okay == true)
00391     {
00392     uword i = 0;
00393     uword j = (N >= 2) ? 1 : 0;
00394     
00395     for(; j<N; i+=2, j+=2)
00396       {
00397       const unsigned char val_i = ptr[i];
00398       const unsigned char val_j = ptr[j];
00399       
00400       // the range checking can be made more elaborate
00401       if( ((val_i <= 8) || (val_i >= 123)) || ((val_j <= 8) || (val_j >= 123)) )
00402         {
00403         has_binary = true;
00404         break;
00405         }
00406       
00407       if( (val_i == ',') || (val_j == ',') )
00408         {
00409         has_comma = true;
00410         break;
00411         }
00412       }
00413     }
00414   else
00415     {
00416     return file_type_unknown;
00417     }
00418   
00419   if(has_binary)
00420     {
00421     return raw_binary;
00422     }
00423   
00424   if(has_comma)
00425     {
00426     return csv_ascii;
00427     }
00428   
00429   return raw_ascii;
00430   }
00431 
00432 
00433 
00434 inline
00435 char
00436 diskio::conv_to_hex_char(const u8 x)
00437   {
00438   char out;
00439 
00440   switch(x)
00441     {
00442     case  0: out = '0'; break;
00443     case  1: out = '1'; break;
00444     case  2: out = '2'; break;
00445     case  3: out = '3'; break;
00446     case  4: out = '4'; break;
00447     case  5: out = '5'; break;
00448     case  6: out = '6'; break;
00449     case  7: out = '7'; break;
00450     case  8: out = '8'; break;
00451     case  9: out = '9'; break;
00452     case 10: out = 'a'; break;
00453     case 11: out = 'b'; break;
00454     case 12: out = 'c'; break;
00455     case 13: out = 'd'; break;
00456     case 14: out = 'e'; break;
00457     case 15: out = 'f'; break;
00458     default: out = '-'; break;
00459     }
00460 
00461   return out;  
00462   }
00463 
00464 
00465 
00466 inline
00467 void
00468 diskio::conv_to_hex(char* out, const u8 x)
00469   {
00470   const u8 a = x / 16;
00471   const u8 b = x - 16*a;
00472 
00473   out[0] = conv_to_hex_char(a);
00474   out[1] = conv_to_hex_char(b);
00475   }
00476 
00477 
00478 
00486 inline
00487 std::string
00488 diskio::gen_tmp_name(const std::string& x)
00489   {
00490   const std::string* ptr_x     = &x;
00491   const u8*          ptr_ptr_x = reinterpret_cast<const u8*>(&ptr_x);
00492   
00493   const char* extra      = ".tmp_";
00494   const uword extra_size = 5;
00495   
00496   const uword tmp_size   = 2*sizeof(u8*) + 2*2;
00497         char  tmp[tmp_size];
00498   
00499   uword char_count = 0;
00500   
00501   for(uword i=0; i<sizeof(u8*); ++i)
00502     {
00503     conv_to_hex(&tmp[char_count], ptr_ptr_x[i]);
00504     char_count += 2;
00505     }
00506   
00507   const uword x_size = static_cast<uword>(x.size());
00508   u8 sum = 0;
00509   
00510   for(uword i=0; i<x_size; ++i)
00511     {
00512     sum += u8(x[i]);
00513     }
00514   
00515   conv_to_hex(&tmp[char_count], sum);
00516   char_count += 2;
00517   
00518   conv_to_hex(&tmp[char_count], u8(x_size));
00519   
00520   
00521   std::string out;
00522   out.resize(x_size + extra_size + tmp_size);
00523   
00524   
00525   for(uword i=0; i<x_size; ++i)
00526     {
00527     out[i] = x[i];
00528     }
00529   
00530   for(uword i=0; i<extra_size; ++i)
00531     {
00532     out[x_size + i] = extra[i];
00533     }
00534   
00535   for(uword i=0; i<tmp_size; ++i)
00536     {
00537     out[x_size + extra_size + i] = tmp[i];
00538     }
00539   
00540   return out;
00541   }
00542 
00543 
00544 
00550 inline
00551 bool
00552 diskio::safe_rename(const std::string& old_name, const std::string& new_name)
00553   {
00554   std::fstream f(new_name.c_str(), std::fstream::out | std::fstream::app);
00555   f.put(' ');
00556   
00557   bool save_okay = f.good();
00558   f.close();
00559   
00560   if(save_okay == true)
00561     {
00562     std::remove(new_name.c_str());
00563     
00564     const int mv_result = std::rename(old_name.c_str(), new_name.c_str());
00565     
00566     save_okay = (mv_result == 0);
00567     }
00568   
00569   return save_okay;
00570   }
00571 
00572 
00573 
00576 template<typename eT>
00577 inline
00578 bool
00579 diskio::save_raw_ascii(const Mat<eT>& x, const std::string& final_name)
00580   {
00581   arma_extra_debug_sigprint();
00582   
00583   const std::string tmp_name = diskio::gen_tmp_name(final_name);
00584   
00585   std::fstream f(tmp_name.c_str(), std::fstream::out);
00586   
00587   bool save_okay = f.is_open();
00588   
00589   if(save_okay == true)
00590     {
00591     save_okay = diskio::save_raw_ascii(x, f);
00592     
00593     f.flush();
00594     f.close();
00595     
00596     if(save_okay == true)
00597       {
00598       save_okay = diskio::safe_rename(tmp_name, final_name);
00599       }
00600     }
00601   
00602   return save_okay;
00603   }
00604 
00605 
00606 
00609 template<typename eT>
00610 inline
00611 bool
00612 diskio::save_raw_ascii(const Mat<eT>& x, std::ostream& f)
00613   {
00614   arma_extra_debug_sigprint();
00615   
00616   uword cell_width;
00617   
00618   // TODO: need sane values for complex numbers
00619   
00620   if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
00621     {
00622     f.setf(ios::scientific);
00623     f.precision(10);
00624     cell_width = 18;
00625     }
00626   
00627   for(uword row=0; row < x.n_rows; ++row)
00628     {
00629     for(uword col=0; col < x.n_cols; ++col)
00630       {
00631       f.put(' ');
00632       
00633       if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
00634         {
00635         f.width(cell_width);
00636         }
00637       
00638       f << x.at(row,col);
00639       }
00640       
00641     f.put('\n');
00642     }
00643   
00644   return f.good();
00645   }
00646 
00647 
00648 
00650 template<typename eT>
00651 inline
00652 bool
00653 diskio::save_raw_binary(const Mat<eT>& x, const std::string& final_name)
00654   {
00655   arma_extra_debug_sigprint();
00656   
00657   const std::string tmp_name = diskio::gen_tmp_name(final_name);
00658   
00659   std::ofstream f(tmp_name.c_str(), std::fstream::binary);
00660   
00661   bool save_okay = f.is_open();
00662   
00663   if(save_okay == true)
00664     {
00665     save_okay = diskio::save_raw_binary(x, f);
00666     
00667     f.flush();
00668     f.close();
00669     
00670     if(save_okay == true)
00671       {
00672       save_okay = diskio::safe_rename(tmp_name, final_name);
00673       }
00674     }
00675   
00676   return save_okay;
00677   }
00678 
00679 
00680 
00681 template<typename eT>
00682 inline
00683 bool
00684 diskio::save_raw_binary(const Mat<eT>& x, std::ostream& f)
00685   {
00686   arma_extra_debug_sigprint();
00687   
00688   f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
00689   
00690   return f.good();
00691   }
00692 
00693 
00694 
00697 template<typename eT>
00698 inline
00699 bool
00700 diskio::save_arma_ascii(const Mat<eT>& x, const std::string& final_name)
00701   {
00702   arma_extra_debug_sigprint();
00703   
00704   const std::string tmp_name = diskio::gen_tmp_name(final_name);
00705   
00706   std::ofstream f(tmp_name.c_str());
00707   
00708   bool save_okay = f.is_open();
00709 
00710   if(save_okay == true)  
00711     {
00712     save_okay = diskio::save_arma_ascii(x, f);
00713     
00714     f.flush();
00715     f.close();
00716     
00717     if(save_okay == true)
00718       {
00719       save_okay = diskio::safe_rename(tmp_name, final_name);
00720       }
00721     }
00722   
00723   return save_okay;
00724   }
00725 
00726 
00727 
00730 template<typename eT>
00731 inline
00732 bool
00733 diskio::save_arma_ascii(const Mat<eT>& x, std::ostream& f)
00734   {
00735   arma_extra_debug_sigprint();
00736   
00737   const ios::fmtflags orig_flags = f.flags();
00738   
00739   f << diskio::gen_txt_header(x) << '\n';
00740   f << x.n_rows << ' ' << x.n_cols << '\n';
00741   
00742   uword cell_width;
00743   
00744   // TODO: need sane values for complex numbers
00745   
00746   if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
00747     {
00748     f.setf(ios::scientific);
00749     f.precision(10);
00750     cell_width = 18;
00751     }
00752     
00753   for(uword row=0; row < x.n_rows; ++row)
00754     {
00755     for(uword col=0; col < x.n_cols; ++col)
00756       {
00757       f.put(' ');
00758       
00759       if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )        
00760         {
00761         f.width(cell_width);
00762         }
00763       
00764       f << x.at(row,col);
00765       }
00766     
00767     f.put('\n');
00768     }
00769   
00770   const bool save_okay = f.good();
00771   
00772   f.flags(orig_flags);
00773   
00774   return save_okay;
00775   }
00776 
00777 
00778 
00780 template<typename eT>
00781 inline
00782 bool
00783 diskio::save_csv_ascii(const Mat<eT>& x, const std::string& final_name)
00784   {
00785   arma_extra_debug_sigprint();
00786   
00787   const std::string tmp_name = diskio::gen_tmp_name(final_name);
00788   
00789   std::ofstream f(tmp_name.c_str());
00790   
00791   bool save_okay = f.is_open();
00792   
00793   if(save_okay == true)  
00794     {
00795     save_okay = diskio::save_csv_ascii(x, f);
00796     
00797     f.flush();
00798     f.close();
00799     
00800     if(save_okay == true)
00801       {
00802       save_okay = diskio::safe_rename(tmp_name, final_name);
00803       }
00804     }
00805   
00806   return save_okay;
00807   }
00808 
00809 
00810 
00812 template<typename eT>
00813 inline
00814 bool
00815 diskio::save_csv_ascii(const Mat<eT>& x, std::ostream& f)
00816   {
00817   arma_extra_debug_sigprint();
00818   
00819   const ios::fmtflags orig_flags = f.flags();
00820   
00821   // TODO: need sane values for complex numbers
00822   
00823   if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
00824     {
00825     f.setf(ios::scientific);
00826     f.precision(10);
00827     }
00828   
00829   uword x_n_rows = x.n_rows;
00830   uword x_n_cols = x.n_cols;
00831   
00832   for(uword row=0; row < x_n_rows; ++row)
00833     {
00834     for(uword col=0; col < x_n_cols; ++col)
00835       {
00836       f << x.at(row,col);
00837       
00838       if( col < (x_n_cols-1) )
00839         {
00840         f.put(',');
00841         }
00842       }
00843     
00844     f.put('\n');
00845     }
00846   
00847   const bool save_okay = f.good();
00848   
00849   f.flags(orig_flags);
00850   
00851   return save_okay;
00852   }
00853 
00854 
00855 
00858 template<typename eT>
00859 inline
00860 bool
00861 diskio::save_arma_binary(const Mat<eT>& x, const std::string& final_name)
00862   {
00863   arma_extra_debug_sigprint();
00864   
00865   const std::string tmp_name = diskio::gen_tmp_name(final_name);
00866   
00867   std::ofstream f(tmp_name.c_str(), std::fstream::binary);
00868   
00869   bool save_okay = f.is_open();
00870   
00871   if(save_okay == true)
00872     {
00873     save_okay = diskio::save_arma_binary(x, f);
00874     
00875     f.flush();
00876     f.close();
00877     
00878     if(save_okay == true)
00879       {
00880       save_okay = diskio::safe_rename(tmp_name, final_name);
00881       }
00882     }
00883   
00884   return save_okay;
00885   }
00886 
00887 
00888 
00891 template<typename eT>
00892 inline
00893 bool
00894 diskio::save_arma_binary(const Mat<eT>& x, std::ostream& f)
00895   {
00896   arma_extra_debug_sigprint();
00897 
00898   f << diskio::gen_bin_header(x) << '\n';
00899   f << x.n_rows << ' ' << x.n_cols << '\n';
00900   
00901   f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
00902   
00903   return f.good();
00904   }
00905 
00906 
00907 
00909 template<typename eT>
00910 inline
00911 bool
00912 diskio::save_pgm_binary(const Mat<eT>& x, const std::string& final_name)
00913   {
00914   arma_extra_debug_sigprint();
00915   
00916   const std::string tmp_name = diskio::gen_tmp_name(final_name);
00917   
00918   std::fstream f(tmp_name.c_str(), std::fstream::out | std::fstream::binary);
00919   
00920   bool save_okay = f.is_open();
00921   
00922   if(save_okay == true)
00923     {
00924     save_okay = diskio::save_pgm_binary(x, f);
00925     
00926     f.flush();
00927     f.close();
00928     
00929     if(save_okay == true)
00930       {
00931       save_okay = diskio::safe_rename(tmp_name, final_name);
00932       }
00933     }
00934   
00935   return save_okay;
00936   }
00937 
00938 
00939 
00940 //
00941 // TODO:
00942 // add functionality to save the image in a normalised format,
00943 // i.e. scaled so that every value falls in the [0,255] range.
00944 
00946 template<typename eT>
00947 inline
00948 bool
00949 diskio::save_pgm_binary(const Mat<eT>& x, std::ostream& f)
00950   {
00951   arma_extra_debug_sigprint();
00952   
00953   f << "P5" << '\n';
00954   f << x.n_cols << ' ' << x.n_rows << '\n';
00955   f << 255 << '\n';
00956   
00957   const uword n_elem = x.n_rows * x.n_cols;
00958   podarray<u8> tmp(n_elem);
00959   
00960   uword i = 0;
00961   
00962   for(uword row=0; row < x.n_rows; ++row)
00963     {
00964     for(uword col=0; col < x.n_cols; ++col)
00965       {
00966       tmp[i] = u8( x.at(row,col) );  // TODO: add round() ?
00967       ++i;
00968       }
00969     }
00970   
00971   f.write(reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
00972   
00973   return f.good();
00974   }
00975 
00976 
00977 
00979 template<typename T>
00980 inline
00981 bool
00982 diskio::save_pgm_binary(const Mat< std::complex<T> >& x, const std::string& final_name)
00983   {
00984   arma_extra_debug_sigprint();
00985   
00986   const uchar_mat tmp = conv_to<uchar_mat>::from(x);
00987   
00988   return diskio::save_pgm_binary(tmp, final_name);
00989   }
00990 
00991 
00992 
00994 template<typename T>
00995 inline
00996 bool
00997 diskio::save_pgm_binary(const Mat< std::complex<T> >& x, std::ostream& f)
00998   {
00999   arma_extra_debug_sigprint();
01000   
01001   const uchar_mat tmp = conv_to<uchar_mat>::from(x);
01002   
01003   return diskio::save_pgm_binary(tmp, f);
01004   }
01005 
01006 
01007 
01011 template<typename eT>
01012 inline
01013 bool
01014 diskio::load_raw_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
01015   {
01016   arma_extra_debug_sigprint();
01017 
01018   std::fstream f;
01019   f.open(name.c_str(), std::fstream::in);
01020   
01021   bool load_okay = f.is_open();
01022   
01023   if(load_okay == true)
01024     {
01025     load_okay = diskio::load_raw_ascii(x, f, err_msg);
01026     f.close();
01027     }
01028   
01029   return load_okay;
01030   }
01031 
01032 
01033 
01037 template<typename eT>
01038 inline
01039 bool
01040 diskio::load_raw_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
01041   {
01042   arma_extra_debug_sigprint();
01043   
01044   bool load_okay = f.good();
01045   
01046   f.clear();
01047   const std::fstream::pos_type pos1 = f.tellg();
01048   
01049   //
01050   // work out the size
01051   
01052   uword f_n_rows = 0;
01053   uword f_n_cols = 0;
01054   
01055   bool f_n_cols_found = false;
01056   
01057   std::string line_string;
01058   std::string token;
01059   
01060   while( (f.good() == true) && (load_okay == true) )
01061     {
01062     std::getline(f, line_string);
01063     
01064     if(line_string.size() == 0)
01065       {
01066       break;
01067       }
01068     
01069     std::stringstream line_stream(line_string);
01070     
01071     uword line_n_cols = 0;
01072     
01073     while (line_stream >> token)
01074       {
01075       ++line_n_cols;
01076       }
01077     
01078     if(f_n_cols_found == false)
01079       {
01080       f_n_cols = line_n_cols;
01081       f_n_cols_found = true;
01082       }
01083     else
01084       {
01085       if(line_n_cols != f_n_cols)
01086         {
01087         err_msg = "inconsistent number of columns in ";
01088         load_okay = false;
01089         }
01090       }
01091     
01092     ++f_n_rows;
01093     }
01094     
01095   if(load_okay == true)
01096     {
01097     f.clear();
01098     f.seekg(pos1);
01099     
01100     x.set_size(f_n_rows, f_n_cols);
01101     
01102     eT val;
01103     
01104     for(uword row=0; (row < x.n_rows) && (load_okay == true); ++row)
01105       {
01106       for(uword col=0; (col < x.n_cols) && (load_okay == true); ++col)
01107         {
01108         f >> val;
01109         
01110         if(f.fail() == false)
01111           {
01112           x.at(row,col) = val;
01113           }
01114         else
01115           {
01116           load_okay = false;
01117           err_msg = "couldn't interpret data in ";
01118           //break;
01119           }
01120         }
01121       }
01122     }
01123   
01124   
01125   // an empty file indicates an empty matrix
01126   if( (f_n_cols_found == false) && (load_okay == true) )
01127     {
01128     x.reset();
01129     }
01130   
01131   
01132   return load_okay;
01133   }
01134 
01135 
01136 
01139 template<typename eT>
01140 inline
01141 bool
01142 diskio::load_raw_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
01143   {
01144   arma_extra_debug_sigprint();
01145   
01146   std::ifstream f;
01147   f.open(name.c_str(), std::fstream::binary);
01148   
01149   bool load_okay = f.is_open();
01150   
01151   if(load_okay == true)
01152     {
01153     load_okay = diskio::load_raw_binary(x, f, err_msg);
01154     f.close();
01155     }
01156   
01157   return load_okay;
01158   }
01159 
01160 
01161 
01162 template<typename eT>
01163 inline
01164 bool
01165 diskio::load_raw_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
01166   {
01167   arma_extra_debug_sigprint();
01168   arma_ignore(err_msg);
01169   
01170   f.clear();
01171   const std::streampos pos1 = f.tellg();
01172   
01173   f.clear();
01174   f.seekg(0, ios::end);
01175 
01176   f.clear();
01177   const std::streampos pos2 = f.tellg();
01178   
01179   const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
01180   
01181   f.clear();
01182   //f.seekg(0, ios::beg);
01183   f.seekg(pos1);
01184   
01185   x.set_size(N / sizeof(eT), 1);
01186   
01187   f.clear();
01188   f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
01189   
01190   return f.good();
01191   }
01192 
01193 
01194 
01197 template<typename eT>
01198 inline
01199 bool
01200 diskio::load_arma_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
01201   {
01202   arma_extra_debug_sigprint();
01203   
01204   std::ifstream f(name.c_str());
01205   
01206   bool load_okay = f.is_open();
01207   
01208   if(load_okay == true)
01209     {
01210     load_okay = diskio::load_arma_ascii(x, f, err_msg);
01211     f.close();
01212     }
01213   
01214   return load_okay;
01215   }
01216 
01217 
01218 
01221 template<typename eT>
01222 inline
01223 bool
01224 diskio::load_arma_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
01225   {
01226   arma_extra_debug_sigprint();
01227   
01228   bool load_okay = true;
01229   
01230   std::string f_header;
01231   uword f_n_rows;
01232   uword f_n_cols;
01233   
01234   f >> f_header;
01235   f >> f_n_rows;
01236   f >> f_n_cols;
01237   
01238   if(f_header == diskio::gen_txt_header(x))
01239     {
01240     x.set_size(f_n_rows, f_n_cols);
01241     
01242     for(uword row=0; row < x.n_rows; ++row)
01243       {
01244       for(uword col=0; col < x.n_cols; ++col)
01245         {
01246         f >> x.at(row,col);
01247         }
01248       }
01249     
01250     load_okay = f.good();
01251     }
01252   else
01253     {
01254     load_okay = false;
01255     err_msg = "incorrect header in ";
01256     }
01257   
01258   return load_okay;
01259   }
01260 
01261 
01262 
01264 template<typename eT>
01265 inline
01266 bool
01267 diskio::load_csv_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
01268   {
01269   arma_extra_debug_sigprint();
01270   
01271   std::fstream f;
01272   f.open(name.c_str(), std::fstream::in);
01273   
01274   bool load_okay = f.is_open();
01275   
01276   if(load_okay == true)
01277     {
01278     load_okay = diskio::load_csv_ascii(x, f, err_msg);
01279     f.close();
01280     }
01281   
01282   return load_okay;
01283   }
01284 
01285 
01286 
01288 template<typename eT>
01289 inline
01290 bool
01291 diskio::load_csv_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
01292   {
01293   arma_extra_debug_sigprint();
01294   
01295   bool load_okay = f.good();
01296   
01297   f.clear();
01298   const std::fstream::pos_type pos1 = f.tellg();
01299   
01300   //
01301   // work out the size
01302   
01303   uword f_n_rows = 0;
01304   uword f_n_cols = 0;
01305   
01306   std::string line_string;
01307   std::string token;
01308   
01309   while( (f.good() == true) && (load_okay == true) )
01310     {
01311     std::getline(f, line_string);
01312     
01313     if(line_string.size() == 0)
01314       {
01315       break;
01316       }
01317     
01318     std::stringstream line_stream(line_string);
01319     
01320     uword line_n_cols = 0;
01321     
01322     while(line_stream.good() == true)
01323       {
01324       getline(line_stream, token, ',');
01325       ++line_n_cols;
01326       }
01327     
01328     if(f_n_cols < line_n_cols)
01329       {
01330       f_n_cols = line_n_cols;
01331       }
01332     
01333     ++f_n_rows;
01334     }
01335   
01336   f.clear();
01337   f.seekg(pos1);
01338   
01339   x.zeros(f_n_rows, f_n_cols);
01340   
01341   uword row = 0;
01342   
01343   while(f.good() == true)
01344     {
01345     std::getline(f, line_string);
01346     
01347     if(line_string.size() == 0)
01348       {
01349       break;
01350       }
01351     
01352     std::stringstream line_stream(line_string);
01353     
01354     uword col = 0;
01355     
01356     while(line_stream.good() == true)
01357       {
01358       getline(line_stream, token, ',');
01359       
01360       eT val;
01361       
01362       std::stringstream ss(token);
01363       
01364       ss >> val;
01365       
01366       if(ss.fail() == false)
01367         {
01368         x.at(row,col) = val;
01369         }
01370       
01371       ++col;
01372       }
01373     
01374     ++row;
01375     }
01376   
01377   return load_okay;
01378   }
01379 
01380 
01381 
01384 template<typename eT>
01385 inline
01386 bool
01387 diskio::load_arma_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
01388   {
01389   arma_extra_debug_sigprint();
01390   
01391   std::ifstream f;
01392   f.open(name.c_str(), std::fstream::binary);
01393   
01394   bool load_okay = f.is_open();
01395   
01396   if(load_okay == true)
01397     {
01398     load_okay = diskio::load_arma_binary(x, f, err_msg);
01399     f.close();
01400     }
01401   
01402   return load_okay;
01403   }
01404 
01405 
01406 
01407 template<typename eT>
01408 inline
01409 bool
01410 diskio::load_arma_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
01411   {
01412   arma_extra_debug_sigprint();
01413   
01414   bool load_okay = true;
01415   
01416   std::string f_header;
01417   uword f_n_rows;
01418   uword f_n_cols;
01419   
01420   f >> f_header;
01421   f >> f_n_rows;
01422   f >> f_n_cols;
01423   
01424   if(f_header == diskio::gen_bin_header(x))
01425     {
01426     //f.seekg(1, ios::cur);  // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
01427     f.get();
01428     
01429     x.set_size(f_n_rows,f_n_cols);
01430     f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
01431     
01432     load_okay = f.good();
01433     }
01434   else
01435     {
01436     load_okay = false;
01437     err_msg = "incorrect header in ";
01438     }
01439   
01440   return load_okay;
01441   }
01442 
01443 
01444 
01445 inline
01446 void
01447 diskio::pnm_skip_comments(std::istream& f)
01448   {
01449   while( isspace(f.peek()) )
01450     {
01451     while( isspace(f.peek()) )
01452       {
01453       f.get();
01454       }
01455   
01456     if(f.peek() == '#')
01457       {
01458       while( (f.peek() != '\r') && (f.peek()!='\n') )
01459         {
01460         f.get();
01461         }
01462       }
01463     }
01464   }
01465 
01466 
01467 
01469 template<typename eT>
01470 inline
01471 bool
01472 diskio::load_pgm_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
01473   {
01474   arma_extra_debug_sigprint();
01475   
01476   std::fstream f;
01477   f.open(name.c_str(), std::fstream::in | std::fstream::binary);
01478   
01479   bool load_okay = f.is_open();
01480   
01481   if(load_okay == true)
01482     {
01483     load_okay = diskio::load_pgm_binary(x, f, err_msg);
01484     f.close();
01485     }
01486   
01487   return load_okay;
01488   }
01489 
01490 
01491 
01493 template<typename eT>
01494 inline
01495 bool
01496 diskio::load_pgm_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
01497   {
01498   bool load_okay = true;
01499   
01500   std::string f_header;
01501   f >> f_header;
01502   
01503   if(f_header == "P5")
01504     {
01505     uword f_n_rows = 0;
01506     uword f_n_cols = 0;
01507     int f_maxval = 0;
01508   
01509     diskio::pnm_skip_comments(f);
01510   
01511     f >> f_n_cols;
01512     diskio::pnm_skip_comments(f);
01513   
01514     f >> f_n_rows;
01515     diskio::pnm_skip_comments(f);
01516   
01517     f >> f_maxval;
01518     f.get();
01519     
01520     if( (f_maxval > 0) || (f_maxval <= 65535) )
01521       {
01522       x.set_size(f_n_rows,f_n_cols);
01523       
01524       if(f_maxval <= 255)
01525         {
01526         const uword n_elem = f_n_cols*f_n_rows;
01527         podarray<u8> tmp(n_elem);
01528         
01529         f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
01530         
01531         uword i = 0;
01532         
01533         //cout << "f_n_cols = " << f_n_cols << endl;
01534         //cout << "f_n_rows = " << f_n_rows << endl;
01535         
01536         
01537         for(uword row=0; row < f_n_rows; ++row)
01538           {
01539           for(uword col=0; col < f_n_cols; ++col)
01540             {
01541             x.at(row,col) = eT(tmp[i]);
01542             ++i;
01543             }
01544           }
01545           
01546         }
01547       else
01548         {
01549         const uword n_elem = f_n_cols*f_n_rows;
01550         podarray<u16> tmp(n_elem);
01551         
01552         f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(n_elem*2) );
01553         
01554         uword i = 0;
01555         
01556         for(uword row=0; row < f_n_rows; ++row)
01557           {
01558           for(uword col=0; col < f_n_cols; ++col)
01559             {
01560             x.at(row,col) = eT(tmp[i]);
01561             ++i;
01562             }
01563           }
01564         
01565         }
01566       
01567       }
01568     else
01569       {
01570       load_okay = false;
01571       err_msg = "currently no code available to handle loading ";
01572       }
01573     
01574     if(f.good() == false)
01575       {
01576       load_okay = false;
01577       }
01578     }
01579   else
01580     {
01581     load_okay = false;
01582     err_msg = "unsupported header in ";
01583     }
01584   
01585   return load_okay;
01586   }
01587 
01588 
01589 
01591 template<typename T>
01592 inline
01593 bool
01594 diskio::load_pgm_binary(Mat< std::complex<T> >& x, const std::string& name, std::string& err_msg)
01595   {
01596   arma_extra_debug_sigprint();
01597   
01598   uchar_mat tmp;
01599   const bool load_okay = diskio::load_pgm_binary(tmp, name, err_msg);
01600   
01601   x = conv_to< Mat< std::complex<T> > >::from(tmp);
01602   
01603   return load_okay;
01604   }
01605 
01606 
01607 
01609 template<typename T>
01610 inline
01611 bool
01612 diskio::load_pgm_binary(Mat< std::complex<T> >& x, std::istream& is, std::string& err_msg)
01613   {
01614   arma_extra_debug_sigprint();
01615   
01616   uchar_mat tmp;
01617   const bool load_okay = diskio::load_pgm_binary(tmp, is, err_msg);
01618   
01619   x = conv_to< Mat< std::complex<T> > >::from(tmp);
01620   
01621   return load_okay;
01622   }
01623 
01624 
01625 
01627 template<typename eT>
01628 inline
01629 bool
01630 diskio::load_auto_detect(Mat<eT>& x, const std::string& name, std::string& err_msg)
01631   {
01632   arma_extra_debug_sigprint();
01633   
01634   std::fstream f;
01635   f.open(name.c_str(), std::fstream::in | std::fstream::binary);
01636   
01637   bool load_okay = f.is_open();
01638   
01639   if(load_okay == true)
01640     {
01641     load_okay = diskio::load_auto_detect(x, f, err_msg);
01642     f.close();
01643     }
01644   
01645   return load_okay;
01646   }
01647 
01648 
01649 
01651 template<typename eT>
01652 inline
01653 bool
01654 diskio::load_auto_detect(Mat<eT>& x, std::istream& f, std::string& err_msg)
01655   {
01656   arma_extra_debug_sigprint();
01657   
01658   static const std::string ARMA_MAT_TXT = "ARMA_MAT_TXT";
01659   static const std::string ARMA_MAT_BIN = "ARMA_MAT_BIN";
01660   static const std::string           P5 = "P5";
01661   
01662   podarray<char> raw_header(ARMA_MAT_TXT.length() + 1);
01663   
01664   std::streampos pos = f.tellg();
01665     
01666   f.read( raw_header.memptr(), std::streamsize(ARMA_MAT_TXT.length()) );
01667   raw_header[ARMA_MAT_TXT.length()] = '\0';
01668   
01669   f.clear();
01670   f.seekg(pos);
01671   
01672   const std::string header = raw_header.mem;
01673   
01674   if(ARMA_MAT_TXT == header.substr(0,ARMA_MAT_TXT.length()))
01675     {
01676     return load_arma_ascii(x, f, err_msg);
01677     }
01678   else
01679   if(ARMA_MAT_BIN == header.substr(0,ARMA_MAT_BIN.length()))
01680     {
01681     return load_arma_binary(x, f, err_msg);
01682     }
01683   else
01684   if(P5 == header.substr(0,P5.length()))
01685     {
01686     return load_pgm_binary(x, f, err_msg);
01687     }
01688   else
01689     {
01690     const file_type ft = guess_file_type(f);
01691     
01692     switch(ft)
01693       {
01694       case csv_ascii:
01695         return load_csv_ascii(x, f, err_msg);
01696         break;
01697       
01698       case raw_binary:
01699         return load_raw_binary(x, f, err_msg);
01700         break;
01701         
01702       case raw_ascii:
01703         return load_raw_ascii(x, f, err_msg);
01704         break;
01705       
01706       default:
01707         err_msg = "unknown data in ";
01708         return false;
01709       }
01710     }
01711   
01712   return false;
01713   }
01714 
01715 
01716 
01717 // cubes
01718 
01719 
01720 
01722 template<typename eT>
01723 inline
01724 bool
01725 diskio::save_raw_ascii(const Cube<eT>& x, const std::string& final_name)
01726   {
01727   arma_extra_debug_sigprint();
01728   
01729   const std::string tmp_name = diskio::gen_tmp_name(final_name);
01730   
01731   std::fstream f(tmp_name.c_str(), std::fstream::out);
01732   
01733   bool save_okay = f.is_open();
01734   
01735   if(save_okay == true)
01736     {
01737     save_okay = save_raw_ascii(x, f);
01738     
01739     f.flush();
01740     f.close();
01741     
01742     if(save_okay == true)
01743       {
01744       save_okay = diskio::safe_rename(tmp_name, final_name);
01745       }
01746     }
01747   
01748   return save_okay;
01749   }
01750 
01751 
01752 
01754 template<typename eT>
01755 inline
01756 bool
01757 diskio::save_raw_ascii(const Cube<eT>& x, std::ostream& f)
01758   {
01759   arma_extra_debug_sigprint();
01760   
01761   uword cell_width;
01762   
01763   // TODO: need sane values for complex numbers
01764   
01765   if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
01766     {
01767     f.setf(ios::scientific);
01768     f.precision(10);
01769     cell_width = 18;
01770     }
01771   
01772   for(uword slice=0; slice < x.n_slices; ++slice)
01773     {
01774     for(uword row=0; row < x.n_rows; ++row)
01775       {
01776       for(uword col=0; col < x.n_cols; ++col)
01777         {
01778         f.put(' ');
01779         
01780         if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
01781           {
01782           f.width(cell_width);
01783           }
01784         
01785         f << x.at(row,col,slice);
01786         }
01787         
01788       f.put('\n');
01789       }
01790     }
01791   
01792   return f.good();
01793   }
01794 
01795 
01796 
01798 template<typename eT>
01799 inline
01800 bool
01801 diskio::save_raw_binary(const Cube<eT>& x, const std::string& final_name)
01802   {
01803   arma_extra_debug_sigprint();
01804   
01805   const std::string tmp_name = diskio::gen_tmp_name(final_name);
01806   
01807   std::ofstream f(tmp_name.c_str(), std::fstream::binary);
01808   
01809   bool save_okay = f.is_open();
01810   
01811   if(save_okay == true)
01812     {
01813     save_okay = diskio::save_raw_binary(x, f);
01814     
01815     f.flush();
01816     f.close();
01817     
01818     if(save_okay == true)
01819       {
01820       save_okay = diskio::safe_rename(tmp_name, final_name);
01821       }
01822     }
01823   
01824   return save_okay;
01825   }
01826 
01827 
01828 
01829 template<typename eT>
01830 inline
01831 bool
01832 diskio::save_raw_binary(const Cube<eT>& x, std::ostream& f)
01833   {
01834   arma_extra_debug_sigprint();
01835   
01836   f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
01837   
01838   return f.good();
01839   }
01840 
01841 
01842 
01845 template<typename eT>
01846 inline
01847 bool
01848 diskio::save_arma_ascii(const Cube<eT>& x, const std::string& final_name)
01849   {
01850   arma_extra_debug_sigprint();
01851   
01852   const std::string tmp_name = diskio::gen_tmp_name(final_name);
01853   
01854   std::ofstream f(tmp_name.c_str());
01855   
01856   bool save_okay = f.is_open();
01857   
01858   if(save_okay == true)
01859     {
01860     save_okay = diskio::save_arma_ascii(x, f);
01861     
01862     f.flush();
01863     f.close();
01864     
01865     if(save_okay == true)
01866       {
01867       save_okay = diskio::safe_rename(tmp_name, final_name);
01868       }
01869     }
01870   
01871   return save_okay;
01872   }
01873 
01874 
01875 
01878 template<typename eT>
01879 inline
01880 bool
01881 diskio::save_arma_ascii(const Cube<eT>& x, std::ostream& f)
01882   {
01883   arma_extra_debug_sigprint();
01884   
01885   const ios::fmtflags orig_flags = f.flags();
01886   
01887   f << diskio::gen_txt_header(x) << '\n';
01888   f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
01889   
01890   uword cell_width;
01891   
01892   // TODO: need sane values for complex numbers
01893   
01894   if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
01895     {
01896     f.setf(ios::scientific);
01897     f.precision(10);
01898     cell_width = 18;
01899     }
01900     
01901   for(uword slice=0; slice < x.n_slices; ++slice)
01902     {
01903     for(uword row=0; row < x.n_rows; ++row)
01904       {
01905       for(uword col=0; col < x.n_cols; ++col)
01906         {
01907         f.put(' ');
01908         
01909         if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )        
01910           {
01911           f.width(cell_width);
01912           }
01913         
01914         f << x.at(row,col,slice);
01915         }
01916       
01917       f.put('\n');
01918       }
01919     }
01920   
01921   const bool save_okay = f.good();
01922   
01923   f.flags(orig_flags);
01924   
01925   return save_okay;
01926   }
01927 
01928 
01929 
01932 template<typename eT>
01933 inline
01934 bool
01935 diskio::save_arma_binary(const Cube<eT>& x, const std::string& final_name)
01936   {
01937   arma_extra_debug_sigprint();
01938   
01939   const std::string tmp_name = diskio::gen_tmp_name(final_name);
01940   
01941   std::ofstream f(tmp_name.c_str(), std::fstream::binary);
01942   
01943   bool save_okay = f.is_open();
01944   
01945   if(save_okay == true)
01946     {
01947     save_okay = diskio::save_arma_binary(x, f);
01948     
01949     f.flush();
01950     f.close();
01951     
01952     if(save_okay == true)
01953       {
01954       save_okay = diskio::safe_rename(tmp_name, final_name);
01955       }
01956     }
01957   
01958   return save_okay;
01959   }
01960 
01961 
01962 
01965 template<typename eT>
01966 inline
01967 bool
01968 diskio::save_arma_binary(const Cube<eT>& x, std::ostream& f)
01969   {
01970   arma_extra_debug_sigprint();
01971   
01972   f << diskio::gen_bin_header(x) << '\n';
01973   f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
01974   
01975   f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
01976   
01977   return f.good();
01978   }
01979 
01980 
01981 
01984 template<typename eT>
01985 inline
01986 bool
01987 diskio::load_raw_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
01988   {
01989   arma_extra_debug_sigprint();
01990   
01991   Mat<eT> tmp;
01992   const bool load_okay = diskio::load_raw_ascii(tmp, name, err_msg);
01993   
01994   if(load_okay == true)
01995     {
01996     if(tmp.is_empty() == false)
01997       {
01998       x.set_size(tmp.n_rows, tmp.n_cols, 1);
01999       
02000       x.slice(0) = tmp;
02001       }
02002     else
02003       {
02004       x.reset();
02005       }
02006     }
02007   
02008   return load_okay;
02009   }
02010 
02011 
02012 
02015 template<typename eT>
02016 inline
02017 bool
02018 diskio::load_raw_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
02019   {
02020   arma_extra_debug_sigprint();
02021   
02022   Mat<eT> tmp;
02023   const bool load_okay = diskio::load_raw_ascii(tmp, f, err_msg);
02024   
02025   if(load_okay == true)
02026     {
02027     if(tmp.is_empty() == false)
02028       {
02029       x.set_size(tmp.n_rows, tmp.n_cols, 1);
02030       
02031       x.slice(0) = tmp;
02032       }
02033     else
02034       {
02035       x.reset();
02036       }
02037     }
02038   
02039   return load_okay;
02040   }
02041 
02042 
02043 
02046 template<typename eT>
02047 inline
02048 bool
02049 diskio::load_raw_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
02050   {
02051   arma_extra_debug_sigprint();
02052   
02053   std::ifstream f;
02054   f.open(name.c_str(), std::fstream::binary);
02055   
02056   bool load_okay = f.is_open();
02057   
02058   if(load_okay == true)
02059     {
02060     load_okay = diskio::load_raw_binary(x, f, err_msg);
02061     f.close();
02062     }
02063   
02064   return load_okay;
02065   }
02066 
02067 
02068 
02069 template<typename eT>
02070 inline
02071 bool
02072 diskio::load_raw_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
02073   {
02074   arma_extra_debug_sigprint();
02075   arma_ignore(err_msg);
02076   
02077   f.clear();
02078   const std::streampos pos1 = f.tellg();
02079   
02080   f.clear();
02081   f.seekg(0, ios::end);
02082   
02083   f.clear();
02084   const std::streampos pos2 = f.tellg();
02085   
02086   const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
02087   
02088   f.clear();
02089   //f.seekg(0, ios::beg);
02090   f.seekg(pos1);
02091   
02092   x.set_size(N / sizeof(eT), 1, 1);
02093   
02094   f.clear();
02095   f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
02096   
02097   return f.good();
02098   }
02099 
02100 
02101 
02104 template<typename eT>
02105 inline
02106 bool
02107 diskio::load_arma_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
02108   {
02109   arma_extra_debug_sigprint();
02110   
02111   std::ifstream f(name.c_str());
02112   
02113   bool load_okay = f.is_open();
02114   
02115   if(load_okay == true)
02116     {
02117     load_okay = diskio::load_arma_ascii(x, f, err_msg);
02118     f.close();
02119     }
02120   
02121   return load_okay;
02122   }
02123   
02124 
02125 
02128 template<typename eT>
02129 inline
02130 bool
02131 diskio::load_arma_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
02132   {
02133   arma_extra_debug_sigprint();
02134   
02135   bool load_okay = true;
02136   
02137   std::string f_header;
02138   uword f_n_rows;
02139   uword f_n_cols;
02140   uword f_n_slices;
02141   
02142   f >> f_header;
02143   f >> f_n_rows;
02144   f >> f_n_cols;
02145   f >> f_n_slices;
02146   
02147   if(f_header == diskio::gen_txt_header(x))
02148     {
02149     x.set_size(f_n_rows, f_n_cols, f_n_slices);
02150 
02151     for(uword slice=0; slice < x.n_slices; ++slice)
02152       {
02153       for(uword row=0; row < x.n_rows; ++row)
02154         {
02155         for(uword col=0; col < x.n_cols; ++col)
02156           {
02157           f >> x.at(row,col,slice);
02158           }
02159         }
02160       }
02161     
02162     load_okay = f.good();
02163     }
02164   else
02165     {
02166     load_okay = false;
02167     err_msg = "incorrect header in ";
02168     }
02169   
02170   return load_okay;
02171   }
02172 
02173 
02174 
02177 template<typename eT>
02178 inline
02179 bool
02180 diskio::load_arma_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
02181   {
02182   arma_extra_debug_sigprint();
02183   
02184   std::ifstream f;
02185   f.open(name.c_str(), std::fstream::binary);
02186   
02187   bool load_okay = f.is_open();
02188   
02189   if(load_okay == true)
02190     {
02191     load_okay = diskio::load_arma_binary(x, f, err_msg);
02192     f.close();
02193     }
02194   
02195   return load_okay;
02196   }
02197 
02198 
02199 
02200 template<typename eT>
02201 inline
02202 bool
02203 diskio::load_arma_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
02204   {
02205   arma_extra_debug_sigprint();
02206   
02207   bool load_okay = true;
02208   
02209   std::string f_header;
02210   uword f_n_rows;
02211   uword f_n_cols;
02212   uword f_n_slices;
02213   
02214   f >> f_header;
02215   f >> f_n_rows;
02216   f >> f_n_cols;
02217   f >> f_n_slices;
02218   
02219   if(f_header == diskio::gen_bin_header(x))
02220     {
02221     //f.seekg(1, ios::cur);  // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
02222     f.get();
02223     
02224     x.set_size(f_n_rows, f_n_cols, f_n_slices);
02225     f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
02226     
02227     load_okay = f.good();
02228     }
02229   else
02230     {
02231     load_okay = false;
02232     err_msg = "incorrect header in ";
02233     }
02234   
02235   return load_okay;
02236   }
02237 
02238 
02239 
02241 template<typename eT>
02242 inline
02243 bool
02244 diskio::load_auto_detect(Cube<eT>& x, const std::string& name, std::string& err_msg)
02245   {
02246   arma_extra_debug_sigprint();
02247   
02248   std::fstream f;
02249   f.open(name.c_str(), std::fstream::in | std::fstream::binary);
02250   
02251   bool load_okay = f.is_open();
02252   
02253   if(load_okay == true)
02254     {
02255     load_okay = diskio::load_auto_detect(x, f, err_msg);
02256     f.close();
02257     }
02258   
02259   return load_okay;
02260   }
02261 
02262 
02263 
02265 template<typename eT>
02266 inline
02267 bool
02268 diskio::load_auto_detect(Cube<eT>& x, std::istream& f, std::string& err_msg)
02269   {
02270   arma_extra_debug_sigprint();
02271   
02272   static const std::string ARMA_CUB_TXT = "ARMA_CUB_TXT";
02273   static const std::string ARMA_CUB_BIN = "ARMA_CUB_BIN";
02274   static const std::string           P6 = "P6";
02275   
02276   podarray<char> raw_header(ARMA_CUB_TXT.length() + 1);
02277   
02278   std::streampos pos = f.tellg();
02279   
02280   f.read( raw_header.memptr(), std::streamsize(ARMA_CUB_TXT.length()) );
02281   raw_header[ARMA_CUB_TXT.length()] = '\0';
02282   
02283   f.clear();
02284   f.seekg(pos);
02285   
02286   const std::string header = raw_header.mem;
02287   
02288   if(ARMA_CUB_TXT == header.substr(0, ARMA_CUB_TXT.length()))
02289     {
02290     return load_arma_ascii(x, f, err_msg);
02291     }
02292   else
02293   if(ARMA_CUB_BIN == header.substr(0, ARMA_CUB_BIN.length()))
02294     {
02295     return load_arma_binary(x, f, err_msg);
02296     }
02297   else
02298   if(P6 == header.substr(0, P6.length()))
02299     {
02300     return load_ppm_binary(x, f, err_msg);
02301     }
02302   else
02303     {
02304     const file_type ft = guess_file_type(f);
02305     
02306     switch(ft)
02307       {
02308       // case csv_ascii:
02309       //   return load_csv_ascii(x, f, err_msg);
02310       //   break;
02311       
02312       case raw_binary:
02313         return load_raw_binary(x, f, err_msg);
02314         break;
02315         
02316       case raw_ascii:
02317         return load_raw_ascii(x, f, err_msg);
02318         break;
02319         
02320       default:
02321         err_msg = "unknown data in ";
02322         return false;
02323       }
02324     }
02325   
02326   return false;
02327   }
02328 
02329 
02330 
02331 
02332 
02333 // fields
02334 
02335 
02336 
02337 template<typename T1>
02338 inline
02339 bool
02340 diskio::save_arma_binary(const field<T1>& x, const std::string& final_name)
02341   {
02342   arma_extra_debug_sigprint();
02343   
02344   const std::string tmp_name = diskio::gen_tmp_name(final_name);
02345   
02346   std::ofstream f( tmp_name.c_str(), std::fstream::binary );
02347   
02348   bool save_okay = f.is_open();
02349   
02350   if(save_okay == true)
02351     {
02352     save_okay = diskio::save_arma_binary(x, f);
02353     
02354     f.flush();
02355     f.close();
02356     
02357     if(save_okay == true)
02358       {
02359       save_okay = diskio::safe_rename(tmp_name, final_name);
02360       }
02361     }
02362   
02363   return save_okay;
02364   }
02365 
02366 
02367 
02368 template<typename T1>
02369 inline
02370 bool
02371 diskio::save_arma_binary(const field<T1>& x, std::ostream& f)
02372   {
02373   arma_extra_debug_sigprint();
02374   
02375   arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
02376   
02377   f << "ARMA_FLD_BIN" << '\n';
02378   f << x.n_rows << '\n';
02379   f << x.n_cols << '\n';
02380   
02381   bool save_okay = true;
02382   
02383   for(uword i=0; i<x.n_elem; ++i)
02384     {
02385     save_okay = diskio::save_arma_binary(x[i], f);
02386     
02387     if(save_okay == false)
02388       {
02389       break;
02390       }
02391     }
02392   
02393   return save_okay;
02394   }
02395 
02396 
02397 
02398 template<typename T1>
02399 inline
02400 bool
02401 diskio::load_arma_binary(field<T1>& x, const std::string& name, std::string& err_msg)
02402   {
02403   arma_extra_debug_sigprint();
02404   
02405   std::ifstream f( name.c_str(), std::fstream::binary );
02406   
02407   bool load_okay = f.is_open();
02408   
02409   if(load_okay == true)
02410     {
02411     load_okay = diskio::load_arma_binary(x, f, err_msg);
02412     f.close();
02413     }
02414   
02415   return load_okay;
02416   }
02417 
02418 
02419 
02420 template<typename T1>
02421 inline
02422 bool
02423 diskio::load_arma_binary(field<T1>& x, std::istream& f, std::string& err_msg)
02424   {
02425   arma_extra_debug_sigprint();
02426   
02427   arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
02428   
02429   bool load_okay = true;
02430   
02431   std::string f_type;
02432   f >> f_type;
02433   
02434   if(f_type != "ARMA_FLD_BIN")
02435     {
02436     load_okay = false;
02437     err_msg = "unsupported field type in ";
02438     }
02439   else
02440     {
02441     uword f_n_rows;
02442     uword f_n_cols;
02443   
02444     f >> f_n_rows;
02445     f >> f_n_cols;
02446     
02447     x.set_size(f_n_rows, f_n_cols);
02448     
02449     f.get();      
02450     
02451     for(uword i=0; i<x.n_elem; ++i)
02452       {
02453       load_okay = diskio::load_arma_binary(x[i], f, err_msg);
02454       
02455       if(load_okay == false)
02456         {
02457         break;
02458         }
02459       }
02460     }
02461   
02462   return load_okay;
02463   }
02464 
02465 
02466 
02467 inline
02468 bool
02469 diskio::save_std_string(const field<std::string>& x, const std::string& final_name)
02470   {
02471   arma_extra_debug_sigprint();
02472   
02473   const std::string tmp_name = diskio::gen_tmp_name(final_name);
02474   
02475   std::ofstream f( tmp_name.c_str(), std::fstream::binary );
02476   
02477   bool save_okay = f.is_open();
02478   
02479   if(save_okay == true)
02480     {
02481     save_okay = diskio::save_std_string(x, f);
02482     
02483     f.flush();
02484     f.close();
02485     
02486     if(save_okay == true)
02487       {
02488       save_okay = diskio::safe_rename(tmp_name, final_name);
02489       }
02490     }
02491   
02492   return save_okay;
02493   }
02494 
02495 
02496 
02497 inline
02498 bool
02499 diskio::save_std_string(const field<std::string>& x, std::ostream& f)
02500   {
02501   arma_extra_debug_sigprint();
02502   
02503   for(uword row=0; row<x.n_rows; ++row)
02504   for(uword col=0; col<x.n_cols; ++col)
02505     {
02506     f << x.at(row,col);
02507     
02508     if(col < x.n_cols-1)
02509       {
02510       f << ' ';
02511       }
02512     else
02513       {
02514       f << '\n';
02515       }
02516     }
02517   
02518   return f.good();
02519   }
02520 
02521 
02522 
02523 inline
02524 bool
02525 diskio::load_std_string(field<std::string>& x, const std::string& name, std::string& err_msg)
02526   {
02527   arma_extra_debug_sigprint();
02528   
02529   std::ifstream f( name.c_str() );
02530   
02531   bool load_okay = f.is_open();
02532   
02533   if(load_okay == true)
02534     {
02535     load_okay = diskio::load_std_string(x, f, err_msg);
02536     f.close();
02537     }
02538   
02539   return load_okay;
02540   }
02541 
02542 
02543 
02544 inline
02545 bool
02546 diskio::load_std_string(field<std::string>& x, std::istream& f, std::string& err_msg)
02547   {
02548   arma_extra_debug_sigprint();
02549   
02550   bool load_okay = true;
02551   
02552   //
02553   // work out the size
02554   
02555   uword f_n_rows = 0;
02556   uword f_n_cols = 0;
02557   
02558   bool f_n_cols_found = false;
02559   
02560   std::string line_string;
02561   std::string token;
02562   
02563   while( (f.good() == true) && (load_okay == true) )
02564     {
02565     std::getline(f, line_string);
02566     if(line_string.size() == 0)
02567       break;
02568     
02569     std::stringstream line_stream(line_string);
02570     
02571     uword line_n_cols = 0;
02572     while (line_stream >> token)
02573       line_n_cols++;
02574     
02575     if(f_n_cols_found == false)
02576       {
02577       f_n_cols = line_n_cols;
02578       f_n_cols_found = true;
02579       }
02580     else
02581       {
02582       if(line_n_cols != f_n_cols)
02583         {
02584         load_okay = false;
02585         err_msg = "inconsistent number of columns in ";
02586         }
02587       }
02588     
02589     ++f_n_rows;
02590     }
02591     
02592   if(load_okay == true)
02593     {
02594     f.clear();
02595     f.seekg(0, ios::beg);
02596     //f.seekg(start);
02597     
02598     x.set_size(f_n_rows, f_n_cols);
02599   
02600     for(uword row=0; row < x.n_rows; ++row)
02601       {
02602       for(uword col=0; col < x.n_cols; ++col)
02603         {
02604         f >> x.at(row,col);
02605         }
02606       }
02607     }
02608   
02609   if(f.good() == false)
02610     {
02611     load_okay = false; 
02612     }
02613   
02614   return load_okay;
02615   }
02616 
02617 
02618 
02620 template<typename T1>
02621 inline
02622 bool
02623 diskio::load_auto_detect(field<T1>& x, const std::string& name, std::string& err_msg)
02624   {
02625   arma_extra_debug_sigprint();
02626   
02627   std::fstream f;
02628   f.open(name.c_str(), std::fstream::in | std::fstream::binary);
02629   
02630   bool load_okay = f.is_open();
02631   
02632   if(load_okay == true)
02633     {
02634     load_okay = diskio::load_auto_detect(x, f, err_msg);
02635     f.close();
02636     }
02637   
02638   return load_okay;
02639   }
02640 
02641 
02642 
02644 template<typename T1>
02645 inline
02646 bool
02647 diskio::load_auto_detect(field<T1>& x, std::istream& f, std::string& err_msg)
02648   {
02649   arma_extra_debug_sigprint();
02650   
02651   arma_type_check(( is_Mat<T1>::value == false ));
02652   
02653   static const std::string ARMA_FLD_BIN = "ARMA_FLD_BIN";
02654   static const std::string           P6 = "P6";
02655   
02656   podarray<char> raw_header(ARMA_FLD_BIN.length() + 1);
02657   
02658   std::streampos pos = f.tellg();
02659   
02660   f.read( raw_header.memptr(), std::streamsize(ARMA_FLD_BIN.length()) );
02661   
02662   f.clear();
02663   f.seekg(pos);
02664   
02665   raw_header[ARMA_FLD_BIN.length()] = '\0';
02666   
02667   const std::string header = raw_header.mem;
02668   
02669   if(ARMA_FLD_BIN == header.substr(0, ARMA_FLD_BIN.length()))
02670     {
02671     return load_arma_binary(x, f, err_msg);
02672     }
02673   else
02674   if(P6 == header.substr(0, P6.length()))
02675     {
02676     return load_ppm_binary(x, f, err_msg);
02677     }
02678   else
02679     {
02680     err_msg = "unsupported header in ";
02681     return false;
02682     }
02683   }
02684 
02685 
02686 
02687 //
02688 // handling of PPM images by cubes
02689 
02690 
02691 template<typename eT>
02692 inline
02693 bool
02694 diskio::load_ppm_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
02695   {
02696   arma_extra_debug_sigprint();
02697   
02698   std::fstream f;
02699   f.open(name.c_str(), std::fstream::in | std::fstream::binary);
02700   
02701   bool load_okay = f.is_open();
02702   
02703   if(load_okay == true)
02704     {
02705     load_okay = diskio::load_ppm_binary(x, f, err_msg);
02706     f.close();
02707     }
02708   
02709   return load_okay;
02710   }
02711 
02712 
02713 
02714 template<typename eT>
02715 inline
02716 bool
02717 diskio::load_ppm_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
02718   {
02719   arma_extra_debug_sigprint();
02720   
02721   bool load_okay = true;
02722   
02723   std::string f_header;
02724   f >> f_header;
02725   
02726   if(f_header == "P6")
02727     {
02728     uword f_n_rows = 0;
02729     uword f_n_cols = 0;
02730     int f_maxval = 0;
02731   
02732     diskio::pnm_skip_comments(f);
02733   
02734     f >> f_n_cols;
02735     diskio::pnm_skip_comments(f);
02736   
02737     f >> f_n_rows;
02738     diskio::pnm_skip_comments(f);
02739   
02740     f >> f_maxval;
02741     f.get();
02742     
02743     if( (f_maxval > 0) || (f_maxval <= 65535) )
02744       {
02745       x.set_size(f_n_rows, f_n_cols, 3);
02746       
02747       if(f_maxval <= 255)
02748         {
02749         const uword n_elem = 3*f_n_cols*f_n_rows;
02750         podarray<u8> tmp(n_elem);
02751         
02752         f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
02753         
02754         uword i = 0;
02755         
02756         //cout << "f_n_cols = " << f_n_cols << endl;
02757         //cout << "f_n_rows = " << f_n_rows << endl;
02758         
02759         
02760         for(uword row=0; row < f_n_rows; ++row)
02761           {
02762           for(uword col=0; col < f_n_cols; ++col)
02763             {
02764             x.at(row,col,0) = eT(tmp[i+0]);
02765             x.at(row,col,1) = eT(tmp[i+1]);
02766             x.at(row,col,2) = eT(tmp[i+2]);
02767             i+=3;
02768             }
02769           
02770           }
02771         }
02772       else
02773         {
02774         const uword n_elem = 3*f_n_cols*f_n_rows;
02775         podarray<u16> tmp(n_elem);
02776         
02777         f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
02778         
02779         uword i = 0;
02780         
02781         for(uword row=0; row < f_n_rows; ++row)
02782           {
02783           for(uword col=0; col < f_n_cols; ++col)
02784             {
02785             x.at(row,col,0) = eT(tmp[i+0]);
02786             x.at(row,col,1) = eT(tmp[i+1]);
02787             x.at(row,col,2) = eT(tmp[i+2]);
02788             i+=3;
02789             }
02790           
02791           }
02792         
02793         }
02794       
02795       }
02796     else
02797       {
02798       load_okay = false;
02799       err_msg = "currently no code available to handle loading ";
02800       }
02801       
02802     if(f.good() == false)
02803       {
02804       load_okay = false;
02805       }
02806     
02807     }
02808   else
02809     {
02810     load_okay = false;
02811     err_msg = "unsupported header in ";
02812     }
02813   
02814   return load_okay;
02815   }
02816 
02817 
02818 
02819 template<typename eT>
02820 inline
02821 bool
02822 diskio::save_ppm_binary(const Cube<eT>& x, const std::string& final_name)
02823   {
02824   arma_extra_debug_sigprint();
02825   
02826   const std::string tmp_name = diskio::gen_tmp_name(final_name);
02827   
02828   std::ofstream f( tmp_name.c_str(), std::fstream::binary );
02829   
02830   bool save_okay = f.is_open();
02831   
02832   if(save_okay == true)
02833     {
02834     save_okay = diskio::save_ppm_binary(x, f);
02835     
02836     f.flush();
02837     f.close();
02838     
02839     if(save_okay == true)
02840       {
02841       save_okay = diskio::safe_rename(tmp_name, final_name);
02842       }
02843     }
02844   
02845   return save_okay;
02846   }
02847 
02848 
02849 
02850 template<typename eT>
02851 inline
02852 bool
02853 diskio::save_ppm_binary(const Cube<eT>& x, std::ostream& f)
02854   {
02855   arma_extra_debug_sigprint();
02856   
02857   arma_debug_check( (x.n_slices != 3), "diskio::save_ppm_binary(): given cube must have exactly 3 slices" );
02858   
02859   const uword n_elem = 3 * x.n_rows * x.n_cols;
02860   podarray<u8> tmp(n_elem);
02861   
02862   uword i = 0;
02863   for(uword row=0; row < x.n_rows; ++row)
02864     {
02865     for(uword col=0; col < x.n_cols; ++col)
02866       {
02867       tmp[i+0] = u8( access::tmp_real( x.at(row,col,0) ) );
02868       tmp[i+1] = u8( access::tmp_real( x.at(row,col,1) ) );
02869       tmp[i+2] = u8( access::tmp_real( x.at(row,col,2) ) );
02870       
02871       i+=3;
02872       }
02873     }
02874   
02875   f << "P6" << '\n';
02876   f << x.n_cols << '\n';
02877   f << x.n_rows << '\n';
02878   f << 255 << '\n';
02879   
02880   f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
02881   
02882   return f.good();
02883   }
02884 
02885 
02886 
02887 //
02888 // handling of PPM images by fields
02889 
02890 
02891 
02892 template<typename T1>
02893 inline
02894 bool
02895 diskio::load_ppm_binary(field<T1>& x, const std::string& name, std::string& err_msg)
02896   {
02897   arma_extra_debug_sigprint();
02898   
02899   std::fstream f;
02900   f.open(name.c_str(), std::fstream::in | std::fstream::binary);
02901   
02902   bool load_okay = f.is_open();
02903   
02904   if(load_okay == true)
02905     {
02906     load_okay = diskio::load_ppm_binary(x, f, err_msg);
02907     f.close();
02908     }
02909   
02910   return load_okay;
02911   }
02912 
02913 
02914 
02915 template<typename T1>
02916 inline
02917 bool
02918 diskio::load_ppm_binary(field<T1>& x, std::istream& f, std::string& err_msg)
02919   {
02920   arma_extra_debug_sigprint();
02921   
02922   arma_type_check(( is_Mat<T1>::value == false ));
02923   typedef typename T1::elem_type eT;
02924   
02925   bool load_okay = true;
02926   
02927   std::string f_header;
02928   f >> f_header;
02929   
02930   if(f_header == "P6")
02931     {
02932     uword f_n_rows = 0;
02933     uword f_n_cols = 0;
02934     int f_maxval = 0;
02935   
02936     diskio::pnm_skip_comments(f);
02937   
02938     f >> f_n_cols;
02939     diskio::pnm_skip_comments(f);
02940   
02941     f >> f_n_rows;
02942     diskio::pnm_skip_comments(f);
02943   
02944     f >> f_maxval;
02945     f.get();
02946     
02947     if( (f_maxval > 0) || (f_maxval <= 65535) )
02948       {
02949       x.set_size(3);
02950       Mat<eT>& R = x(0);
02951       Mat<eT>& G = x(1);
02952       Mat<eT>& B = x(2);
02953       
02954       R.set_size(f_n_rows,f_n_cols);
02955       G.set_size(f_n_rows,f_n_cols);
02956       B.set_size(f_n_rows,f_n_cols);
02957       
02958       if(f_maxval <= 255)
02959         {
02960         const uword n_elem = 3*f_n_cols*f_n_rows;
02961         podarray<u8> tmp(n_elem);
02962         
02963         f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
02964         
02965         uword i = 0;
02966         
02967         //cout << "f_n_cols = " << f_n_cols << endl;
02968         //cout << "f_n_rows = " << f_n_rows << endl;
02969         
02970         
02971         for(uword row=0; row < f_n_rows; ++row)
02972           {
02973           for(uword col=0; col < f_n_cols; ++col)
02974             {
02975             R.at(row,col) = eT(tmp[i+0]);
02976             G.at(row,col) = eT(tmp[i+1]);
02977             B.at(row,col) = eT(tmp[i+2]);
02978             i+=3;
02979             }
02980           
02981           }
02982         }
02983       else
02984         {
02985         const uword n_elem = 3*f_n_cols*f_n_rows;
02986         podarray<u16> tmp(n_elem);
02987         
02988         f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
02989         
02990         uword i = 0;
02991         
02992         for(uword row=0; row < f_n_rows; ++row)
02993           {
02994           for(uword col=0; col < f_n_cols; ++col)
02995             {
02996             R.at(row,col) = eT(tmp[i+0]);
02997             G.at(row,col) = eT(tmp[i+1]);
02998             B.at(row,col) = eT(tmp[i+2]);
02999             i+=3;
03000             }
03001           
03002           }
03003         
03004         }
03005       
03006       }
03007     else
03008       {
03009       load_okay = false;
03010       err_msg = "currently no code available to handle loading ";
03011       }
03012     
03013     if(f.good() == false)
03014       {
03015       load_okay = false;
03016       }
03017     
03018     }
03019   else
03020     {
03021     load_okay = false;
03022     err_msg = "unsupported header in ";
03023     }
03024   
03025   return load_okay;
03026   }
03027 
03028 
03029 
03030 template<typename T1>
03031 inline
03032 bool
03033 diskio::save_ppm_binary(const field<T1>& x, const std::string& final_name)
03034   {
03035   arma_extra_debug_sigprint();
03036   
03037   const std::string tmp_name = diskio::gen_tmp_name(final_name);
03038   std::ofstream f( tmp_name.c_str(), std::fstream::binary );
03039   
03040   bool save_okay = f.is_open();
03041   
03042   if(save_okay == true)
03043     {
03044     save_okay = diskio::save_ppm_binary(x, f);
03045     
03046     f.flush();
03047     f.close();
03048     
03049     if(save_okay == true)
03050       {
03051       save_okay = diskio::safe_rename(tmp_name, final_name);
03052       }
03053     }
03054   
03055   return save_okay;
03056   }
03057 
03058 
03059 
03060 template<typename T1>
03061 inline
03062 bool
03063 diskio::save_ppm_binary(const field<T1>& x, std::ostream& f)
03064   {
03065   arma_extra_debug_sigprint();
03066   
03067   arma_type_check(( is_Mat<T1>::value == false ));
03068   
03069   typedef typename T1::elem_type eT;
03070   
03071   arma_debug_check( (x.n_elem != 3), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
03072   
03073   bool same_size = true;
03074   for(uword i=1; i<3; ++i)
03075     {
03076     if( (x(0).n_rows != x(i).n_rows) || (x(0).n_cols != x(i).n_cols) )
03077       {
03078       same_size = false;
03079       break;
03080       }
03081     }
03082   
03083   arma_debug_check( (same_size != true), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
03084   
03085   const Mat<eT>& R = x(0);
03086   const Mat<eT>& G = x(1);
03087   const Mat<eT>& B = x(2);
03088   
03089   f << "P6" << '\n';
03090   f << R.n_cols << '\n';
03091   f << R.n_rows << '\n';
03092   f << 255 << '\n';
03093 
03094   const uword n_elem = 3 * R.n_rows * R.n_cols;
03095   podarray<u8> tmp(n_elem);
03096 
03097   uword i = 0;
03098   for(uword row=0; row < R.n_rows; ++row)
03099     {
03100     for(uword col=0; col < R.n_cols; ++col)
03101       {
03102       tmp[i+0] = u8( access::tmp_real( R.at(row,col) ) );
03103       tmp[i+1] = u8( access::tmp_real( G.at(row,col) ) );
03104       tmp[i+2] = u8( access::tmp_real( B.at(row,col) ) );
03105       
03106       i+=3;
03107       }
03108     }
03109   
03110   f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
03111   
03112   return f.good();
03113   }
03114 
03115 
03116 
03118 


armadillo_matrix
Author(s): Conrad Sanderson - NICTA (www.nicta.com.au), (Wrapper by Sjoerd van den Dries)
autogenerated on Tue Jan 7 2014 11:42:03