$search
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