00001
00002
00003
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _CAPD_HOMENGIN_CUBFILES_H_
00036 #define _CAPD_HOMENGIN_CUBFILES_H_
00037
00038 #include "chomp/system/config.h"
00039 #include "chomp/system/textfile.h"
00040 #include "chomp/system/timeused.h"
00041 #include "chomp/system/arg.h"
00042 #include "chomp/homology/homtools.h"
00043
00044 #include <cstdlib>
00045 #include <ctime>
00046 #include <new>
00047 #include <exception>
00048 #include <iostream>
00049 #include <fstream>
00050 #include <iomanip>
00051 #include <vector>
00052 #include <sstream>
00053 #include <algorithm>
00054
00055 namespace chomp {
00056 namespace homengin {
00057
00058
00059
00060
00061
00063 class cubfile
00064 {
00065 public:
00067 cubfile (const char *_filename);
00068
00070 virtual ~cubfile ();
00071
00072
00073
00074
00076
00077
00079 const char *filename () const
00080 {
00081 return _filename. c_str ();
00082 }
00083
00085 virtual int dim () const
00086 {
00087 if (_dim > 0)
00088 return _dim;
00089 throw "Undefined dimension of a set of cubes.";
00090 }
00091
00093 virtual int count () const
00094 {
00095 if (_count >= 0)
00096 return _count;
00097 throw "Undefined number of cubes in a set.";
00098 }
00099
00101 virtual bool bitmaptype () const
00102 {
00103 throw "Undefined bitmapness of a set of cubes.";
00104 }
00105
00107 virtual bool elementary () const
00108 {
00109 throw "Undefined type of a set of cubes.";
00110 }
00111
00113 virtual bool spacewrapping () const
00114 {
00115 return (_wrapping. size () != 0);
00116 }
00117
00120 virtual int *spacewrapping (int *table) const
00121 {
00122 if (_wrapping. size ())
00123 {
00124 std::copy (_wrapping. begin (), _wrapping. end (),
00125 table);
00126 return table;
00127 }
00128 throw "Unknown space wrapping of a set of cubes.";
00129 }
00130
00132 virtual void setwrapping (const int *table, int count = 0)
00133 {
00134 _wrapping. clear ();
00135 int d = count ? count : dim ();
00136 _wrapping. assign (table, table + d);
00137 return;
00138 }
00139
00144 virtual int boundingbox (int *mincoord, int *maxcoord) const
00145 {
00146 if (_min. size () && _max. size ())
00147 {
00148 if (mincoord)
00149 std::copy (_min. begin (), _min. end (),
00150 mincoord);
00151 if (maxcoord)
00152 std::copy (_max. begin (), _max. end (),
00153 maxcoord);
00154 return 0;
00155 }
00156 throw "Undefined bounding box of a set of cubes.";
00157 }
00158
00164 int volume (int chunk = 0, bool power2 = false) const;
00165
00167 static const char *name ()
00168 {
00169 return "unknown set of cubes";
00170 }
00171
00173 static std::ostream &describe (std::ostream &out)
00174 {
00175 out << "This is an unknown set of cubes.";
00176 return out;
00177 }
00178
00180 static bool compatible (const char *filename)
00181 {
00182 return false;
00183 }
00184
00186 virtual int readcubes (chomp::homology::CubicalComplex &s) const
00187 {
00188 throw "Unable to read a set of cells.";
00189 }
00190
00192 virtual int readcubes (chomp::homology::SetOfCubes &s) const
00193 {
00194 throw "Unable to read a set of cubes.";
00195 }
00196
00202 virtual int readcubes (int *&sizes, char *&bytes, int padding = 0,
00203 bool power2 = false) const
00204 {
00205 throw "Unable to read a bitmap set of cubes.";
00206 }
00207
00208 protected:
00210 std::string _filename;
00211
00213 mutable int _dim;
00214
00216 mutable int _count;
00217
00219 mutable std::vector<int> _min;
00220
00222 mutable std::vector<int> _max;
00223
00225 mutable std::vector<int> _wrapping;
00226
00227 };
00228
00229
00230
00231 inline cubfile::cubfile (const char *filename): _filename (filename),
00232 _dim (0), _count (-1), _min (), _max (), _wrapping ()
00233 {
00234 return;
00235 }
00236
00237 inline cubfile::~cubfile ()
00238 {
00239 return;
00240 }
00241
00242
00243
00244
00245
00246
00248 class cubtype
00249 {
00250 public:
00252 typedef std::vector<const cubtype *> cubtypelist;
00253
00255 static cubtypelist cubtypes;
00256
00257 protected:
00259 cubtype ()
00260 {
00261 cubtypes. push_back (this);
00262 return;
00263 }
00264
00266 virtual ~cubtype ()
00267 {
00268 cubtypelist::iterator it = find (cubtypes. begin (),
00269 cubtypes. end (), this);
00270 if (it != cubtypes. end ())
00271 cubtypes. erase (it);
00272 return;
00273 }
00274
00275 public:
00277 virtual const char *name () const = 0;
00278
00280 virtual std::ostream &describe (std::ostream &out) const = 0;
00281
00283 virtual bool compatible (const char *filename) const = 0;
00284
00286 virtual cubfile *newcubfile (const char *filename) const = 0;
00287
00289 static std::ostream &showlist (std::ostream &out,
00290 const cubtype::cubtypelist &types = cubtype::cubtypes);
00291
00295 static cubfile *newfile (const char *filename,
00296 const cubtype::cubtypelist &types = cubtype::cubtypes);
00297
00298 };
00299
00302 template <class cubfileT>
00303 class cubfile_traits: public cubtype
00304 {
00305 public:
00307 cubfile_traits ()
00308 {
00309 return;
00310 }
00311
00313 ~cubfile_traits ()
00314 {
00315 return;
00316 }
00317
00319 const char *name () const
00320 {
00321 return cubfileT::name ();
00322 }
00323
00325 std::ostream &describe (std::ostream &out) const
00326 {
00327 return cubfileT::describe (out);
00328 }
00329
00331 bool compatible (const char *filename) const
00332 {
00333 return cubfileT::compatible (filename);
00334 }
00335
00337 cubfile *newcubfile (const char *filename) const
00338 {
00339 return new cubfileT (filename);
00340 }
00341
00342 };
00343
00344
00345
00346
00347
00348
00350 class cublistfile: public cubfile
00351 {
00352 public:
00354 cublistfile (const char *filename);
00355
00357 int dim () const;
00358
00360 int count () const
00361 {
00362 if (_count < 0)
00363 analyze ();
00364 return _count;
00365 }
00366
00368 bool bitmaptype () const
00369 {
00370 return false;
00371 }
00372
00374 bool elementary () const
00375 {
00376 return false;
00377 }
00378
00380 int boundingbox (int *mincoord, int *maxcoord) const
00381 {
00382 if (!_min. size ())
00383 analyze ();
00384 return cubfile::boundingbox (mincoord, maxcoord);
00385 }
00386
00388 static const char *name ()
00389 {
00390 return "text list of cubes";
00391 }
00392
00394 static std::ostream &describe (std::ostream &out);
00395
00397 static bool compatible (const char *filename);
00398
00400 int readcubes (chomp::homology::CubicalComplex &s) const;
00401
00403 int readcubes (chomp::homology::SetOfCubes &s) const;
00404
00406 int readcubes (int *&sizes, char *&bytes, int padding = 0,
00407 bool power2 = false) const;
00408
00409 private:
00412 void analyze () const;
00413
00415 static cubfile_traits<cublistfile> t;
00416
00417 };
00418
00419
00420
00421 inline cublistfile::cublistfile (const char *filename): cubfile (filename)
00422 {
00423 return;
00424 }
00425
00426
00427
00428
00429
00430
00432 class cellistfile: public cubfile
00433 {
00434 public:
00436 cellistfile (const char *filename);
00437
00439 int dim () const;
00440
00442 int count () const
00443 {
00444 if (_count < 0)
00445 analyze ();
00446 return _count;
00447 }
00448
00450 bool bitmaptype () const
00451 {
00452 return false;
00453 }
00454
00456 bool elementary () const
00457 {
00458 return true;
00459 }
00460
00462 int boundingbox (int *mincoord, int *maxcoord) const
00463 {
00464 if (!_min. size ())
00465 analyze ();
00466 return cubfile::boundingbox (mincoord, maxcoord);
00467 }
00468
00470 static const char *name ()
00471 {
00472 return "text list of cubical cells";
00473 }
00474
00476 static std::ostream &describe (std::ostream &out);
00477
00479 static bool compatible (const char *filename);
00480
00482 int readcubes (chomp::homology::CubicalComplex &s) const;
00483
00485 int readcubes (chomp::homology::SetOfCubes &s) const
00486 {
00487 throw "Trying to read cubical cells as a set of full cubes.";
00488 }
00489
00491 int readcubes (int *&sizes, char *&bytes, int padding = 0,
00492 bool power2 = false) const
00493 {
00494 throw "Trying to read cubical cells as a bitmap.";
00495 }
00496
00497 private:
00500 void analyze () const;
00501
00503 static cubfile_traits<cellistfile> t;
00504
00505 };
00506
00507
00508
00509 inline cellistfile::cellistfile (const char *filename): cubfile (filename)
00510 {
00511 return;
00512 }
00513
00514
00515
00516
00517
00518
00520 class bitcodefile: public cubfile
00521 {
00522 public:
00524 bitcodefile (const char *filename);
00525
00527 int dim () const
00528 {
00529 if (_dim <= 0)
00530 analyze ();
00531 return _dim;
00532 }
00533
00535 int count () const
00536 {
00537 if (_count < 0)
00538 analyze ();
00539 return _count;
00540 }
00541
00543 bool bitmaptype () const
00544 {
00545 return false;
00546 }
00547
00549 bool elementary () const
00550 {
00551 return false;
00552 }
00553
00555 static const char *name ()
00556 {
00557 return "text bitcodes";
00558 }
00559
00561 static std::ostream &describe (std::ostream &out);
00562
00564 static bool compatible (const char *filename);
00565
00567 int readcubes (chomp::homology::CubicalComplex &s) const;
00568
00570 int readcubes (chomp::homology::SetOfCubes &s) const;
00571
00573 int readcubes (int *&sizes, char *&bytes, int padding = 0,
00574 bool power2 = false) const;
00575
00576 private:
00579 void analyze () const;
00580
00582 static cubfile_traits<bitcodefile> t;
00583
00584 };
00585
00586
00587
00588 inline bitcodefile::bitcodefile (const char *filename): cubfile (filename)
00589 {
00590 return;
00591 }
00592
00593
00594
00595
00596
00597
00599 class winbmpfile: public cubfile
00600 {
00601 public:
00603 winbmpfile (const char *filename);
00604
00606 int count () const;
00607
00609 bool bitmaptype () const
00610 {
00611 return true;
00612 }
00613
00615 bool elementary () const
00616 {
00617 return false;
00618 }
00619
00621 int boundingbox (int *mincoord, int *maxcoord) const;
00622
00624 static const char *name ()
00625 {
00626 return "windows bitmap";
00627 }
00628
00630 static std::ostream &describe (std::ostream &out);
00631
00633 static bool compatible (const char *filename);
00634
00636 int readcubes (chomp::homology::CubicalComplex &s) const
00637 {
00638 throw "Trying to read a set of cells from a Win BMP file.";
00639 }
00640
00642 int readcubes (chomp::homology::SetOfCubes &s) const;
00643
00645 int readcubes (int *&sizes, char *&bytes, int padding = 0,
00646 bool power2 = false) const;
00647
00648 private:
00650 static cubfile_traits<winbmpfile> t;
00651
00652 };
00653
00654
00655
00656 inline winbmpfile::winbmpfile (const char *filename): cubfile (filename)
00657 {
00658 _dim = 2;
00659 return;
00660 }
00661
00662
00663
00664
00665
00666
00672 class bmdheader
00673 {
00674 public:
00676 bmdheader (const char *filename);
00677
00679 bool little;
00680
00682 int offset;
00683
00685 int dim;
00686
00688 int length;
00689
00691 int zerowidth;
00692
00694 std::vector<int> width;
00695
00697 int readbytes (std::istream &f, int n) const;
00698
00699 };
00700
00701
00702
00705 std::ostream &operator << (std::ostream &out, const bmdheader &header);
00706
00707
00708
00709
00711 class bmdfile: public cubfile
00712 {
00713 public:
00715 bmdfile (const char *filename);
00716
00718 int count () const;
00719
00721 bool bitmaptype () const
00722 {
00723 return true;
00724 }
00725
00727 bool elementary () const
00728 {
00729 return false;
00730 }
00731
00733 static const char *name ()
00734 {
00735 return "multi-dimensional bitmap";
00736 }
00737
00739 static std::ostream &describe (std::ostream &out);
00740
00742 static bool compatible (const char *filename);
00743
00745 int readcubes (chomp::homology::CubicalComplex &s) const
00746 {
00747 throw "Trying to read a set of cells from a BMD file.";
00748 }
00749
00751 int readcubes (chomp::homology::SetOfCubes &s) const;
00752
00754 int readcubes (int *&sizes, char *&bytes, int padding = 0,
00755 bool power2 = false) const;
00756
00757 private:
00759 bmdheader header;
00760
00762 static cubfile_traits<bmdfile> t;
00763
00764 };
00765
00766
00767
00768 inline bmdfile::bmdfile (const char *filename): cubfile (filename),
00769 header (filename)
00770 {
00771 _dim = header. dim;
00772 _min. assign (_dim, 0);
00773 _max. assign (header. width. begin (), header. width. end ());
00774 return;
00775 }
00776
00777
00778
00779
00780
00781
00783 class cubitmap: public cubfile
00784 {
00785 public:
00787 cubitmap (const char *buffer, const int *sizes, int dim);
00788
00790 int count () const;
00791
00793 bool bitmaptype () const
00794 {
00795 return true;
00796 }
00797
00799 bool elementary () const
00800 {
00801 return false;
00802 }
00803
00805 static const char *name ()
00806 {
00807 return "bitmap buffer (memory)";
00808 }
00809
00811 static std::ostream &describe (std::ostream &out);
00812
00814 static bool compatible (const char *)
00815 {
00816 return false;
00817 }
00818
00820 int readcubes (chomp::homology::CubicalComplex &s) const
00821 {
00822 throw "Trying to read a set of cells from a bitmap buffer.";
00823 }
00824
00826 int readcubes (chomp::homology::SetOfCubes &s) const;
00827
00829 int readcubes (int *&sizes, char *&bytes, int padding = 0,
00830 bool power2 = false) const;
00831
00832 private:
00834 const char *buf;
00835
00837 int buflength;
00838
00839 };
00840
00841
00842
00843 inline cubitmap::cubitmap (const char *buffer, const int *sizes, int dim):
00844 cubfile ("(memory)"), buf (buffer)
00845 {
00846 _dim = dim;
00847 _min. assign (_dim, 0);
00848 _max. assign (sizes, sizes + _dim);
00849 if (sizes [0] & 0x1F)
00850 throw "The x-size of a bitmap must be a multiple of 32.";
00851 buflength = sizes [0] >> 3;
00852 for (int i = 1; i < _dim; ++ i)
00853 buflength *= sizes [i];
00854 if (buflength <= 0)
00855 throw "Non-positive buffer size - something went wrong.";
00856 return;
00857 }
00858
00859
00860 }
00861 }
00862
00863 #endif // _CAPD_HOMENGIN_CUBFILES_H_
00864
00866