annotate armadillo-2.4.4/include/armadillo_bits/diskio_meat.hpp @ 5:79b343f3e4b8

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