// img must be square with width/height being a power of 2 static BWContrastQuadTree bwImageContrastQuadtree(BWImage img) { int w = img.getWidth(), h = img.getHeight(); assertEquals("width/height", w, h); if (!isPowerOf2(w)) fail("image size not a power of 2: " + w); ret bwImageContrastQuadtree_make(img, 0, 0, w); } static BWContrastQuadTree bwImageContrastQuadtree_make(BWImage img, int x, int y, int w) { if (w == 1) ret BWContrastQuadTree(img.getInt(x, y)); int r = w/2; BWContrastQuadTree a = bwImageContrastQuadtree_make(img, x, y, r), b = bwImageContrastQuadtree_make(img, x+r, y, r), c = bwImageContrastQuadtree_make(img, x, y+r, r), d = bwImageContrastQuadtree_make(img, x+r, y+r, r); int min = intMin(a.min(), b.min(), c.min(), d.min()); int max = intMax(a.max(), b.max(), c.max(), d.max()); if (min == max) ret BWContrastQuadTree(min, max); ret new BWContrastQuadTree.Composite(min, max, a, b, c, d); }