sclass HashedImage2B is IBinaryImage, MakesImage2B { Image2B image; // don't change this afterwards... long hash; bool hashComputed; *(BufferedImage image) { this(new Image2B(image)); } *(Image2B *image) { assertNotNull(image); } long hash() { while (!hashComputed) { synchronized { if (!hashComputed) { hash = hashBinaryImage(image); set hashComputed; } } } ret hash; } equals HashedImage2B o { if (hash() != o.hash()) false; if (!binaryImagesIdentical(image, o.image)) { reportHashCollision(this, o); false; } true; } public int hashCode() { ret (int) hash(); } public Image2B get aka getImage2B() { ret image; } public int getWidth() { ret image.getWidth(); } public int getHeight() { ret image.getHeight(); } public BufferedImage getBufferedImage() { ret image.getBufferedImage(); } // check that Image2B wasn't modified void verify { if (hash != 0) assertEquals(hash, hashBinaryImage(image)); } S classNameForPrinting() { ret cnfp(this, selfType.class, "HashedImage2B"; } toString { ret formatFunctionCall(classNameForPrinting(), w() + "*" + h() + "px", "hash " + longToHex(hash())); } // implement IBinaryImage public bool getBoolPixel(int x, int y) { ret image.getBoolPixel(x, y); } }