@Override
    public synchronized void dispose() {

      for (Map.Entry<File, Jp2File> entry : openFiles.entrySet()) {
        System.out.println("closing " + entry.getKey());
        try {
          final Jp2File jp2File = entry.getValue();
          if (jp2File.stream != null) {
            jp2File.stream.close();
            jp2File.stream = null;
          }
        } catch (IOException e) {
          // warn
        }
      }

      for (File file : openFiles.keySet()) {
        System.out.println("deleting " + file);
        if (!file.delete()) {
          // warn
        }
      }

      openFiles.clear();

      if (!cacheDir.delete()) {
        // warn
      }
    }
    private Jp2File getOpenJ2pFile(File outputFile) throws IOException {
      Jp2File jp2File = openFiles.get(outputFile);
      if (jp2File == null) {
        jp2File = new Jp2File();
        jp2File.file = outputFile;
        jp2File.stream = new FileImageInputStream(outputFile);
        jp2File.header = jp2File.stream.readLine();
        jp2File.dataPos = jp2File.stream.getStreamPosition();

        final String[] tokens = jp2File.header.split(" ");
        if (tokens.length != 6) {
          throw new IOException("Unexpected tile format");
        }

        // String pg = tokens[0];   // PG
        // String ml = tokens[1];   // ML
        // String plus = tokens[2]; // +
        int jp2Width;
        int jp2Height;
        try {
          // int jp2File.nbits = Integer.parseInt(tokens[3]);
          jp2File.width = Integer.parseInt(tokens[4]);
          jp2File.height = Integer.parseInt(tokens[5]);
        } catch (NumberFormatException e) {
          throw new IOException("Unexpected tile format");
        }

        openFiles.put(outputFile, jp2File);
      }

      return jp2File;
    }