00001 #ifndef QUADTREE_HEADER_
00002 #define QUADTREE_HEADER_
00003
00004 #include "../headers.h"
00005
00006
00007 class BitWriter;
00008 class BitReader;
00009
00011
00013 class MQuadTree: public ISquareRanges {
00014 DECLARE_debugModule;
00015
00016 DECLARE_TypeInfo( MQuadTree, "Quad-tree"
00017 , "Splits the range blocks according to the <b>quad-tree</b> algorithm"
00018 , {
00019 label: "Min. range-block size",
00020 desc: "Blocks with this size won't be divided",
00021 type: settingInt(2,2,8,IntLog2)
00022 }, {
00023 label: "Max. range-block size",
00024 desc: "Blocks with bigger size will be always divided",
00025 type: settingInt(2,12,12,IntLog2)
00026 }, {
00027 label: "Heuristic dividing",
00028 desc: "Pre-divide the ranges heuristically and later divide ranges\n"
00029 "with bad quality and try to merge ranges with good quality",
00030 type: settingCombo("no\nyes",1)
00031 } )
00032
00033
00034 protected:
00035 class Node;
00036 friend class Node;
00037
00038 protected:
00040 enum Settings { MinLevel, MaxLevel, HeuristicAllowed };
00041
00042 int minLevel() { return settingsInt(MinLevel); }
00043 int maxLevel() { return settingsInt(MaxLevel); }
00044 bool heuristicAllowed() { return settingsInt(HeuristicAllowed); }
00045
00046 protected:
00047
00048 Node *root;
00049 std::vector<RangeNode*> fringe;
00050 int zoom;
00051 #ifndef NDEBUG
00052 int badDivides, triedMerges, badTries;
00053 const PlaneBlock *planeBlock;
00054 #endif
00055
00056 protected:
00057
00059 MQuadTree()
00060 : root(0), zoom(-1)
00061 #ifndef NDEBUG
00062 , badDivides(0), triedMerges(0), badTries(0), planeBlock(0)
00063 #endif
00064 {}
00066 ~MQuadTree() { delete root; }
00067 public:
00070 void encode(const PlaneBlock &toEncode);
00071 const RangeList& getRangeList() const
00072 { return fringe; }
00073
00074
00075 void writeSettings(std::ostream&) {}
00076 void readSettings(std::istream&) {}
00077
00078 void writeData(std::ostream &file);
00079 void readData_buildRanges(std::istream &file,const PlaneBlock &block);
00081 protected:
00082 static float estimateSE(Real rSum,Real r2Sum,int pixCount,int level)
00083 { return ldexp( r2Sum-sqr(rSum)/pixCount, -4 ) * level; }
00084 protected:
00085 struct NodeExtremes;
00087 class Node: public RangeNode {
00088 Node *father
00089 , *brother
00090 , *son;
00091
00093 Node( const Block &block, Node *father_, Node* brother_ )
00094 : RangeNode( block, father_->level-1 )
00095 , father(father_), brother(brother_), son(0) {}
00097 void disconnect();
00098 public:
00100 Node(const Block &block)
00101 : RangeNode( block, log2ceil(std::max(block.width(),block.height())) )
00102 , father(0), brother(this), son(0) {}
00104 ~Node() { deleteSons(); }
00106 void deleteSons();
00107
00109 void divide();
00112 void getHilbertList(RangeList &list,char start=0,char clockwise=1);
00114 int getSonCount() const;
00115
00117 bool encode(const PlaneBlock &toEncode);
00118
00120 void toFile(BitWriter &file,NodeExtremes extremes);
00122 void fromFile(BitReader &file,NodeExtremes extremes);
00123 };
00124 };
00125
00126 #endif // QUADTREE_HEADER_