PHPackages                             drainerlight/php-pdf-decompressor - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. drainerlight/php-pdf-decompressor

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

drainerlight/php-pdf-decompressor
=================================

Pure-PHP PDF decompressor: converts PDF 1.5+ cross-reference streams and object streams (ObjStm) into a classic PDF 1.4 structure, so parsers that only understand the traditional xref table (such as FPDI's free parser) can read them. A qpdf-free alternative — no external binaries.

v0.1.0(today)02↑2900%MITPHPPHP &gt;=7.4CI passing

Since Jul 1Pushed todayCompare

[ Source](https://github.com/drainerlight/php-pdf-decompressor)[ Packagist](https://packagist.org/packages/drainerlight/php-pdf-decompressor)[ Docs](https://github.com/drainerlight/php-pdf-decompressor)[ RSS](/packages/drainerlight-php-pdf-decompressor/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (2)Versions (2)Used By (0)

php-pdf-decompressor
====================

[](#php-pdf-decompressor)

**Make modern PDFs readable by legacy parsers — in pure PHP.**

[![CI](https://github.com/drainerlight/php-pdf-decompressor/actions/workflows/ci.yml/badge.svg)](https://github.com/drainerlight/php-pdf-decompressor/actions/workflows/ci.yml)[![Latest Version](https://camo.githubusercontent.com/f2dae8ca0bca161ead7c9b650d5adbbd6f5edc1960fad7474824d26334dccc61/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f647261696e65726c696768742f7068702d7064662d6465636f6d70726573736f722e737667)](https://packagist.org/packages/drainerlight/php-pdf-decompressor)[![Total Downloads](https://camo.githubusercontent.com/417c46aeb60ddeeb562431f8385aff34b735d7a8642dd675c00aeaf406d33f86/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f647261696e65726c696768742f7068702d7064662d6465636f6d70726573736f722e737667)](https://packagist.org/packages/drainerlight/php-pdf-decompressor)[![PHP Version](https://camo.githubusercontent.com/f5acea407dc9f9151dc2bf93e6f3ba7b8b88345c0ef2f92d89653615bff4b9d1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f647261696e65726c696768742f7068702d7064662d6465636f6d70726573736f722e737667)](https://www.php.net/)[![License: MIT](https://camo.githubusercontent.com/6c3572a1ee8577d98a641342bd3de054d166d82710451663f2fc45169d4fa077/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f647261696e65726c696768742f7068702d7064662d6465636f6d70726573736f722e737667)](LICENSE)

Converts PDF 1.5+ files that use **compressed cross-reference streams** (`/Type /XRef`) and **object streams** (`/Type /ObjStm`) into a **classic PDF 1.4** structure that parsers such as the **free parser shipped with FPDI** can read.

A **qpdf-free / Ghostscript-free** alternative: no external binaries, no PHP extensions beyond `ext-zlib`. Works on shared hosting where you can't install anything.

> This PDF document probably uses a compression technique which is not supported by the free parser shipped with FPDI.

If you have ever seen that error — this library is the fix.

---

- [Why](#why)
- [Requirements](#requirements)
- [Installation](#installation)
- [Usage](#usage)
    - [Use it with FPDI](#use-it-with-fpdi)
    - [As a library](#as-a-library)
    - [Command line](#command-line)
- [How it works](#how-it-works)
- [What's supported](#whats-supported)
- [FAQ](#faq)
- [Contributing](#contributing)
- [License](#license)

Why
---

[](#why)

Modern PDFs (produced by most current tools) store their cross-reference table and many objects **compressed**. Older, pure-PHP PDF importers — most notably the free parser bundled with [FPDI](https://www.setasign.com/fpdi) — can't read that and abort. The usual fixes require a **system binary**:

```
qpdf --object-streams=disable --stream-data=uncompress --force-version=1.4 in.pdf out.pdf
```

…which you often can't install (shared hosting, locked-down servers). This library does the same job **in pure PHP**, so you can normalize a PDF at runtime and hand it straight to FPDI.

Requirements
------------

[](#requirements)

- **PHP 7.4 or any PHP 8** — supports 7.4, 8.0, 8.1, 8.2, 8.3 (tested in CI on all of these; runs on 8.4 as well).
- `ext-zlib`

Installation
------------

[](#installation)

```
composer require drainerlight/php-pdf-decompressor
```

Usage
-----

[](#usage)

### Use it with FPDI

[](#use-it-with-fpdi)

The most common use case — normalize only when needed, then import as usual:

```
use PdfDecompressor\Normalizer;
use setasign\Fpdi\Fpdi;

$file = 'modern.pdf';

// Only rewrite the file if it uses features the free parser rejects.
if (Normalizer::isCompressed(file_get_contents($file))) {
    (new Normalizer())->normalizeFile($file, $file = 'normalized.pdf');
}

$pdf = new Fpdi();
$pdf->setSourceFile($file); // no more "compression technique not supported"
$pdf->importPage(1);
```

### As a library

[](#as-a-library)

```
use PdfDecompressor\Normalizer;

$normalizer = new Normalizer();

// File to file
$normalizer->normalizeFile('input.pdf', 'output.pdf');

// Bytes to bytes
$classicBytes = $normalizer->normalize(file_get_contents('input.pdf'));
```

### Command line

[](#command-line)

```
vendor/bin/pdf-decompress [--force] [--quiet] input.pdf output.pdf
```

Exit codes: `0` success, `1` runtime error (I/O, unreadable/encrypted PDF), `2`usage error.

How it works
------------

[](#how-it-works)

The same steps a tool like qpdf performs, implemented from the ISO 32000-1 spec:

1. **Parse** the cross-reference table — classic table *or* compressed cross-reference stream, following `/Prev` chains and hybrid `/XRefStm`.
2. **Unpack** every object, including those packed inside object streams (ObjStm).
3. **Rewrite** everything as uncompressed indirect objects with a classic cross-reference table and a minimal trailer.

If `startxref` is missing or corrupt, it **rebuilds** the cross-reference table by scanning the file for object definitions.

What's supported
----------------

[](#whats-supported)

FeatureStatusCompressed cross-reference streams (`/XRef`)✅Object streams (`/ObjStm`)✅`/Prev` chains + hybrid `/XRefStm`✅Broken / missing `startxref` (rebuild)✅Generation numbers preserved✅Encrypted PDFs (`/Encrypt`)⛔ detected &amp; rejected (no decryption)Filters other than FlateDecode (LZW, ASCII85, …)⛔ not yet`/Extends` object-stream chaining⛔ not yetSee [PLANNING.md](PLANNING.md) for the roadmap and known edge cases.

> **Not affiliated with Setasign or FPDI.** This is an independent, clean-room implementation based solely on the public ISO 32000-1 specification. "FPDI" and "qpdf" are named only to describe compatibility and purpose.

FAQ
---

[](#faq)

**How do I fix "This PDF document probably uses a compression technique which is not supported by the free parser shipped with FPDI"?**That error means the PDF uses a compressed cross-reference stream and/or object streams (PDF 1.5+). Run the file through this library first, then hand the result to FPDI — see [Use it with FPDI](#use-it-with-fpdi). No commercial add-on or system binary required.

**How can I read a PDF 1.5, 1.6 or 1.7 with FPDI's free parser?**Normalize it to a classic PDF 1.4 structure with `Normalizer::normalizeFile()` and open the output with FPDI as usual.

**How do I decompress a PDF in PHP without qpdf or Ghostscript?**This library reimplements the relevant part of `qpdf --object-streams=disable --stream-data=uncompress` in pure PHP. It only needs `ext-zlib`, so it runs on shared hosting where you can't install binaries.

**What are object streams (ObjStm) and cross-reference streams?**They are PDF 1.5+ features that pack many objects into one compressed stream and replace the classic `xref` table with a compressed one. They shrink files but break parsers that only understand the traditional cross-reference table.

**Does it decrypt password-protected PDFs?**No. Encrypted PDFs (with an `/Encrypt` dictionary) are detected and rejected with a clear error rather than producing garbage.

**Is this a replacement for the commercial FPDI PDF-Parser add-on?**It solves the same "compressed PDF won't open" problem for free, from a different angle: instead of teaching the parser to read compressed PDFs, it rewrites the PDF into a form the free parser already understands. It is an independent, clean-room project and is not affiliated with Setasign.

Contributing
------------

[](#contributing)

Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). In short: `composer install`, keep `composer test` green on PHP 7.4+, and add a test for any new behavior.

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance100

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity23

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/72e859ce5f89c699c4af4c5184a4f19e1a7ede2b71ed8247b52838a39f0f39ac?d=identicon)[drainerlight](/maintainers/drainerlight)

---

Top Contributors

[![drainerlight](https://avatars.githubusercontent.com/u/28043807?v=4)](https://github.com/drainerlight "drainerlight (13 commits)")

---

Tags

cross-reference-streamdecompressfpdifpdi-pdf-parserobjstmpdfpdf-parserphpqpdfxrefphppdffpdiqpdfdecompresspdf-parseruncompressdecompressorobject-streamobjstmxrefcross-reference-streamflatedecode

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/drainerlight-php-pdf-decompressor/health.svg)

```
[![Health](https://phpackages.com/badges/drainerlight-php-pdf-decompressor/health.svg)](https://phpackages.com/packages/drainerlight-php-pdf-decompressor)
```

###  Alternatives

[pontedilana/php-weasyprint

PHP library allowing PDF generation from an url or a html page. Wrapper for Kozea/WeasyPrint.

781.2M17](/packages/pontedilana-php-weasyprint)[setasign/fpdi-protection

A FPDI compatible version of the FPDF\_Protection script.

324.4M2](/packages/setasign-fpdi-protection)[daandesmedt/phpheadlesschrome

A PHP wrapper for using Google Chrome Headless mode. Convert URL or HTML to a PDF / screenshot. Easy to use and OOP interfaced.

92255.6k](/packages/daandesmedt-phpheadlesschrome)[kartik-v/mpdf

A PHP class to generate PDF files from HTML with Unicode/UTF-8 and CJK support. This is a fork of the official mPDF library.

38330.2k1](/packages/kartik-v-mpdf)[kiwilan/php-ebook

PHP package to read metadata and extract covers from eBooks, comics and audiobooks.

3918.3k2](/packages/kiwilan-php-ebook)[renatio/dynamicpdf-plugin

October HTML to PDF converter using dompdf library.

3013.4k3](/packages/renatio-dynamicpdf-plugin)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
