# PD4ML PDF COS

PD4ML PDF COS is a Java API for working with an existing PDF at the level of its objects: dictionaries, arrays, streams, names and the references between them (the COS, Carousel Object Structure). It parses a PDF into an object model you can navigate and query, and writes changes back as an incremental update that leaves the original bytes untouched. Use it to inspect a PDF's structure, read values the higher-level tools do not expose, or make targeted edits. The package is [`com.pd4ml.pdf.cos`](https://pd4ml.com/javadoc/com/pd4ml/pdf/cos/package-summary.html); the PD4ML Merge, Optimizer, Signing and XFDF tools are built on it.

{% hint style="version" %}
Available from **PD4ML v4.1.1**. Part of `pd4ml.jar`, which also contains the `coscli` command-line tool.
{% endhint %}

## What you can do with it

- **Parse a PDF** into a `COSDocument` with `COSParser.load(...)` and reach the trailer, the catalog and every indirect object.
- **Query the object graph with COS paths**, a filesystem-like syntax such as `/Root/Pages/Kids[0]/MediaBox`, through `COSPathEvaluator.evaluate` (returns `COSNull.NULL` on a miss) or `evaluateStrict` (throws `COSPathException` naming the failed step).
- **Walk the page tree** by page index with `PageTree.findPage(catalog, index)`.
- **Decode streams**: `COSStream.getDecodedBytes()` applies the `/Filter` chain; `isFullyDecodable()` tells you in advance whether it reaches the end.
- **Read encrypted PDFs**: given the right password, strings and streams are decrypted while the document is parsed.
- **Edit an existing PDF** as an incremental update with `IncrementalUpdateWriter`: change, add or remove a key or array element of an indirect object, add new objects, and append them to the original file.
- **Build a PDF from scratch** from the object model and serialize it with `COSDocumentWriter`.
- **Do all of this from the command line** with `coscli`: `inspect`, `list`, `pages`, `dump`, `set` and `delete`.

## Quick start

Read a value with a COS path, then rotate the first page and save the change as an incremental update:

```java
byte[] pdfBytes = Files.readAllBytes(Paths.get("report.pdf"));
COSDocument document = COSParser.load(pdfBytes);

// Read: number of pages
COSBase count = COSPathEvaluator.evaluate(document, "/Root/Pages/Count");
System.out.println("Pages: " + count);

// Edit: the target must be an indirect object (it has its own object number)
COSBase page = COSPathEvaluator.evaluateStrict(document, "/Root/Pages/Kids[0]");
((COSDictionary) page).setItem("Rotate", COSInteger.get(90));

IncrementalUpdateWriter update = new IncrementalUpdateWriter(pdfBytes, document);
update.writeObject(page);
Files.write(Paths.get("out.pdf"), update.finish());
```

The same from the command line:

```bash
java -cp pd4ml.jar com.pd4ml.pdf.cos.cli.CosCli inspect report.pdf "/Root/Pages/Count"
java -cp pd4ml.jar com.pd4ml.pdf.cos.cli.CosCli set report.pdf out.pdf "/Root/Pages/Kids[0]" Rotate 90 --type=int
```

`set` and `delete` refuse encrypted input: the writer does not encrypt what it appends.

## When to use it

Use PD4ML PDF COS when you need direct access to a PDF's objects: to inspect or validate its structure, extract a value or a stream, or change a specific key. For common whole-document tasks, the tools built on it are a better fit:

| Task | Tool |
|---|---|
| Combine page ranges from several PDFs into one | [PD4ML PDF Merge](pd4ml-pdf-merge) |
| Remove unreachable objects and collapse incremental-update history | [PD4ML PDF Optimizer](pd4ml-pdf-optimizer) |
| Sign, timestamp, certify, add PAdES-LT validation data | [PD4ML PDF Signing](pd4ml-pdf-signing) |
| Export or import annotations and form field values as XFDF | [PD4ML PDF XFDF](pd4ml-pdf-xfdf) |

## In this section

- [PD4ML COS API - Programmer's Manual](pd4ml-pdf-cos/pd4ml-cos-api-manual): the object model, parsing, COS-path syntax, writing and the edit recipe, page tree, filters, encrypted input and known limits.
- [Examples](pd4ml-pdf-cos/pd4ml-cos-examples): eight runnable example classes from the `pd4ml-examples` repository, from parsing to building a document from scratch.
- [coscli - Command-Line Reference](pd4ml-pdf-cos/pd4coscli-reference): every `coscli` command and flag, exit codes and troubleshooting.
- [Javadoc](https://pd4ml.com/javadoc/com/pd4ml/pdf/cos/package-summary.html): reference for `com.pd4ml.pdf.cos` and its subpackages.
