public static void main(String[] arg)
    {
        if (arg.length != 2) {
            System.out.println("Usage:\n   java Reorganize [source] [target]");
            return;
        }

        BufferedImage source = null;
        try {
            source = ImageIO.read(new File(arg[0]));
        } catch (IOException e) {
            System.out.println("Error while trying to read " + arg[0] + ".");
            e.printStackTrace();
            System.exit(1);
        }

        // Read the existing frames into a vector
        Vector<BufferedImage> spriteSet = gridCut(source,
                HAIR_SPRITE_WIDTH, HAIR_SPRITE_HEIGHT,
                HAIR_FRAMES, 1);

        // Determine minimal rectangle that can still contain the contents of
        // any frame
        /*
        Rectangle cropRect = minimumCropRect(spriteSet);

        if (cropRect == null) {
            System.out.println(
                    "Error: no optimal crop rect could be determined.");
            System.exit(1);
        }

        System.out.println(arg[0] + ": width=\"" +
                cropRect.width + "\" height=\"" + cropRect.height + "\"");
        */

        filterHeadgear(spriteSet);

        BufferedImage target = gridDraw(
                spriteSet,
                new Rectangle(0, 0, HAIR_SPRITE_WIDTH, HAIR_SPRITE_HEIGHT),
                HAIR_FRAMES - 4, 1);

        // Save the target image
        try {
            ImageIO.write(target, "png", new File(arg[1]));
        } catch (IOException e) {
            System.out.println("Error while trying to write " + arg[1] + ".");
            e.printStackTrace();
            System.exit(1);
        }
    }