# PD4ML PDF Optimizer

PD4ML PDF Optimizer rewrites an existing PDF file so that it contains only what the document still uses. A PDF that has been edited by incremental updates keeps objects nothing points to any more, plus one cross-reference section and trailer per update; the same font or image can also end up embedded twice. The optimizer drops the unreferenced objects, merges byte-identical duplicates and writes the result as one fresh file with a single cross-reference section and trailer. You call it from Java (`com.pd4ml.pdf.optimizer`) or run it from the command line.

{% hint style="version" %}
Available from **PD4ML v4.1.1**. The optimizer is part of `pd4ml.jar` and is built on PD4ML's own PDF COS layer, not on a third-party PDF library.
{% endhint %}

## What you can do with it

- **Drop unreferenced objects**: only what is reachable from the trailer's `/Root` and `/Info` is copied to the output, with compact object numbering.
- **Collapse incremental-update history**: the output is a full rewrite with one cross-reference section and trailer, not another incremental update.
- **Compact output**: from v4.2.0, a PDF 1.5 or later document is written with its dictionaries and arrays packed into compressed object streams and a compressed cross-reference stream, as PD4ML writes its own PDFs; a PDF 1.4 document (PDF/A-1 among them) and an encrypted output use the classic cross-reference table.
- **Merge duplicate content**: byte-identical objects (for example the same font, image or color space embedded twice) become one shared copy. On by default; page, annotation and form field dictionaries are never merged. Turn it off with `deduplicateContent(false)` or `--no-dedup`.
- **Open encrypted input**: pass the user or owner password. The output is plain unless you request encryption.
- **Encrypt the output**: AES-256 by default, or RC4-128 / AES-128 with your own permission bits.
- **Linearize the output** ("Fast Web View"): a viewer that loads the file over a network shows the first page, and then any other page, before the whole file has arrived. Turn it on with `linearize(true)` or `--linearize` (from v4.2.0; not together with output encryption).
- **See what changed**: `PdfOptimizeResult` reports input and output byte counts, object counts, removed objects and how many of them were merged duplicates.

The optimizer does not recompress streams: stream data is copied as it is.

## Quick start

```java
import com.pd4ml.pdf.optimizer.PdfOptimizeException;
import com.pd4ml.pdf.optimizer.PdfOptimizeResult;
import com.pd4ml.pdf.optimizer.PdfOptimizer;

import java.io.File;

public class OptimizeQuickStart {
    public static void main(String[] args) throws PdfOptimizeException {
        PdfOptimizeResult result = PdfOptimizer.optimize(
                new File("bloated.pdf"), new PdfOptimizer.Options(), new File("cleaned.pdf"));
        System.out.println(result.getInputByteCount() + " -> " + result.getOutputByteCount() + " bytes, "
                + result.getRemovedObjectCount() + " object(s) removed, "
                + result.getDuplicateObjectCount() + " of them duplicate content");
    }
}
```

The same from the command line (`--in` and `--out` are required; add `--password=<pw>` for an encrypted input):

```bash
java -cp pd4ml.jar com.pd4ml.pdf.optimizer.cli.Pd4OptimizeCli --in=bloated.pdf --out=cleaned.pdf
```

## When to use it

PD4ML's HTML-to-PDF converter already writes its own output compactly, with nothing to enable (see [Compact PDF output](../features/compact-pdf-output)). The optimizer is for PDF files that already exist, whoever produced them: documents created elsewhere or before, edited by incremental updates, or carrying the same resource twice. A file without such leftovers shrinks little, because the optimizer removes objects and does not re-encode stream data.

| Tool | Use it to |
|---|---|
| [PD4ML PDF COS](pd4ml-pdf-cos) | read, inspect, modify and write PDF objects at a low level; the foundation the other tools are built on |
| [PD4ML PDF Merge](pd4ml-pdf-merge) | combine page ranges from several PDFs into one document |
| PD4ML PDF Optimizer | clean up a single existing PDF and make it smaller |
| [PD4ML PDF Signing](pd4ml-pdf-signing) | add digital signatures |
| [PD4ML PDF XFDF](pd4ml-pdf-xfdf) | export and import annotations and form field values as XFDF; its `--optimize` option runs this optimizer after an import |

## In this section

- [PD4ML PDF Optimizer API - Programmer's Manual](pd4ml-pdf-optimizer/pd4ml-optimize-manual): how optimizing works, the `PdfOptimizer` methods and `Options`, duplicate-content rules, error messages, encryption, linearized output and threading.
- [Examples](pd4ml-pdf-optimizer/pd4ml-optimize-examples): seven runnable example classes from the `pd4ml-examples` repository, from a basic cleanup to error handling and deduplication.
- [pd4optimizecli Reference](pd4ml-pdf-optimizer/pd4optimizecli-reference): command-line flags, exit codes, examples and troubleshooting for `Pd4OptimizeCli`.
- [Javadoc](https://pd4ml.com/javadoc/com/pd4ml/pdf/optimizer/package-summary.html): API reference for the `com.pd4ml.pdf.optimizer` package.
