package qtrees; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.util.logging.Level; import java.util.logging.Logger; /** * Representation of a Quad-tree * @author Camil Staps, s4498062 */ public class QTree { /** the root of the tree */ QTNode root; /** * Construct the tree based on an ASCII representation of a bitstream on a reader * @param input the reader */ public QTree( Reader input ) { root = readQTree( input ); } /** * Construct the tree based on a bitmap * @param bitmap the bitmap */ public QTree( Bitmap bitmap ) { root = bitmap2QTree( 0, 0, bitmap.getWidth(), bitmap ); } /** * Fill a bitmap based on this tree * @param bitmap the bitmap */ public void fillBitmap ( Bitmap bitmap ) { root.fillBitmap(0, 0, bitmap.getWidth(), bitmap); } /** * Write the quad-tree as compressed bitstream * @param sb the Writer to write to * @throws IOException is passed on from Writer */ public void writeQTree( Writer sb ) throws IOException { root.writeNode( sb ); } /** * Read a Quad-tree node based on an ASCII representation of a bitstream on a Reader * @param input the Reader * @return the node */ private static QTNode readQTree( Reader input ) { try { int read = input.read(); if (read == '1') { GreyNode node = new GreyNode(); for (int i = 0; i < 4; i++) node.setChild(i, readQTree(input)); return node; } else { read = input.read(); if (read == '1') { return new WhiteLeaf(); } else { return new BlackLeaf(); } } } catch (IOException ex) { Logger.getLogger(QTree.class.getName()).log(Level.SEVERE, null, ex); return null; } } /** * Get a (compressed) node from a (part of a) bitmap * @param x the x coordinate of the top left corner * @param y the y coordinate of the top left corner * @param width the width of the part to read * @param bitmap the bitmap * @return the (compressed) node */ public static QTNode bitmap2QTree( int x, int y, int width, Bitmap bitmap ) { if (width == 1) { if (bitmap.getBit(x,y)) { return new WhiteLeaf(); } else { return new BlackLeaf(); } } else { GreyNode node = new GreyNode(); node.setChild(0, bitmap2QTree(x, y, width / 2, bitmap)); node.setChild(1, bitmap2QTree(x + width / 2, y, width / 2, bitmap)); node.setChild(2, bitmap2QTree(x + width / 2, y + width / 2, width / 2, bitmap)); node.setChild(3, bitmap2QTree(x, y + width / 2, width / 2, bitmap)); return node.compress(); } } }