private boolean[][][][][] readCellVisibilities() throws IOException {
        if (cellVisibilities != null) {
            return cellVisibilities;
        }

        int worldWidth = readInt();
        if (worldWidth < 0) {
            return null;
        }

        int worldHeight = readInt();
        if (worldHeight < 0) {
            return null;
        }

        int stanceCount = readInt();
        if (stanceCount < 0) {
            return null;
        }

        byte[] rawVisibilities = readBytes(worldWidth * worldHeight * worldWidth * worldHeight * stanceCount);
        cellVisibilities = new boolean[worldWidth][worldHeight][worldWidth][worldHeight][stanceCount];

        int rawVisibilityIndex = 0;

        for (int viewerX = 0; viewerX < worldWidth; ++viewerX) {
            for (int viewerY = 0; viewerY < worldHeight; ++viewerY) {
                for (int objectX = 0; objectX < worldWidth; ++objectX) {
                    for (int objectY = 0; objectY < worldHeight; ++objectY) {
                        for (int stanceIndex = 0; stanceIndex < stanceCount; ++stanceIndex) {
                            cellVisibilities[viewerX][viewerY][objectX][objectY][stanceIndex]
                                    = rawVisibilities[rawVisibilityIndex++] != 0;
                        }
                    }
                }
            }
        }

        return cellVisibilities;
    }