private void printBench(CompressionStream stream) {
    long t = System.currentTimeMillis() - startTime;
    int vertexCount = stream.getVertexCount();
    int meshReferenceCount = stream.getMeshReferenceCount();
    int totalVertices = meshReferenceCount + vertexCount;
    float meshPercent = 100f * meshReferenceCount / (float) totalVertices;

    float compressionRatio = stream.getByteCount() / ((float) outputBuffer.getByteCount());

    int vertexBytes =
        12
            + (stream.vertexColor3 ? 12 : 0)
            + (stream.vertexColor4 ? 16 : 0)
            + (stream.vertexNormals ? 12 : 0);

    float compressedVertexBytes = outputBuffer.getByteCount() / (float) totalVertices;

    System.out.println(
        "\nGeometryCompressor:\n"
            + totalVertices
            + " total vertices\n"
            + vertexCount
            + " streamed vertices\n"
            + meshReferenceCount
            + " mesh buffer references ("
            + meshPercent
            + "%)\n"
            + stream.getByteCount()
            + " bytes streamed geometry compressed to "
            + outputBuffer.getByteCount()
            + " in "
            + (t / 1000f)
            + " sec\n"
            + (stream.getByteCount() / (float) t)
            + " kbytes/sec, "
            + "stream compression ratio "
            + compressionRatio
            + "\n\n"
            + vertexBytes
            + " original bytes per vertex, "
            + compressedVertexBytes
            + " compressed bytes per vertex\n"
            + "total vertex compression ratio "
            + (vertexBytes / (float) compressedVertexBytes)
            + "\n\n"
            + "lower bound "
            + stream.ncBounds[0].toString()
            + "\n"
            + "upper bound "
            + stream.ncBounds[1].toString());
  }
  //
  // Compress the stream and put the results in the output buffer.
  // Set up the CompressedGeometryData.Header object.
  //
  private void compressStream(CompressionStream stream) {
    if (benchmark) startTime = System.currentTimeMillis();

    // Create the Huffman table.
    huffmanTable = new HuffmanTable();

    // Quantize the stream, compute deltas between consecutive elements if
    // possible, and histogram the data length distribution.
    stream.quantize(huffmanTable);

    // Compute tags for stream tokens.
    huffmanTable.computeTags();

    // Create the output buffer and assemble the compressed output.
    outputBuffer = new CommandStream(stream.getByteCount() / 3);
    stream.outputCommands(huffmanTable, outputBuffer);

    // Print any desired info.
    if (benchmark) printBench(stream);
    if (printStream) stream.print();
    if (printHuffman) huffmanTable.print();

    // Set up the compressed geometry header object.
    cgHeader.bufferType = stream.streamType;
    cgHeader.bufferDataPresent = 0;
    cgHeader.lowerBound = new Point3d(stream.ncBounds[0]);
    cgHeader.upperBound = new Point3d(stream.ncBounds[1]);

    if (stream.vertexNormals)
      cgHeader.bufferDataPresent |= CompressedGeometryData.Header.NORMAL_IN_BUFFER;

    if (stream.vertexColor3 || stream.vertexColor4)
      cgHeader.bufferDataPresent |= CompressedGeometryData.Header.COLOR_IN_BUFFER;

    if (stream.vertexColor4)
      cgHeader.bufferDataPresent |= CompressedGeometryData.Header.ALPHA_IN_BUFFER;

    cgHeader.start = 0;
    cgHeader.size = outputBuffer.getByteCount();

    // Clear the huffman table for next use.
    huffmanTable.clear();
  }