diskio_meat.hpp
Go to the documentation of this file.
1 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
2 // Copyright (C) 2008-2011 Conrad Sanderson
3 // Copyright (C) 2009-2010 Ian Cullinan
4 //
5 // This file is part of the Armadillo C++ library.
6 // It is provided without any warranty of fitness
7 // for any purpose. You can redistribute this file
8 // and/or modify it under the terms of the GNU
9 // Lesser General Public License (LGPL) as published
10 // by the Free Software Foundation, either version 3
11 // of the License or (at your option) any later version.
12 // (see http://www.opensource.org/licenses for more info)
13 
14 
17 
18 
24 template<typename eT>
25 inline
26 std::string
28  {
30 
31  arma_ignore(x);
32 
33  if(is_u8<eT>::value == true)
34  {
35  return std::string("ARMA_MAT_TXT_IU001");
36  }
37  else
38  if(is_s8<eT>::value == true)
39  {
40  return std::string("ARMA_MAT_TXT_IS001");
41  }
42  else
43  if(is_u16<eT>::value == true)
44  {
45  return std::string("ARMA_MAT_TXT_IU002");
46  }
47  else
48  if(is_s16<eT>::value == true)
49  {
50  return std::string("ARMA_MAT_TXT_IS002");
51  }
52  else
53  if(is_u32<eT>::value == true)
54  {
55  return std::string("ARMA_MAT_TXT_IU004");
56  }
57  else
58  if(is_s32<eT>::value == true)
59  {
60  return std::string("ARMA_MAT_TXT_IS004");
61  }
62 #if defined(ARMA_64BIT_WORD)
63  else
64  if(is_u64<eT>::value == true)
65  {
66  return std::string("ARMA_MAT_TXT_IU008");
67  }
68  else
69  if(is_s64<eT>::value == true)
70  {
71  return std::string("ARMA_MAT_TXT_IS008");
72  }
73 #endif
74  else
75  if(is_float<eT>::value == true)
76  {
77  return std::string("ARMA_MAT_TXT_FN004");
78  }
79  else
80  if(is_double<eT>::value == true)
81  {
82  return std::string("ARMA_MAT_TXT_FN008");
83  }
84  else
85  if(is_complex_float<eT>::value == true)
86  {
87  return std::string("ARMA_MAT_TXT_FC008");
88  }
89  else
91  {
92  return std::string("ARMA_MAT_TXT_FC016");
93  }
94  else
95  {
96  return std::string();
97  }
98 
99  }
100 
101 
102 
108 template<typename eT>
109 inline
110 std::string
112  {
114 
115  arma_ignore(x);
116 
117  if(is_u8<eT>::value == true)
118  {
119  return std::string("ARMA_MAT_BIN_IU001");
120  }
121  else
122  if(is_s8<eT>::value == true)
123  {
124  return std::string("ARMA_MAT_BIN_IS001");
125  }
126  else
127  if(is_u16<eT>::value == true)
128  {
129  return std::string("ARMA_MAT_BIN_IU002");
130  }
131  else
132  if(is_s16<eT>::value == true)
133  {
134  return std::string("ARMA_MAT_BIN_IS002");
135  }
136  else
137  if(is_u32<eT>::value == true)
138  {
139  return std::string("ARMA_MAT_BIN_IU004");
140  }
141  else
142  if(is_s32<eT>::value == true)
143  {
144  return std::string("ARMA_MAT_BIN_IS004");
145  }
146 #if defined(ARMA_64BIT_WORD)
147  else
148  if(is_u64<eT>::value == true)
149  {
150  return std::string("ARMA_MAT_BIN_IU008");
151  }
152  else
153  if(is_s64<eT>::value == true)
154  {
155  return std::string("ARMA_MAT_BIN_IS008");
156  }
157 #endif
158  else
159  if(is_float<eT>::value == true)
160  {
161  return std::string("ARMA_MAT_BIN_FN004");
162  }
163  else
164  if(is_double<eT>::value == true)
165  {
166  return std::string("ARMA_MAT_BIN_FN008");
167  }
168  else
169  if(is_complex_float<eT>::value == true)
170  {
171  return std::string("ARMA_MAT_BIN_FC008");
172  }
173  else
174  if(is_complex_double<eT>::value == true)
175  {
176  return std::string("ARMA_MAT_BIN_FC016");
177  }
178  else
179  {
180  return std::string();
181  }
182 
183  }
184 
185 
186 
192 template<typename eT>
193 inline
194 std::string
196  {
198 
199  arma_ignore(x);
200 
201  if(is_u8<eT>::value == true)
202  {
203  return std::string("ARMA_CUB_TXT_IU001");
204  }
205  else
206  if(is_s8<eT>::value == true)
207  {
208  return std::string("ARMA_CUB_TXT_IS001");
209  }
210  else
211  if(is_u16<eT>::value == true)
212  {
213  return std::string("ARMA_CUB_TXT_IU002");
214  }
215  else
216  if(is_s16<eT>::value == true)
217  {
218  return std::string("ARMA_CUB_TXT_IS002");
219  }
220  else
221  if(is_u32<eT>::value == true)
222  {
223  return std::string("ARMA_CUB_TXT_IU004");
224  }
225  else
226  if(is_s32<eT>::value == true)
227  {
228  return std::string("ARMA_CUB_TXT_IS004");
229  }
230 #if defined(ARMA_64BIT_WORD)
231  else
232  if(is_u64<eT>::value == true)
233  {
234  return std::string("ARMA_CUB_TXT_IU008");
235  }
236  else
237  if(is_s64<eT>::value == true)
238  {
239  return std::string("ARMA_CUB_TXT_IS008");
240  }
241 #endif
242  else
243  if(is_float<eT>::value == true)
244  {
245  return std::string("ARMA_CUB_TXT_FN004");
246  }
247  else
248  if(is_double<eT>::value == true)
249  {
250  return std::string("ARMA_CUB_TXT_FN008");
251  }
252  else
253  if(is_complex_float<eT>::value == true)
254  {
255  return std::string("ARMA_CUB_TXT_FC008");
256  }
257  else
258  if(is_complex_double<eT>::value == true)
259  {
260  return std::string("ARMA_CUB_TXT_FC016");
261  }
262  else
263  {
264  return std::string();
265  }
266 
267  }
268 
269 
270 
276 template<typename eT>
277 inline
278 std::string
280  {
282 
283  arma_ignore(x);
284 
285  if(is_u8<eT>::value == true)
286  {
287  return std::string("ARMA_CUB_BIN_IU001");
288  }
289  else
290  if(is_s8<eT>::value == true)
291  {
292  return std::string("ARMA_CUB_BIN_IS001");
293  }
294  else
295  if(is_u16<eT>::value == true)
296  {
297  return std::string("ARMA_CUB_BIN_IU002");
298  }
299  else
300  if(is_s16<eT>::value == true)
301  {
302  return std::string("ARMA_CUB_BIN_IS002");
303  }
304  else
305  if(is_u32<eT>::value == true)
306  {
307  return std::string("ARMA_CUB_BIN_IU004");
308  }
309  else
310  if(is_s32<eT>::value == true)
311  {
312  return std::string("ARMA_CUB_BIN_IS004");
313  }
314 #if defined(ARMA_64BIT_WORD)
315  else
316  if(is_u64<eT>::value == true)
317  {
318  return std::string("ARMA_CUB_BIN_IU008");
319  }
320  else
321  if(is_s64<eT>::value == true)
322  {
323  return std::string("ARMA_CUB_BIN_IS008");
324  }
325 #endif
326  else
327  if(is_float<eT>::value == true)
328  {
329  return std::string("ARMA_CUB_BIN_FN004");
330  }
331  else
332  if(is_double<eT>::value == true)
333  {
334  return std::string("ARMA_CUB_BIN_FN008");
335  }
336  else
337  if(is_complex_float<eT>::value == true)
338  {
339  return std::string("ARMA_CUB_BIN_FC008");
340  }
341  else
342  if(is_complex_double<eT>::value == true)
343  {
344  return std::string("ARMA_CUB_BIN_FC016");
345  }
346  else
347  {
348  return std::string();
349  }
350 
351  }
352 
353 
354 
355 inline
356 file_type
357 diskio::guess_file_type(std::istream& f)
358  {
360 
361  f.clear();
362  const std::fstream::pos_type pos1 = f.tellg();
363 
364  f.clear();
365  f.seekg(0, ios::end);
366 
367  f.clear();
368  const std::fstream::pos_type pos2 = f.tellg();
369 
370  const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
371 
372  f.clear();
373  f.seekg(pos1);
374 
375  podarray<unsigned char> data(N);
376 
377  unsigned char* ptr = data.memptr();
378 
379  f.clear();
380  f.read( reinterpret_cast<char*>(ptr), std::streamsize(N) );
381 
382  const bool load_okay = f.good();
383 
384  f.clear();
385  f.seekg(pos1);
386 
387  bool has_binary = false;
388  bool has_comma = false;
389 
390  if(load_okay == true)
391  {
392  uword i = 0;
393  uword j = (N >= 2) ? 1 : 0;
394 
395  for(; j<N; i+=2, j+=2)
396  {
397  const unsigned char val_i = ptr[i];
398  const unsigned char val_j = ptr[j];
399 
400  // the range checking can be made more elaborate
401  if( ((val_i <= 8) || (val_i >= 123)) || ((val_j <= 8) || (val_j >= 123)) )
402  {
403  has_binary = true;
404  break;
405  }
406 
407  if( (val_i == ',') || (val_j == ',') )
408  {
409  has_comma = true;
410  break;
411  }
412  }
413  }
414  else
415  {
416  return file_type_unknown;
417  }
418 
419  if(has_binary)
420  {
421  return raw_binary;
422  }
423 
424  if(has_comma)
425  {
426  return csv_ascii;
427  }
428 
429  return raw_ascii;
430  }
431 
432 
433 
434 inline
435 char
437  {
438  char out;
439 
440  switch(x)
441  {
442  case 0: out = '0'; break;
443  case 1: out = '1'; break;
444  case 2: out = '2'; break;
445  case 3: out = '3'; break;
446  case 4: out = '4'; break;
447  case 5: out = '5'; break;
448  case 6: out = '6'; break;
449  case 7: out = '7'; break;
450  case 8: out = '8'; break;
451  case 9: out = '9'; break;
452  case 10: out = 'a'; break;
453  case 11: out = 'b'; break;
454  case 12: out = 'c'; break;
455  case 13: out = 'd'; break;
456  case 14: out = 'e'; break;
457  case 15: out = 'f'; break;
458  default: out = '-'; break;
459  }
460 
461  return out;
462  }
463 
464 
465 
466 inline
467 void
468 diskio::conv_to_hex(char* out, const u8 x)
469  {
470  const u8 a = x / 16;
471  const u8 b = x - 16*a;
472 
473  out[0] = conv_to_hex_char(a);
474  out[1] = conv_to_hex_char(b);
475  }
476 
477 
478 
486 inline
487 std::string
488 diskio::gen_tmp_name(const std::string& x)
489  {
490  const std::string* ptr_x = &x;
491  const u8* ptr_ptr_x = reinterpret_cast<const u8*>(&ptr_x);
492 
493  const char* extra = ".tmp_";
494  const uword extra_size = 5;
495 
496  const uword tmp_size = 2*sizeof(u8*) + 2*2;
497  char tmp[tmp_size];
498 
499  uword char_count = 0;
500 
501  for(uword i=0; i<sizeof(u8*); ++i)
502  {
503  conv_to_hex(&tmp[char_count], ptr_ptr_x[i]);
504  char_count += 2;
505  }
506 
507  const uword x_size = static_cast<uword>(x.size());
508  u8 sum = 0;
509 
510  for(uword i=0; i<x_size; ++i)
511  {
512  sum += u8(x[i]);
513  }
514 
515  conv_to_hex(&tmp[char_count], sum);
516  char_count += 2;
517 
518  conv_to_hex(&tmp[char_count], u8(x_size));
519 
520 
521  std::string out;
522  out.resize(x_size + extra_size + tmp_size);
523 
524 
525  for(uword i=0; i<x_size; ++i)
526  {
527  out[i] = x[i];
528  }
529 
530  for(uword i=0; i<extra_size; ++i)
531  {
532  out[x_size + i] = extra[i];
533  }
534 
535  for(uword i=0; i<tmp_size; ++i)
536  {
537  out[x_size + extra_size + i] = tmp[i];
538  }
539 
540  return out;
541  }
542 
543 
544 
550 inline
551 bool
552 diskio::safe_rename(const std::string& old_name, const std::string& new_name)
553  {
554  std::fstream f(new_name.c_str(), std::fstream::out | std::fstream::app);
555  f.put(' ');
556 
557  bool save_okay = f.good();
558  f.close();
559 
560  if(save_okay == true)
561  {
562  std::remove(new_name.c_str());
563 
564  const int mv_result = std::rename(old_name.c_str(), new_name.c_str());
565 
566  save_okay = (mv_result == 0);
567  }
568 
569  return save_okay;
570  }
571 
572 
573 
576 template<typename eT>
577 inline
578 bool
579 diskio::save_raw_ascii(const Mat<eT>& x, const std::string& final_name)
580  {
582 
583  const std::string tmp_name = diskio::gen_tmp_name(final_name);
584 
585  std::fstream f(tmp_name.c_str(), std::fstream::out);
586 
587  bool save_okay = f.is_open();
588 
589  if(save_okay == true)
590  {
591  save_okay = diskio::save_raw_ascii(x, f);
592 
593  f.flush();
594  f.close();
595 
596  if(save_okay == true)
597  {
598  save_okay = diskio::safe_rename(tmp_name, final_name);
599  }
600  }
601 
602  return save_okay;
603  }
604 
605 
606 
609 template<typename eT>
610 inline
611 bool
612 diskio::save_raw_ascii(const Mat<eT>& x, std::ostream& f)
613  {
615 
616  uword cell_width;
617 
618  // TODO: need sane values for complex numbers
619 
620  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
621  {
622  f.setf(ios::scientific);
623  f.precision(10);
624  cell_width = 18;
625  }
626 
627  for(uword row=0; row < x.n_rows; ++row)
628  {
629  for(uword col=0; col < x.n_cols; ++col)
630  {
631  f.put(' ');
632 
633  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
634  {
635  f.width(cell_width);
636  }
637 
638  f << x.at(row,col);
639  }
640 
641  f.put('\n');
642  }
643 
644  return f.good();
645  }
646 
647 
648 
650 template<typename eT>
651 inline
652 bool
653 diskio::save_raw_binary(const Mat<eT>& x, const std::string& final_name)
654  {
656 
657  const std::string tmp_name = diskio::gen_tmp_name(final_name);
658 
659  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
660 
661  bool save_okay = f.is_open();
662 
663  if(save_okay == true)
664  {
665  save_okay = diskio::save_raw_binary(x, f);
666 
667  f.flush();
668  f.close();
669 
670  if(save_okay == true)
671  {
672  save_okay = diskio::safe_rename(tmp_name, final_name);
673  }
674  }
675 
676  return save_okay;
677  }
678 
679 
680 
681 template<typename eT>
682 inline
683 bool
684 diskio::save_raw_binary(const Mat<eT>& x, std::ostream& f)
685  {
687 
688  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
689 
690  return f.good();
691  }
692 
693 
694 
697 template<typename eT>
698 inline
699 bool
700 diskio::save_arma_ascii(const Mat<eT>& x, const std::string& final_name)
701  {
703 
704  const std::string tmp_name = diskio::gen_tmp_name(final_name);
705 
706  std::ofstream f(tmp_name.c_str());
707 
708  bool save_okay = f.is_open();
709 
710  if(save_okay == true)
711  {
712  save_okay = diskio::save_arma_ascii(x, f);
713 
714  f.flush();
715  f.close();
716 
717  if(save_okay == true)
718  {
719  save_okay = diskio::safe_rename(tmp_name, final_name);
720  }
721  }
722 
723  return save_okay;
724  }
725 
726 
727 
730 template<typename eT>
731 inline
732 bool
733 diskio::save_arma_ascii(const Mat<eT>& x, std::ostream& f)
734  {
736 
737  const ios::fmtflags orig_flags = f.flags();
738 
739  f << diskio::gen_txt_header(x) << '\n';
740  f << x.n_rows << ' ' << x.n_cols << '\n';
741 
742  uword cell_width;
743 
744  // TODO: need sane values for complex numbers
745 
746  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
747  {
748  f.setf(ios::scientific);
749  f.precision(10);
750  cell_width = 18;
751  }
752 
753  for(uword row=0; row < x.n_rows; ++row)
754  {
755  for(uword col=0; col < x.n_cols; ++col)
756  {
757  f.put(' ');
758 
759  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
760  {
761  f.width(cell_width);
762  }
763 
764  f << x.at(row,col);
765  }
766 
767  f.put('\n');
768  }
769 
770  const bool save_okay = f.good();
771 
772  f.flags(orig_flags);
773 
774  return save_okay;
775  }
776 
777 
778 
780 template<typename eT>
781 inline
782 bool
783 diskio::save_csv_ascii(const Mat<eT>& x, const std::string& final_name)
784  {
786 
787  const std::string tmp_name = diskio::gen_tmp_name(final_name);
788 
789  std::ofstream f(tmp_name.c_str());
790 
791  bool save_okay = f.is_open();
792 
793  if(save_okay == true)
794  {
795  save_okay = diskio::save_csv_ascii(x, f);
796 
797  f.flush();
798  f.close();
799 
800  if(save_okay == true)
801  {
802  save_okay = diskio::safe_rename(tmp_name, final_name);
803  }
804  }
805 
806  return save_okay;
807  }
808 
809 
810 
812 template<typename eT>
813 inline
814 bool
815 diskio::save_csv_ascii(const Mat<eT>& x, std::ostream& f)
816  {
818 
819  const ios::fmtflags orig_flags = f.flags();
820 
821  // TODO: need sane values for complex numbers
822 
823  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
824  {
825  f.setf(ios::scientific);
826  f.precision(10);
827  }
828 
829  uword x_n_rows = x.n_rows;
830  uword x_n_cols = x.n_cols;
831 
832  for(uword row=0; row < x_n_rows; ++row)
833  {
834  for(uword col=0; col < x_n_cols; ++col)
835  {
836  f << x.at(row,col);
837 
838  if( col < (x_n_cols-1) )
839  {
840  f.put(',');
841  }
842  }
843 
844  f.put('\n');
845  }
846 
847  const bool save_okay = f.good();
848 
849  f.flags(orig_flags);
850 
851  return save_okay;
852  }
853 
854 
855 
858 template<typename eT>
859 inline
860 bool
861 diskio::save_arma_binary(const Mat<eT>& x, const std::string& final_name)
862  {
864 
865  const std::string tmp_name = diskio::gen_tmp_name(final_name);
866 
867  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
868 
869  bool save_okay = f.is_open();
870 
871  if(save_okay == true)
872  {
873  save_okay = diskio::save_arma_binary(x, f);
874 
875  f.flush();
876  f.close();
877 
878  if(save_okay == true)
879  {
880  save_okay = diskio::safe_rename(tmp_name, final_name);
881  }
882  }
883 
884  return save_okay;
885  }
886 
887 
888 
891 template<typename eT>
892 inline
893 bool
894 diskio::save_arma_binary(const Mat<eT>& x, std::ostream& f)
895  {
897 
898  f << diskio::gen_bin_header(x) << '\n';
899  f << x.n_rows << ' ' << x.n_cols << '\n';
900 
901  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
902 
903  return f.good();
904  }
905 
906 
907 
909 template<typename eT>
910 inline
911 bool
912 diskio::save_pgm_binary(const Mat<eT>& x, const std::string& final_name)
913  {
915 
916  const std::string tmp_name = diskio::gen_tmp_name(final_name);
917 
918  std::fstream f(tmp_name.c_str(), std::fstream::out | std::fstream::binary);
919 
920  bool save_okay = f.is_open();
921 
922  if(save_okay == true)
923  {
924  save_okay = diskio::save_pgm_binary(x, f);
925 
926  f.flush();
927  f.close();
928 
929  if(save_okay == true)
930  {
931  save_okay = diskio::safe_rename(tmp_name, final_name);
932  }
933  }
934 
935  return save_okay;
936  }
937 
938 
939 
940 //
941 // TODO:
942 // add functionality to save the image in a normalised format,
943 // i.e. scaled so that every value falls in the [0,255] range.
944 
946 template<typename eT>
947 inline
948 bool
949 diskio::save_pgm_binary(const Mat<eT>& x, std::ostream& f)
950  {
952 
953  f << "P5" << '\n';
954  f << x.n_cols << ' ' << x.n_rows << '\n';
955  f << 255 << '\n';
956 
957  const uword n_elem = x.n_rows * x.n_cols;
958  podarray<u8> tmp(n_elem);
959 
960  uword i = 0;
961 
962  for(uword row=0; row < x.n_rows; ++row)
963  {
964  for(uword col=0; col < x.n_cols; ++col)
965  {
966  tmp[i] = u8( x.at(row,col) ); // TODO: add round() ?
967  ++i;
968  }
969  }
970 
971  f.write(reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
972 
973  return f.good();
974  }
975 
976 
977 
979 template<typename T>
980 inline
981 bool
982 diskio::save_pgm_binary(const Mat< std::complex<T> >& x, const std::string& final_name)
983  {
985 
986  const uchar_mat tmp = conv_to<uchar_mat>::from(x);
987 
988  return diskio::save_pgm_binary(tmp, final_name);
989  }
990 
991 
992 
994 template<typename T>
995 inline
996 bool
997 diskio::save_pgm_binary(const Mat< std::complex<T> >& x, std::ostream& f)
998  {
1000 
1001  const uchar_mat tmp = conv_to<uchar_mat>::from(x);
1002 
1003  return diskio::save_pgm_binary(tmp, f);
1004  }
1005 
1006 
1007 
1011 template<typename eT>
1012 inline
1013 bool
1014 diskio::load_raw_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
1015  {
1017 
1018  std::fstream f;
1019  f.open(name.c_str(), std::fstream::in);
1020 
1021  bool load_okay = f.is_open();
1022 
1023  if(load_okay == true)
1024  {
1025  load_okay = diskio::load_raw_ascii(x, f, err_msg);
1026  f.close();
1027  }
1028 
1029  return load_okay;
1030  }
1031 
1032 
1033 
1037 template<typename eT>
1038 inline
1039 bool
1040 diskio::load_raw_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
1041  {
1043 
1044  bool load_okay = f.good();
1045 
1046  f.clear();
1047  const std::fstream::pos_type pos1 = f.tellg();
1048 
1049  //
1050  // work out the size
1051 
1052  uword f_n_rows = 0;
1053  uword f_n_cols = 0;
1054 
1055  bool f_n_cols_found = false;
1056 
1057  std::string line_string;
1058  std::string token;
1059 
1060  while( (f.good() == true) && (load_okay == true) )
1061  {
1062  std::getline(f, line_string);
1063 
1064  if(line_string.size() == 0)
1065  {
1066  break;
1067  }
1068 
1069  std::stringstream line_stream(line_string);
1070 
1071  uword line_n_cols = 0;
1072 
1073  while (line_stream >> token)
1074  {
1075  ++line_n_cols;
1076  }
1077 
1078  if(f_n_cols_found == false)
1079  {
1080  f_n_cols = line_n_cols;
1081  f_n_cols_found = true;
1082  }
1083  else
1084  {
1085  if(line_n_cols != f_n_cols)
1086  {
1087  err_msg = "inconsistent number of columns in ";
1088  load_okay = false;
1089  }
1090  }
1091 
1092  ++f_n_rows;
1093  }
1094 
1095  if(load_okay == true)
1096  {
1097  f.clear();
1098  f.seekg(pos1);
1099 
1100  x.set_size(f_n_rows, f_n_cols);
1101 
1102  eT val;
1103 
1104  for(uword row=0; (row < x.n_rows) && (load_okay == true); ++row)
1105  {
1106  for(uword col=0; (col < x.n_cols) && (load_okay == true); ++col)
1107  {
1108  f >> val;
1109 
1110  if(f.fail() == false)
1111  {
1112  x.at(row,col) = val;
1113  }
1114  else
1115  {
1116  load_okay = false;
1117  err_msg = "couldn't interpret data in ";
1118  //break;
1119  }
1120  }
1121  }
1122  }
1123 
1124 
1125  // an empty file indicates an empty matrix
1126  if( (f_n_cols_found == false) && (load_okay == true) )
1127  {
1128  x.reset();
1129  }
1130 
1131 
1132  return load_okay;
1133  }
1134 
1135 
1136 
1139 template<typename eT>
1140 inline
1141 bool
1142 diskio::load_raw_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
1143  {
1145 
1146  std::ifstream f;
1147  f.open(name.c_str(), std::fstream::binary);
1148 
1149  bool load_okay = f.is_open();
1150 
1151  if(load_okay == true)
1152  {
1153  load_okay = diskio::load_raw_binary(x, f, err_msg);
1154  f.close();
1155  }
1156 
1157  return load_okay;
1158  }
1159 
1160 
1161 
1162 template<typename eT>
1163 inline
1164 bool
1165 diskio::load_raw_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
1166  {
1168  arma_ignore(err_msg);
1169 
1170  f.clear();
1171  const std::streampos pos1 = f.tellg();
1172 
1173  f.clear();
1174  f.seekg(0, ios::end);
1175 
1176  f.clear();
1177  const std::streampos pos2 = f.tellg();
1178 
1179  const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
1180 
1181  f.clear();
1182  //f.seekg(0, ios::beg);
1183  f.seekg(pos1);
1184 
1185  x.set_size(N / sizeof(eT), 1);
1186 
1187  f.clear();
1188  f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
1189 
1190  return f.good();
1191  }
1192 
1193 
1194 
1197 template<typename eT>
1198 inline
1199 bool
1200 diskio::load_arma_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
1201  {
1203 
1204  std::ifstream f(name.c_str());
1205 
1206  bool load_okay = f.is_open();
1207 
1208  if(load_okay == true)
1209  {
1210  load_okay = diskio::load_arma_ascii(x, f, err_msg);
1211  f.close();
1212  }
1213 
1214  return load_okay;
1215  }
1216 
1217 
1218 
1221 template<typename eT>
1222 inline
1223 bool
1224 diskio::load_arma_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
1225  {
1227 
1228  bool load_okay = true;
1229 
1230  std::string f_header;
1231  uword f_n_rows;
1232  uword f_n_cols;
1233 
1234  f >> f_header;
1235  f >> f_n_rows;
1236  f >> f_n_cols;
1237 
1238  if(f_header == diskio::gen_txt_header(x))
1239  {
1240  x.set_size(f_n_rows, f_n_cols);
1241 
1242  for(uword row=0; row < x.n_rows; ++row)
1243  {
1244  for(uword col=0; col < x.n_cols; ++col)
1245  {
1246  f >> x.at(row,col);
1247  }
1248  }
1249 
1250  load_okay = f.good();
1251  }
1252  else
1253  {
1254  load_okay = false;
1255  err_msg = "incorrect header in ";
1256  }
1257 
1258  return load_okay;
1259  }
1260 
1261 
1262 
1264 template<typename eT>
1265 inline
1266 bool
1267 diskio::load_csv_ascii(Mat<eT>& x, const std::string& name, std::string& err_msg)
1268  {
1270 
1271  std::fstream f;
1272  f.open(name.c_str(), std::fstream::in);
1273 
1274  bool load_okay = f.is_open();
1275 
1276  if(load_okay == true)
1277  {
1278  load_okay = diskio::load_csv_ascii(x, f, err_msg);
1279  f.close();
1280  }
1281 
1282  return load_okay;
1283  }
1284 
1285 
1286 
1288 template<typename eT>
1289 inline
1290 bool
1291 diskio::load_csv_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg)
1292  {
1294 
1295  bool load_okay = f.good();
1296 
1297  f.clear();
1298  const std::fstream::pos_type pos1 = f.tellg();
1299 
1300  //
1301  // work out the size
1302 
1303  uword f_n_rows = 0;
1304  uword f_n_cols = 0;
1305 
1306  std::string line_string;
1307  std::string token;
1308 
1309  while( (f.good() == true) && (load_okay == true) )
1310  {
1311  std::getline(f, line_string);
1312 
1313  if(line_string.size() == 0)
1314  {
1315  break;
1316  }
1317 
1318  std::stringstream line_stream(line_string);
1319 
1320  uword line_n_cols = 0;
1321 
1322  while(line_stream.good() == true)
1323  {
1324  getline(line_stream, token, ',');
1325  ++line_n_cols;
1326  }
1327 
1328  if(f_n_cols < line_n_cols)
1329  {
1330  f_n_cols = line_n_cols;
1331  }
1332 
1333  ++f_n_rows;
1334  }
1335 
1336  f.clear();
1337  f.seekg(pos1);
1338 
1339  x.zeros(f_n_rows, f_n_cols);
1340 
1341  uword row = 0;
1342 
1343  while(f.good() == true)
1344  {
1345  std::getline(f, line_string);
1346 
1347  if(line_string.size() == 0)
1348  {
1349  break;
1350  }
1351 
1352  std::stringstream line_stream(line_string);
1353 
1354  uword col = 0;
1355 
1356  while(line_stream.good() == true)
1357  {
1358  getline(line_stream, token, ',');
1359 
1360  eT val;
1361 
1362  std::stringstream ss(token);
1363 
1364  ss >> val;
1365 
1366  if(ss.fail() == false)
1367  {
1368  x.at(row,col) = val;
1369  }
1370 
1371  ++col;
1372  }
1373 
1374  ++row;
1375  }
1376 
1377  return load_okay;
1378  }
1379 
1380 
1381 
1384 template<typename eT>
1385 inline
1386 bool
1387 diskio::load_arma_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
1388  {
1390 
1391  std::ifstream f;
1392  f.open(name.c_str(), std::fstream::binary);
1393 
1394  bool load_okay = f.is_open();
1395 
1396  if(load_okay == true)
1397  {
1398  load_okay = diskio::load_arma_binary(x, f, err_msg);
1399  f.close();
1400  }
1401 
1402  return load_okay;
1403  }
1404 
1405 
1406 
1407 template<typename eT>
1408 inline
1409 bool
1410 diskio::load_arma_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
1411  {
1413 
1414  bool load_okay = true;
1415 
1416  std::string f_header;
1417  uword f_n_rows;
1418  uword f_n_cols;
1419 
1420  f >> f_header;
1421  f >> f_n_rows;
1422  f >> f_n_cols;
1423 
1424  if(f_header == diskio::gen_bin_header(x))
1425  {
1426  //f.seekg(1, ios::cur); // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
1427  f.get();
1428 
1429  x.set_size(f_n_rows,f_n_cols);
1430  f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
1431 
1432  load_okay = f.good();
1433  }
1434  else
1435  {
1436  load_okay = false;
1437  err_msg = "incorrect header in ";
1438  }
1439 
1440  return load_okay;
1441  }
1442 
1443 
1444 
1445 inline
1446 void
1448  {
1449  while( isspace(f.peek()) )
1450  {
1451  while( isspace(f.peek()) )
1452  {
1453  f.get();
1454  }
1455 
1456  if(f.peek() == '#')
1457  {
1458  while( (f.peek() != '\r') && (f.peek()!='\n') )
1459  {
1460  f.get();
1461  }
1462  }
1463  }
1464  }
1465 
1466 
1467 
1469 template<typename eT>
1470 inline
1471 bool
1472 diskio::load_pgm_binary(Mat<eT>& x, const std::string& name, std::string& err_msg)
1473  {
1475 
1476  std::fstream f;
1477  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
1478 
1479  bool load_okay = f.is_open();
1480 
1481  if(load_okay == true)
1482  {
1483  load_okay = diskio::load_pgm_binary(x, f, err_msg);
1484  f.close();
1485  }
1486 
1487  return load_okay;
1488  }
1489 
1490 
1491 
1493 template<typename eT>
1494 inline
1495 bool
1496 diskio::load_pgm_binary(Mat<eT>& x, std::istream& f, std::string& err_msg)
1497  {
1498  bool load_okay = true;
1499 
1500  std::string f_header;
1501  f >> f_header;
1502 
1503  if(f_header == "P5")
1504  {
1505  uword f_n_rows = 0;
1506  uword f_n_cols = 0;
1507  int f_maxval = 0;
1508 
1510 
1511  f >> f_n_cols;
1513 
1514  f >> f_n_rows;
1516 
1517  f >> f_maxval;
1518  f.get();
1519 
1520  if( (f_maxval > 0) || (f_maxval <= 65535) )
1521  {
1522  x.set_size(f_n_rows,f_n_cols);
1523 
1524  if(f_maxval <= 255)
1525  {
1526  const uword n_elem = f_n_cols*f_n_rows;
1527  podarray<u8> tmp(n_elem);
1528 
1529  f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
1530 
1531  uword i = 0;
1532 
1533  //cout << "f_n_cols = " << f_n_cols << endl;
1534  //cout << "f_n_rows = " << f_n_rows << endl;
1535 
1536 
1537  for(uword row=0; row < f_n_rows; ++row)
1538  {
1539  for(uword col=0; col < f_n_cols; ++col)
1540  {
1541  x.at(row,col) = eT(tmp[i]);
1542  ++i;
1543  }
1544  }
1545 
1546  }
1547  else
1548  {
1549  const uword n_elem = f_n_cols*f_n_rows;
1550  podarray<u16> tmp(n_elem);
1551 
1552  f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(n_elem*2) );
1553 
1554  uword i = 0;
1555 
1556  for(uword row=0; row < f_n_rows; ++row)
1557  {
1558  for(uword col=0; col < f_n_cols; ++col)
1559  {
1560  x.at(row,col) = eT(tmp[i]);
1561  ++i;
1562  }
1563  }
1564 
1565  }
1566 
1567  }
1568  else
1569  {
1570  load_okay = false;
1571  err_msg = "currently no code available to handle loading ";
1572  }
1573 
1574  if(f.good() == false)
1575  {
1576  load_okay = false;
1577  }
1578  }
1579  else
1580  {
1581  load_okay = false;
1582  err_msg = "unsupported header in ";
1583  }
1584 
1585  return load_okay;
1586  }
1587 
1588 
1589 
1591 template<typename T>
1592 inline
1593 bool
1594 diskio::load_pgm_binary(Mat< std::complex<T> >& x, const std::string& name, std::string& err_msg)
1595  {
1597 
1598  uchar_mat tmp;
1599  const bool load_okay = diskio::load_pgm_binary(tmp, name, err_msg);
1600 
1601  x = conv_to< Mat< std::complex<T> > >::from(tmp);
1602 
1603  return load_okay;
1604  }
1605 
1606 
1607 
1609 template<typename T>
1610 inline
1611 bool
1612 diskio::load_pgm_binary(Mat< std::complex<T> >& x, std::istream& is, std::string& err_msg)
1613  {
1615 
1616  uchar_mat tmp;
1617  const bool load_okay = diskio::load_pgm_binary(tmp, is, err_msg);
1618 
1619  x = conv_to< Mat< std::complex<T> > >::from(tmp);
1620 
1621  return load_okay;
1622  }
1623 
1624 
1625 
1627 template<typename eT>
1628 inline
1629 bool
1630 diskio::load_auto_detect(Mat<eT>& x, const std::string& name, std::string& err_msg)
1631  {
1633 
1634  std::fstream f;
1635  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
1636 
1637  bool load_okay = f.is_open();
1638 
1639  if(load_okay == true)
1640  {
1641  load_okay = diskio::load_auto_detect(x, f, err_msg);
1642  f.close();
1643  }
1644 
1645  return load_okay;
1646  }
1647 
1648 
1649 
1651 template<typename eT>
1652 inline
1653 bool
1654 diskio::load_auto_detect(Mat<eT>& x, std::istream& f, std::string& err_msg)
1655  {
1657 
1658  static const std::string ARMA_MAT_TXT = "ARMA_MAT_TXT";
1659  static const std::string ARMA_MAT_BIN = "ARMA_MAT_BIN";
1660  static const std::string P5 = "P5";
1661 
1662  podarray<char> raw_header(ARMA_MAT_TXT.length() + 1);
1663 
1664  std::streampos pos = f.tellg();
1665 
1666  f.read( raw_header.memptr(), std::streamsize(ARMA_MAT_TXT.length()) );
1667  raw_header[ARMA_MAT_TXT.length()] = '\0';
1668 
1669  f.clear();
1670  f.seekg(pos);
1671 
1672  const std::string header = raw_header.mem;
1673 
1674  if(ARMA_MAT_TXT == header.substr(0,ARMA_MAT_TXT.length()))
1675  {
1676  return load_arma_ascii(x, f, err_msg);
1677  }
1678  else
1679  if(ARMA_MAT_BIN == header.substr(0,ARMA_MAT_BIN.length()))
1680  {
1681  return load_arma_binary(x, f, err_msg);
1682  }
1683  else
1684  if(P5 == header.substr(0,P5.length()))
1685  {
1686  return load_pgm_binary(x, f, err_msg);
1687  }
1688  else
1689  {
1690  const file_type ft = guess_file_type(f);
1691 
1692  switch(ft)
1693  {
1694  case csv_ascii:
1695  return load_csv_ascii(x, f, err_msg);
1696  break;
1697 
1698  case raw_binary:
1699  return load_raw_binary(x, f, err_msg);
1700  break;
1701 
1702  case raw_ascii:
1703  return load_raw_ascii(x, f, err_msg);
1704  break;
1705 
1706  default:
1707  err_msg = "unknown data in ";
1708  return false;
1709  }
1710  }
1711 
1712  return false;
1713  }
1714 
1715 
1716 
1717 // cubes
1718 
1719 
1720 
1722 template<typename eT>
1723 inline
1724 bool
1725 diskio::save_raw_ascii(const Cube<eT>& x, const std::string& final_name)
1726  {
1728 
1729  const std::string tmp_name = diskio::gen_tmp_name(final_name);
1730 
1731  std::fstream f(tmp_name.c_str(), std::fstream::out);
1732 
1733  bool save_okay = f.is_open();
1734 
1735  if(save_okay == true)
1736  {
1737  save_okay = save_raw_ascii(x, f);
1738 
1739  f.flush();
1740  f.close();
1741 
1742  if(save_okay == true)
1743  {
1744  save_okay = diskio::safe_rename(tmp_name, final_name);
1745  }
1746  }
1747 
1748  return save_okay;
1749  }
1750 
1751 
1752 
1754 template<typename eT>
1755 inline
1756 bool
1757 diskio::save_raw_ascii(const Cube<eT>& x, std::ostream& f)
1758  {
1760 
1761  uword cell_width;
1762 
1763  // TODO: need sane values for complex numbers
1764 
1765  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
1766  {
1767  f.setf(ios::scientific);
1768  f.precision(10);
1769  cell_width = 18;
1770  }
1771 
1772  for(uword slice=0; slice < x.n_slices; ++slice)
1773  {
1774  for(uword row=0; row < x.n_rows; ++row)
1775  {
1776  for(uword col=0; col < x.n_cols; ++col)
1777  {
1778  f.put(' ');
1779 
1780  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
1781  {
1782  f.width(cell_width);
1783  }
1784 
1785  f << x.at(row,col,slice);
1786  }
1787 
1788  f.put('\n');
1789  }
1790  }
1791 
1792  return f.good();
1793  }
1794 
1795 
1796 
1798 template<typename eT>
1799 inline
1800 bool
1801 diskio::save_raw_binary(const Cube<eT>& x, const std::string& final_name)
1802  {
1804 
1805  const std::string tmp_name = diskio::gen_tmp_name(final_name);
1806 
1807  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
1808 
1809  bool save_okay = f.is_open();
1810 
1811  if(save_okay == true)
1812  {
1813  save_okay = diskio::save_raw_binary(x, f);
1814 
1815  f.flush();
1816  f.close();
1817 
1818  if(save_okay == true)
1819  {
1820  save_okay = diskio::safe_rename(tmp_name, final_name);
1821  }
1822  }
1823 
1824  return save_okay;
1825  }
1826 
1827 
1828 
1829 template<typename eT>
1830 inline
1831 bool
1832 diskio::save_raw_binary(const Cube<eT>& x, std::ostream& f)
1833  {
1835 
1836  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
1837 
1838  return f.good();
1839  }
1840 
1841 
1842 
1845 template<typename eT>
1846 inline
1847 bool
1848 diskio::save_arma_ascii(const Cube<eT>& x, const std::string& final_name)
1849  {
1851 
1852  const std::string tmp_name = diskio::gen_tmp_name(final_name);
1853 
1854  std::ofstream f(tmp_name.c_str());
1855 
1856  bool save_okay = f.is_open();
1857 
1858  if(save_okay == true)
1859  {
1860  save_okay = diskio::save_arma_ascii(x, f);
1861 
1862  f.flush();
1863  f.close();
1864 
1865  if(save_okay == true)
1866  {
1867  save_okay = diskio::safe_rename(tmp_name, final_name);
1868  }
1869  }
1870 
1871  return save_okay;
1872  }
1873 
1874 
1875 
1878 template<typename eT>
1879 inline
1880 bool
1881 diskio::save_arma_ascii(const Cube<eT>& x, std::ostream& f)
1882  {
1884 
1885  const ios::fmtflags orig_flags = f.flags();
1886 
1887  f << diskio::gen_txt_header(x) << '\n';
1888  f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
1889 
1890  uword cell_width;
1891 
1892  // TODO: need sane values for complex numbers
1893 
1894  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
1895  {
1896  f.setf(ios::scientific);
1897  f.precision(10);
1898  cell_width = 18;
1899  }
1900 
1901  for(uword slice=0; slice < x.n_slices; ++slice)
1902  {
1903  for(uword row=0; row < x.n_rows; ++row)
1904  {
1905  for(uword col=0; col < x.n_cols; ++col)
1906  {
1907  f.put(' ');
1908 
1909  if( (is_float<eT>::value == true) || (is_double<eT>::value == true) )
1910  {
1911  f.width(cell_width);
1912  }
1913 
1914  f << x.at(row,col,slice);
1915  }
1916 
1917  f.put('\n');
1918  }
1919  }
1920 
1921  const bool save_okay = f.good();
1922 
1923  f.flags(orig_flags);
1924 
1925  return save_okay;
1926  }
1927 
1928 
1929 
1932 template<typename eT>
1933 inline
1934 bool
1935 diskio::save_arma_binary(const Cube<eT>& x, const std::string& final_name)
1936  {
1938 
1939  const std::string tmp_name = diskio::gen_tmp_name(final_name);
1940 
1941  std::ofstream f(tmp_name.c_str(), std::fstream::binary);
1942 
1943  bool save_okay = f.is_open();
1944 
1945  if(save_okay == true)
1946  {
1947  save_okay = diskio::save_arma_binary(x, f);
1948 
1949  f.flush();
1950  f.close();
1951 
1952  if(save_okay == true)
1953  {
1954  save_okay = diskio::safe_rename(tmp_name, final_name);
1955  }
1956  }
1957 
1958  return save_okay;
1959  }
1960 
1961 
1962 
1965 template<typename eT>
1966 inline
1967 bool
1968 diskio::save_arma_binary(const Cube<eT>& x, std::ostream& f)
1969  {
1971 
1972  f << diskio::gen_bin_header(x) << '\n';
1973  f << x.n_rows << ' ' << x.n_cols << ' ' << x.n_slices << '\n';
1974 
1975  f.write( reinterpret_cast<const char*>(x.mem), std::streamsize(x.n_elem*sizeof(eT)) );
1976 
1977  return f.good();
1978  }
1979 
1980 
1981 
1984 template<typename eT>
1985 inline
1986 bool
1987 diskio::load_raw_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
1988  {
1990 
1991  Mat<eT> tmp;
1992  const bool load_okay = diskio::load_raw_ascii(tmp, name, err_msg);
1993 
1994  if(load_okay == true)
1995  {
1996  if(tmp.is_empty() == false)
1997  {
1998  x.set_size(tmp.n_rows, tmp.n_cols, 1);
1999 
2000  x.slice(0) = tmp;
2001  }
2002  else
2003  {
2004  x.reset();
2005  }
2006  }
2007 
2008  return load_okay;
2009  }
2010 
2011 
2012 
2015 template<typename eT>
2016 inline
2017 bool
2018 diskio::load_raw_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
2019  {
2021 
2022  Mat<eT> tmp;
2023  const bool load_okay = diskio::load_raw_ascii(tmp, f, err_msg);
2024 
2025  if(load_okay == true)
2026  {
2027  if(tmp.is_empty() == false)
2028  {
2029  x.set_size(tmp.n_rows, tmp.n_cols, 1);
2030 
2031  x.slice(0) = tmp;
2032  }
2033  else
2034  {
2035  x.reset();
2036  }
2037  }
2038 
2039  return load_okay;
2040  }
2041 
2042 
2043 
2046 template<typename eT>
2047 inline
2048 bool
2049 diskio::load_raw_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
2050  {
2052 
2053  std::ifstream f;
2054  f.open(name.c_str(), std::fstream::binary);
2055 
2056  bool load_okay = f.is_open();
2057 
2058  if(load_okay == true)
2059  {
2060  load_okay = diskio::load_raw_binary(x, f, err_msg);
2061  f.close();
2062  }
2063 
2064  return load_okay;
2065  }
2066 
2067 
2068 
2069 template<typename eT>
2070 inline
2071 bool
2072 diskio::load_raw_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
2073  {
2075  arma_ignore(err_msg);
2076 
2077  f.clear();
2078  const std::streampos pos1 = f.tellg();
2079 
2080  f.clear();
2081  f.seekg(0, ios::end);
2082 
2083  f.clear();
2084  const std::streampos pos2 = f.tellg();
2085 
2086  const uword N = ( (pos1 >= 0) && (pos2 >= 0) ) ? uword(pos2 - pos1) : 0;
2087 
2088  f.clear();
2089  //f.seekg(0, ios::beg);
2090  f.seekg(pos1);
2091 
2092  x.set_size(N / sizeof(eT), 1, 1);
2093 
2094  f.clear();
2095  f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(N) );
2096 
2097  return f.good();
2098  }
2099 
2100 
2101 
2104 template<typename eT>
2105 inline
2106 bool
2107 diskio::load_arma_ascii(Cube<eT>& x, const std::string& name, std::string& err_msg)
2108  {
2110 
2111  std::ifstream f(name.c_str());
2112 
2113  bool load_okay = f.is_open();
2114 
2115  if(load_okay == true)
2116  {
2117  load_okay = diskio::load_arma_ascii(x, f, err_msg);
2118  f.close();
2119  }
2120 
2121  return load_okay;
2122  }
2123 
2124 
2125 
2128 template<typename eT>
2129 inline
2130 bool
2131 diskio::load_arma_ascii(Cube<eT>& x, std::istream& f, std::string& err_msg)
2132  {
2134 
2135  bool load_okay = true;
2136 
2137  std::string f_header;
2138  uword f_n_rows;
2139  uword f_n_cols;
2140  uword f_n_slices;
2141 
2142  f >> f_header;
2143  f >> f_n_rows;
2144  f >> f_n_cols;
2145  f >> f_n_slices;
2146 
2147  if(f_header == diskio::gen_txt_header(x))
2148  {
2149  x.set_size(f_n_rows, f_n_cols, f_n_slices);
2150 
2151  for(uword slice=0; slice < x.n_slices; ++slice)
2152  {
2153  for(uword row=0; row < x.n_rows; ++row)
2154  {
2155  for(uword col=0; col < x.n_cols; ++col)
2156  {
2157  f >> x.at(row,col,slice);
2158  }
2159  }
2160  }
2161 
2162  load_okay = f.good();
2163  }
2164  else
2165  {
2166  load_okay = false;
2167  err_msg = "incorrect header in ";
2168  }
2169 
2170  return load_okay;
2171  }
2172 
2173 
2174 
2177 template<typename eT>
2178 inline
2179 bool
2180 diskio::load_arma_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
2181  {
2183 
2184  std::ifstream f;
2185  f.open(name.c_str(), std::fstream::binary);
2186 
2187  bool load_okay = f.is_open();
2188 
2189  if(load_okay == true)
2190  {
2191  load_okay = diskio::load_arma_binary(x, f, err_msg);
2192  f.close();
2193  }
2194 
2195  return load_okay;
2196  }
2197 
2198 
2199 
2200 template<typename eT>
2201 inline
2202 bool
2203 diskio::load_arma_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
2204  {
2206 
2207  bool load_okay = true;
2208 
2209  std::string f_header;
2210  uword f_n_rows;
2211  uword f_n_cols;
2212  uword f_n_slices;
2213 
2214  f >> f_header;
2215  f >> f_n_rows;
2216  f >> f_n_cols;
2217  f >> f_n_slices;
2218 
2219  if(f_header == diskio::gen_bin_header(x))
2220  {
2221  //f.seekg(1, ios::cur); // NOTE: this may not be portable, as on a Windows machine a newline could be two characters
2222  f.get();
2223 
2224  x.set_size(f_n_rows, f_n_cols, f_n_slices);
2225  f.read( reinterpret_cast<char *>(x.memptr()), std::streamsize(x.n_elem*sizeof(eT)) );
2226 
2227  load_okay = f.good();
2228  }
2229  else
2230  {
2231  load_okay = false;
2232  err_msg = "incorrect header in ";
2233  }
2234 
2235  return load_okay;
2236  }
2237 
2238 
2239 
2241 template<typename eT>
2242 inline
2243 bool
2244 diskio::load_auto_detect(Cube<eT>& x, const std::string& name, std::string& err_msg)
2245  {
2247 
2248  std::fstream f;
2249  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
2250 
2251  bool load_okay = f.is_open();
2252 
2253  if(load_okay == true)
2254  {
2255  load_okay = diskio::load_auto_detect(x, f, err_msg);
2256  f.close();
2257  }
2258 
2259  return load_okay;
2260  }
2261 
2262 
2263 
2265 template<typename eT>
2266 inline
2267 bool
2268 diskio::load_auto_detect(Cube<eT>& x, std::istream& f, std::string& err_msg)
2269  {
2271 
2272  static const std::string ARMA_CUB_TXT = "ARMA_CUB_TXT";
2273  static const std::string ARMA_CUB_BIN = "ARMA_CUB_BIN";
2274  static const std::string P6 = "P6";
2275 
2276  podarray<char> raw_header(ARMA_CUB_TXT.length() + 1);
2277 
2278  std::streampos pos = f.tellg();
2279 
2280  f.read( raw_header.memptr(), std::streamsize(ARMA_CUB_TXT.length()) );
2281  raw_header[ARMA_CUB_TXT.length()] = '\0';
2282 
2283  f.clear();
2284  f.seekg(pos);
2285 
2286  const std::string header = raw_header.mem;
2287 
2288  if(ARMA_CUB_TXT == header.substr(0, ARMA_CUB_TXT.length()))
2289  {
2290  return load_arma_ascii(x, f, err_msg);
2291  }
2292  else
2293  if(ARMA_CUB_BIN == header.substr(0, ARMA_CUB_BIN.length()))
2294  {
2295  return load_arma_binary(x, f, err_msg);
2296  }
2297  else
2298  if(P6 == header.substr(0, P6.length()))
2299  {
2300  return load_ppm_binary(x, f, err_msg);
2301  }
2302  else
2303  {
2304  const file_type ft = guess_file_type(f);
2305 
2306  switch(ft)
2307  {
2308  // case csv_ascii:
2309  // return load_csv_ascii(x, f, err_msg);
2310  // break;
2311 
2312  case raw_binary:
2313  return load_raw_binary(x, f, err_msg);
2314  break;
2315 
2316  case raw_ascii:
2317  return load_raw_ascii(x, f, err_msg);
2318  break;
2319 
2320  default:
2321  err_msg = "unknown data in ";
2322  return false;
2323  }
2324  }
2325 
2326  return false;
2327  }
2328 
2329 
2330 
2331 
2332 
2333 // fields
2334 
2335 
2336 
2337 template<typename T1>
2338 inline
2339 bool
2340 diskio::save_arma_binary(const field<T1>& x, const std::string& final_name)
2341  {
2343 
2344  const std::string tmp_name = diskio::gen_tmp_name(final_name);
2345 
2346  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
2347 
2348  bool save_okay = f.is_open();
2349 
2350  if(save_okay == true)
2351  {
2352  save_okay = diskio::save_arma_binary(x, f);
2353 
2354  f.flush();
2355  f.close();
2356 
2357  if(save_okay == true)
2358  {
2359  save_okay = diskio::safe_rename(tmp_name, final_name);
2360  }
2361  }
2362 
2363  return save_okay;
2364  }
2365 
2366 
2367 
2368 template<typename T1>
2369 inline
2370 bool
2371 diskio::save_arma_binary(const field<T1>& x, std::ostream& f)
2372  {
2374 
2375  arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
2376 
2377  f << "ARMA_FLD_BIN" << '\n';
2378  f << x.n_rows << '\n';
2379  f << x.n_cols << '\n';
2380 
2381  bool save_okay = true;
2382 
2383  for(uword i=0; i<x.n_elem; ++i)
2384  {
2385  save_okay = diskio::save_arma_binary(x[i], f);
2386 
2387  if(save_okay == false)
2388  {
2389  break;
2390  }
2391  }
2392 
2393  return save_okay;
2394  }
2395 
2396 
2397 
2398 template<typename T1>
2399 inline
2400 bool
2401 diskio::load_arma_binary(field<T1>& x, const std::string& name, std::string& err_msg)
2402  {
2404 
2405  std::ifstream f( name.c_str(), std::fstream::binary );
2406 
2407  bool load_okay = f.is_open();
2408 
2409  if(load_okay == true)
2410  {
2411  load_okay = diskio::load_arma_binary(x, f, err_msg);
2412  f.close();
2413  }
2414 
2415  return load_okay;
2416  }
2417 
2418 
2419 
2420 template<typename T1>
2421 inline
2422 bool
2423 diskio::load_arma_binary(field<T1>& x, std::istream& f, std::string& err_msg)
2424  {
2426 
2427  arma_type_check(( (is_Mat<T1>::value == false) && (is_Cube<T1>::value == false) ));
2428 
2429  bool load_okay = true;
2430 
2431  std::string f_type;
2432  f >> f_type;
2433 
2434  if(f_type != "ARMA_FLD_BIN")
2435  {
2436  load_okay = false;
2437  err_msg = "unsupported field type in ";
2438  }
2439  else
2440  {
2441  uword f_n_rows;
2442  uword f_n_cols;
2443 
2444  f >> f_n_rows;
2445  f >> f_n_cols;
2446 
2447  x.set_size(f_n_rows, f_n_cols);
2448 
2449  f.get();
2450 
2451  for(uword i=0; i<x.n_elem; ++i)
2452  {
2453  load_okay = diskio::load_arma_binary(x[i], f, err_msg);
2454 
2455  if(load_okay == false)
2456  {
2457  break;
2458  }
2459  }
2460  }
2461 
2462  return load_okay;
2463  }
2464 
2465 
2466 
2467 inline
2468 bool
2469 diskio::save_std_string(const field<std::string>& x, const std::string& final_name)
2470  {
2472 
2473  const std::string tmp_name = diskio::gen_tmp_name(final_name);
2474 
2475  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
2476 
2477  bool save_okay = f.is_open();
2478 
2479  if(save_okay == true)
2480  {
2481  save_okay = diskio::save_std_string(x, f);
2482 
2483  f.flush();
2484  f.close();
2485 
2486  if(save_okay == true)
2487  {
2488  save_okay = diskio::safe_rename(tmp_name, final_name);
2489  }
2490  }
2491 
2492  return save_okay;
2493  }
2494 
2495 
2496 
2497 inline
2498 bool
2500  {
2502 
2503  for(uword row=0; row<x.n_rows; ++row)
2504  for(uword col=0; col<x.n_cols; ++col)
2505  {
2506  f << x.at(row,col);
2507 
2508  if(col < x.n_cols-1)
2509  {
2510  f << ' ';
2511  }
2512  else
2513  {
2514  f << '\n';
2515  }
2516  }
2517 
2518  return f.good();
2519  }
2520 
2521 
2522 
2523 inline
2524 bool
2525 diskio::load_std_string(field<std::string>& x, const std::string& name, std::string& err_msg)
2526  {
2528 
2529  std::ifstream f( name.c_str() );
2530 
2531  bool load_okay = f.is_open();
2532 
2533  if(load_okay == true)
2534  {
2535  load_okay = diskio::load_std_string(x, f, err_msg);
2536  f.close();
2537  }
2538 
2539  return load_okay;
2540  }
2541 
2542 
2543 
2544 inline
2545 bool
2546 diskio::load_std_string(field<std::string>& x, std::istream& f, std::string& err_msg)
2547  {
2549 
2550  bool load_okay = true;
2551 
2552  //
2553  // work out the size
2554 
2555  uword f_n_rows = 0;
2556  uword f_n_cols = 0;
2557 
2558  bool f_n_cols_found = false;
2559 
2560  std::string line_string;
2561  std::string token;
2562 
2563  while( (f.good() == true) && (load_okay == true) )
2564  {
2565  std::getline(f, line_string);
2566  if(line_string.size() == 0)
2567  break;
2568 
2569  std::stringstream line_stream(line_string);
2570 
2571  uword line_n_cols = 0;
2572  while (line_stream >> token)
2573  line_n_cols++;
2574 
2575  if(f_n_cols_found == false)
2576  {
2577  f_n_cols = line_n_cols;
2578  f_n_cols_found = true;
2579  }
2580  else
2581  {
2582  if(line_n_cols != f_n_cols)
2583  {
2584  load_okay = false;
2585  err_msg = "inconsistent number of columns in ";
2586  }
2587  }
2588 
2589  ++f_n_rows;
2590  }
2591 
2592  if(load_okay == true)
2593  {
2594  f.clear();
2595  f.seekg(0, ios::beg);
2596  //f.seekg(start);
2597 
2598  x.set_size(f_n_rows, f_n_cols);
2599 
2600  for(uword row=0; row < x.n_rows; ++row)
2601  {
2602  for(uword col=0; col < x.n_cols; ++col)
2603  {
2604  f >> x.at(row,col);
2605  }
2606  }
2607  }
2608 
2609  if(f.good() == false)
2610  {
2611  load_okay = false;
2612  }
2613 
2614  return load_okay;
2615  }
2616 
2617 
2618 
2620 template<typename T1>
2621 inline
2622 bool
2623 diskio::load_auto_detect(field<T1>& x, const std::string& name, std::string& err_msg)
2624  {
2626 
2627  std::fstream f;
2628  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
2629 
2630  bool load_okay = f.is_open();
2631 
2632  if(load_okay == true)
2633  {
2634  load_okay = diskio::load_auto_detect(x, f, err_msg);
2635  f.close();
2636  }
2637 
2638  return load_okay;
2639  }
2640 
2641 
2642 
2644 template<typename T1>
2645 inline
2646 bool
2647 diskio::load_auto_detect(field<T1>& x, std::istream& f, std::string& err_msg)
2648  {
2650 
2651  arma_type_check(( is_Mat<T1>::value == false ));
2652 
2653  static const std::string ARMA_FLD_BIN = "ARMA_FLD_BIN";
2654  static const std::string P6 = "P6";
2655 
2656  podarray<char> raw_header(ARMA_FLD_BIN.length() + 1);
2657 
2658  std::streampos pos = f.tellg();
2659 
2660  f.read( raw_header.memptr(), std::streamsize(ARMA_FLD_BIN.length()) );
2661 
2662  f.clear();
2663  f.seekg(pos);
2664 
2665  raw_header[ARMA_FLD_BIN.length()] = '\0';
2666 
2667  const std::string header = raw_header.mem;
2668 
2669  if(ARMA_FLD_BIN == header.substr(0, ARMA_FLD_BIN.length()))
2670  {
2671  return load_arma_binary(x, f, err_msg);
2672  }
2673  else
2674  if(P6 == header.substr(0, P6.length()))
2675  {
2676  return load_ppm_binary(x, f, err_msg);
2677  }
2678  else
2679  {
2680  err_msg = "unsupported header in ";
2681  return false;
2682  }
2683  }
2684 
2685 
2686 
2687 //
2688 // handling of PPM images by cubes
2689 
2690 
2691 template<typename eT>
2692 inline
2693 bool
2694 diskio::load_ppm_binary(Cube<eT>& x, const std::string& name, std::string& err_msg)
2695  {
2697 
2698  std::fstream f;
2699  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
2700 
2701  bool load_okay = f.is_open();
2702 
2703  if(load_okay == true)
2704  {
2705  load_okay = diskio::load_ppm_binary(x, f, err_msg);
2706  f.close();
2707  }
2708 
2709  return load_okay;
2710  }
2711 
2712 
2713 
2714 template<typename eT>
2715 inline
2716 bool
2717 diskio::load_ppm_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
2718  {
2720 
2721  bool load_okay = true;
2722 
2723  std::string f_header;
2724  f >> f_header;
2725 
2726  if(f_header == "P6")
2727  {
2728  uword f_n_rows = 0;
2729  uword f_n_cols = 0;
2730  int f_maxval = 0;
2731 
2733 
2734  f >> f_n_cols;
2736 
2737  f >> f_n_rows;
2739 
2740  f >> f_maxval;
2741  f.get();
2742 
2743  if( (f_maxval > 0) || (f_maxval <= 65535) )
2744  {
2745  x.set_size(f_n_rows, f_n_cols, 3);
2746 
2747  if(f_maxval <= 255)
2748  {
2749  const uword n_elem = 3*f_n_cols*f_n_rows;
2750  podarray<u8> tmp(n_elem);
2751 
2752  f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
2753 
2754  uword i = 0;
2755 
2756  //cout << "f_n_cols = " << f_n_cols << endl;
2757  //cout << "f_n_rows = " << f_n_rows << endl;
2758 
2759 
2760  for(uword row=0; row < f_n_rows; ++row)
2761  {
2762  for(uword col=0; col < f_n_cols; ++col)
2763  {
2764  x.at(row,col,0) = eT(tmp[i+0]);
2765  x.at(row,col,1) = eT(tmp[i+1]);
2766  x.at(row,col,2) = eT(tmp[i+2]);
2767  i+=3;
2768  }
2769 
2770  }
2771  }
2772  else
2773  {
2774  const uword n_elem = 3*f_n_cols*f_n_rows;
2775  podarray<u16> tmp(n_elem);
2776 
2777  f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
2778 
2779  uword i = 0;
2780 
2781  for(uword row=0; row < f_n_rows; ++row)
2782  {
2783  for(uword col=0; col < f_n_cols; ++col)
2784  {
2785  x.at(row,col,0) = eT(tmp[i+0]);
2786  x.at(row,col,1) = eT(tmp[i+1]);
2787  x.at(row,col,2) = eT(tmp[i+2]);
2788  i+=3;
2789  }
2790 
2791  }
2792 
2793  }
2794 
2795  }
2796  else
2797  {
2798  load_okay = false;
2799  err_msg = "currently no code available to handle loading ";
2800  }
2801 
2802  if(f.good() == false)
2803  {
2804  load_okay = false;
2805  }
2806 
2807  }
2808  else
2809  {
2810  load_okay = false;
2811  err_msg = "unsupported header in ";
2812  }
2813 
2814  return load_okay;
2815  }
2816 
2817 
2818 
2819 template<typename eT>
2820 inline
2821 bool
2822 diskio::save_ppm_binary(const Cube<eT>& x, const std::string& final_name)
2823  {
2825 
2826  const std::string tmp_name = diskio::gen_tmp_name(final_name);
2827 
2828  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
2829 
2830  bool save_okay = f.is_open();
2831 
2832  if(save_okay == true)
2833  {
2834  save_okay = diskio::save_ppm_binary(x, f);
2835 
2836  f.flush();
2837  f.close();
2838 
2839  if(save_okay == true)
2840  {
2841  save_okay = diskio::safe_rename(tmp_name, final_name);
2842  }
2843  }
2844 
2845  return save_okay;
2846  }
2847 
2848 
2849 
2850 template<typename eT>
2851 inline
2852 bool
2853 diskio::save_ppm_binary(const Cube<eT>& x, std::ostream& f)
2854  {
2856 
2857  arma_debug_check( (x.n_slices != 3), "diskio::save_ppm_binary(): given cube must have exactly 3 slices" );
2858 
2859  const uword n_elem = 3 * x.n_rows * x.n_cols;
2860  podarray<u8> tmp(n_elem);
2861 
2862  uword i = 0;
2863  for(uword row=0; row < x.n_rows; ++row)
2864  {
2865  for(uword col=0; col < x.n_cols; ++col)
2866  {
2867  tmp[i+0] = u8( access::tmp_real( x.at(row,col,0) ) );
2868  tmp[i+1] = u8( access::tmp_real( x.at(row,col,1) ) );
2869  tmp[i+2] = u8( access::tmp_real( x.at(row,col,2) ) );
2870 
2871  i+=3;
2872  }
2873  }
2874 
2875  f << "P6" << '\n';
2876  f << x.n_cols << '\n';
2877  f << x.n_rows << '\n';
2878  f << 255 << '\n';
2879 
2880  f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
2881 
2882  return f.good();
2883  }
2884 
2885 
2886 
2887 //
2888 // handling of PPM images by fields
2889 
2890 
2891 
2892 template<typename T1>
2893 inline
2894 bool
2895 diskio::load_ppm_binary(field<T1>& x, const std::string& name, std::string& err_msg)
2896  {
2898 
2899  std::fstream f;
2900  f.open(name.c_str(), std::fstream::in | std::fstream::binary);
2901 
2902  bool load_okay = f.is_open();
2903 
2904  if(load_okay == true)
2905  {
2906  load_okay = diskio::load_ppm_binary(x, f, err_msg);
2907  f.close();
2908  }
2909 
2910  return load_okay;
2911  }
2912 
2913 
2914 
2915 template<typename T1>
2916 inline
2917 bool
2918 diskio::load_ppm_binary(field<T1>& x, std::istream& f, std::string& err_msg)
2919  {
2921 
2922  arma_type_check(( is_Mat<T1>::value == false ));
2923  typedef typename T1::elem_type eT;
2924 
2925  bool load_okay = true;
2926 
2927  std::string f_header;
2928  f >> f_header;
2929 
2930  if(f_header == "P6")
2931  {
2932  uword f_n_rows = 0;
2933  uword f_n_cols = 0;
2934  int f_maxval = 0;
2935 
2937 
2938  f >> f_n_cols;
2940 
2941  f >> f_n_rows;
2943 
2944  f >> f_maxval;
2945  f.get();
2946 
2947  if( (f_maxval > 0) || (f_maxval <= 65535) )
2948  {
2949  x.set_size(3);
2950  Mat<eT>& R = x(0);
2951  Mat<eT>& G = x(1);
2952  Mat<eT>& B = x(2);
2953 
2954  R.set_size(f_n_rows,f_n_cols);
2955  G.set_size(f_n_rows,f_n_cols);
2956  B.set_size(f_n_rows,f_n_cols);
2957 
2958  if(f_maxval <= 255)
2959  {
2960  const uword n_elem = 3*f_n_cols*f_n_rows;
2961  podarray<u8> tmp(n_elem);
2962 
2963  f.read( reinterpret_cast<char*>(tmp.memptr()), std::streamsize(n_elem) );
2964 
2965  uword i = 0;
2966 
2967  //cout << "f_n_cols = " << f_n_cols << endl;
2968  //cout << "f_n_rows = " << f_n_rows << endl;
2969 
2970 
2971  for(uword row=0; row < f_n_rows; ++row)
2972  {
2973  for(uword col=0; col < f_n_cols; ++col)
2974  {
2975  R.at(row,col) = eT(tmp[i+0]);
2976  G.at(row,col) = eT(tmp[i+1]);
2977  B.at(row,col) = eT(tmp[i+2]);
2978  i+=3;
2979  }
2980 
2981  }
2982  }
2983  else
2984  {
2985  const uword n_elem = 3*f_n_cols*f_n_rows;
2986  podarray<u16> tmp(n_elem);
2987 
2988  f.read( reinterpret_cast<char *>(tmp.memptr()), std::streamsize(2*n_elem) );
2989 
2990  uword i = 0;
2991 
2992  for(uword row=0; row < f_n_rows; ++row)
2993  {
2994  for(uword col=0; col < f_n_cols; ++col)
2995  {
2996  R.at(row,col) = eT(tmp[i+0]);
2997  G.at(row,col) = eT(tmp[i+1]);
2998  B.at(row,col) = eT(tmp[i+2]);
2999  i+=3;
3000  }
3001 
3002  }
3003 
3004  }
3005 
3006  }
3007  else
3008  {
3009  load_okay = false;
3010  err_msg = "currently no code available to handle loading ";
3011  }
3012 
3013  if(f.good() == false)
3014  {
3015  load_okay = false;
3016  }
3017 
3018  }
3019  else
3020  {
3021  load_okay = false;
3022  err_msg = "unsupported header in ";
3023  }
3024 
3025  return load_okay;
3026  }
3027 
3028 
3029 
3030 template<typename T1>
3031 inline
3032 bool
3033 diskio::save_ppm_binary(const field<T1>& x, const std::string& final_name)
3034  {
3036 
3037  const std::string tmp_name = diskio::gen_tmp_name(final_name);
3038  std::ofstream f( tmp_name.c_str(), std::fstream::binary );
3039 
3040  bool save_okay = f.is_open();
3041 
3042  if(save_okay == true)
3043  {
3044  save_okay = diskio::save_ppm_binary(x, f);
3045 
3046  f.flush();
3047  f.close();
3048 
3049  if(save_okay == true)
3050  {
3051  save_okay = diskio::safe_rename(tmp_name, final_name);
3052  }
3053  }
3054 
3055  return save_okay;
3056  }
3057 
3058 
3059 
3060 template<typename T1>
3061 inline
3062 bool
3063 diskio::save_ppm_binary(const field<T1>& x, std::ostream& f)
3064  {
3066 
3067  arma_type_check(( is_Mat<T1>::value == false ));
3068 
3069  typedef typename T1::elem_type eT;
3070 
3071  arma_debug_check( (x.n_elem != 3), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
3072 
3073  bool same_size = true;
3074  for(uword i=1; i<3; ++i)
3075  {
3076  if( (x(0).n_rows != x(i).n_rows) || (x(0).n_cols != x(i).n_cols) )
3077  {
3078  same_size = false;
3079  break;
3080  }
3081  }
3082 
3083  arma_debug_check( (same_size != true), "diskio::save_ppm_binary(): given field must have exactly 3 matrices of equal size" );
3084 
3085  const Mat<eT>& R = x(0);
3086  const Mat<eT>& G = x(1);
3087  const Mat<eT>& B = x(2);
3088 
3089  f << "P6" << '\n';
3090  f << R.n_cols << '\n';
3091  f << R.n_rows << '\n';
3092  f << 255 << '\n';
3093 
3094  const uword n_elem = 3 * R.n_rows * R.n_cols;
3095  podarray<u8> tmp(n_elem);
3096 
3097  uword i = 0;
3098  for(uword row=0; row < R.n_rows; ++row)
3099  {
3100  for(uword col=0; col < R.n_cols; ++col)
3101  {
3102  tmp[i+0] = u8( access::tmp_real( R.at(row,col) ) );
3103  tmp[i+1] = u8( access::tmp_real( G.at(row,col) ) );
3104  tmp[i+2] = u8( access::tmp_real( B.at(row,col) ) );
3105 
3106  i+=3;
3107  }
3108  }
3109 
3110  f.write( reinterpret_cast<const char*>(tmp.mem), std::streamsize(n_elem) );
3111 
3112  return f.good();
3113  }
3114 
3115 
3116 
3118 
static arma_inline const eT & tmp_real(const eT &X)
internal function to obtain the real part of either a plain number or a complex number ...
Definition: access.hpp:26
static bool save_raw_binary(const Mat< eT > &x, const std::string &final_name)
Save a matrix as raw binary (no header)
arma_inline const Op< T1, op_sum > sum(const Base< typename T1::elem_type, T1 > &X, const uword dim=0)
Delayed sum of elements of a matrix along a specified dimension (either rows or columns). The result is stored in a dense matrix that has either one column or one row. For dim = 0, find the sum of each column. For dim = 1, find the sum of each row. The default is dim = 0. NOTE: this function works differently than in Matlab/Octave.
Definition: fn_sum.hpp:29
arma_inline arma_warn_unused eT * memptr()
returns a pointer to array of eTs used by the matrix
Definition: Mat_meat.hpp:4024
A lightweight array for POD types. If the amount of memory requested is small, the stack is used...
static bool save_pgm_binary(const Mat< eT > &x, const std::string &final_name)
Save a matrix as a PGM greyscale image.
void set_size(const uword in_elem)
change the matrix to have user specified dimensions (data is not preserved)
Definition: Mat_meat.hpp:4211
static void conv_to_hex(char *out, const u8 x)
static out_eT from(const Base< in_eT, T1 > &in, const typename arma_not_cx< in_eT >::result *junk=0)
Definition: fn_conv_to.hpp:45
static bool load_arma_binary(Mat< eT > &x, const std::string &name, std::string &err_msg)
static bool load_pgm_binary(Mat< eT > &x, const std::string &name, std::string &err_msg)
Load a PGM greyscale image as a matrix.
static char conv_to_hex_char(const u8 x)
const uword n_rows
number of rows in the field (read-only)
Definition: field_bones.hpp:37
static bool save_csv_ascii(const Mat< eT > &x, const std::string &final_name)
Save a matrix in CSV text format (human readable)
const uword n_cols
number of columns in the field (read-only)
Definition: field_bones.hpp:38
static file_type guess_file_type(std::istream &f)
void set_size(const uword n_obj_in)
Definition: field_meat.hpp:155
void set_size(const uword in_rows, const uword in_cols, const uword in_slices)
change the cube to have user specified dimensions (data is not preserved)
Definition: Cube_meat.hpp:2414
const uword n_cols
number of columns in the matrix (read-only)
Definition: Mat_bones.hpp:30
const uword n_elem
number of elements in the matrix (read-only)
Definition: Mat_bones.hpp:31
const uword n_rows
number of rows in the matrix (read-only)
Definition: Mat_bones.hpp:29
comma separated values (CSV), without any other information
u32 uword
Definition: typedef.hpp:85
#define arma_type_check(condition)
static bool load_std_string(field< std::string > &x, const std::string &name, std::string &err_msg)
arma_inline arma_warn_unused eT * memptr()
returns a pointer to array of eTs used by the cube
Definition: Cube_meat.hpp:2260
const uword n_cols
number of columns in each slice (read-only)
Definition: Cube_bones.hpp:38
static bool save_ppm_binary(const Cube< T1 > &x, const std::string &final_name)
static std::string gen_bin_header(const Mat< eT > &x)
static bool load_ppm_binary(Cube< T1 > &x, const std::string &final_name, std::string &err_msg)
#define arma_debug_check
Definition: debug.hpp:1084
static bool load_raw_binary(Mat< eT > &x, const std::string &name, std::string &err_msg)
file_type
arma_inline Mat< eT > & slice(const uword in_slice)
provide the reference to the matrix representing a single slice
Definition: Cube_meat.hpp:796
arma_inline arma_warn_unused eT & at(const uword i)
linear element accessor (treats the matrix as a vector); no bounds check.
Definition: Mat_meat.hpp:3692
#define arma_ignore(variable)
Dense cube class.
Definition: Cube_bones.hpp:30
static bool load_auto_detect(Mat< eT > &x, const std::string &name, std::string &err_msg)
Try to load a matrix by automatically determining its type.
static std::string gen_tmp_name(const std::string &x)
static bool save_raw_ascii(const Mat< eT > &x, const std::string &final_name)
void reset()
Definition: Cube_meat.hpp:2609
void reset()
Definition: Mat_meat.hpp:4553
arma_aligned const eT *const mem
pointer to the memory used by the cube (memory is read-only)
Definition: Cube_bones.hpp:51
static bool load_raw_ascii(Mat< eT > &x, const std::string &name, std::string &err_msg)
static std::string gen_txt_header(const Mat< eT > &x)
Definition: diskio_meat.hpp:27
#define arma_extra_debug_sigprint
Definition: debug.hpp:1116
static bool save_std_string(const field< std::string > &x, const std::string &name)
ASCII format (text), without any other information.
raw binary format, without any other information.
static bool safe_rename(const std::string &old_name, const std::string &new_name)
static bool load_arma_ascii(Mat< eT > &x, const std::string &name, std::string &err_msg)
static bool save_arma_ascii(const Mat< eT > &x, const std::string &final_name)
const uword n_elem
number of elements in the cube (read-only)
Definition: Cube_bones.hpp:41
arma_inline eT * memptr()
Dense matrix class.
const Mat & zeros()
Definition: Mat_meat.hpp:4331
static bool load_csv_ascii(Mat< eT > &x, const std::string &name, std::string &err_msg)
Load a matrix in CSV text format (human readable)
arma_aligned const eT *const mem
pointer to the memory used by the matrix (memory is read-only)
Definition: Mat_bones.hpp:40
arma_aligned const eT *const mem
pointer to memory used by the object
static void pnm_skip_comments(std::istream &f)
const uword n_elem
number of elements in the field (read-only)
Definition: field_bones.hpp:39
arma_inline arma_warn_unused bool is_empty() const
returns true if the matrix has no elements
Definition: Mat_meat.hpp:3812
static bool save_arma_binary(const Mat< eT > &x, const std::string &final_name)
const uword n_slices
number of slices in the cube (read-only)
Definition: Cube_bones.hpp:40
const uword n_rows
number of rows in each slice (read-only)
Definition: Cube_bones.hpp:37
arma_inline oT & at(const uword i)
linear element accessor (treats the field as a vector); no bounds check
Definition: field_meat.hpp:217
arma_inline arma_warn_unused eT & at(const uword i)
linear element accessor (treats the cube as a vector); no bounds check.
Definition: Cube_meat.hpp:2024


armadillo_matrix
Author(s):
autogenerated on Fri Apr 16 2021 02:31:57