qpdf-compress 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +124 -0
- package/package.json +6 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [0.4.0] - 2026-03-31
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Grayscale detection**: automatically converts RGB images where R==G==B to DeviceGray (3× raw data reduction)
|
|
12
|
+
- **Bitonal conversion**: converts 8-bit grayscale images that are effectively B&W to 1-bit (8× raw data reduction)
|
|
13
|
+
- **TrueType font subsetting**: strips unused glyph outlines from `/FontFile2` font programs via custom binary parser (cmap format 0/4, composite glyph dependency resolution, glyf/loca/hmtx table rebuilding)
|
|
14
|
+
- **Soft mask optimization**: losslessly optimizes JPEG `/SMask` transparency streams
|
|
15
|
+
- **ICC profile stripping**: replaces ICCBased color spaces with Device equivalents on images and page resources
|
|
16
|
+
- **Form flattening**: stamps widget annotation appearances into page content and removes `/AcroForm`
|
|
17
|
+
- **Page tree flattening**: pushes inherited attributes to individual pages for optimal QPDFWriter output
|
|
18
|
+
- **Content stream coalescing**: merges multiple content streams per page into one
|
|
19
|
+
- **Content stream minification**: normalizes whitespace and trims numeric formatting (trailing/leading zeros)
|
|
20
|
+
- **Non-image stream deduplication**: deduplicates identical font, ICC, and other non-image streams via FNV-1a hash + full byte comparison
|
|
21
|
+
- **Embedded file stripping**: removes `/EmbeddedFiles` from the document name tree
|
|
22
|
+
- **JavaScript removal**: strips `/OpenAction`, `/AA`, and `/JavaScript` from catalog, pages, and annotations
|
|
23
|
+
- **Accurate DPI calculation**: content stream CTM matrix parser (~170 lines) tracks `q`/`Q`/`cm`/`Do` operators to find actual rendered image dimensions, with MediaBox fallback
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- **Grayscale JPEG inflation**: `convertGrayscaleImages` now skips DCTDecode images — previously replacing JPEG with raw gray + Flate inflated photographic images 2–4× in lossless mode
|
|
28
|
+
- **Font subset size comparison**: compares uncompressed sizes instead of uncompressed subset vs Flate-compressed original
|
|
29
|
+
- **Stream dedup safety**: `deduplicateStreams` now checks `/DecodeParms` equality — identical raw bytes with different decode parameters produce different content
|
|
30
|
+
- **Content stream decoding**: decoded once per page in `subsetFonts` instead of redundantly per font
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- Split `images.cc` into `images.cc` (image operations) and `optimize.cc` (structural optimizations)
|
|
35
|
+
- Added `font_subset.cc`/`font_subset.h` for TrueType binary parsing
|
|
36
|
+
- Source: 5 `.cc` files, 4 headers, ~3000 lines total
|
|
37
|
+
|
|
38
|
+
## [0.3.0] - 2026-03-30
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- **BREAKING**: Replaced `mode: 'lossy' | 'lossless'` with `lossy?: boolean` (default `false`)
|
|
43
|
+
- **BREAKING**: Removed `quality` parameter — quality is now automatically determined per mode
|
|
44
|
+
- **BREAKING**: Removed `maxDpi` parameter — DPI is now automatically determined per mode
|
|
45
|
+
- **BREAKING**: Options parameter is now optional — `compress(input)` defaults to lossless
|
|
46
|
+
- Lossless: pure structural optimization — no image re-encoding or downscaling
|
|
47
|
+
- Lossy: skip images at q ≤ 65, re-encode at q75, downscale to 72 DPI
|
|
48
|
+
|
|
49
|
+
## [0.2.0] - 2026-03-30
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
|
|
53
|
+
- CMYK → RGB conversion for JPEG images
|
|
54
|
+
- ICCBased color space support (extracts and converts embedded ICC profiles)
|
|
55
|
+
- PNG optimization (re-encodes as JPEG when beneficial)
|
|
56
|
+
- DPI downscaling (configurable max DPI, default 75)
|
|
57
|
+
- Metadata stripping (XMP, document info, thumbnails) — enabled by default
|
|
58
|
+
- Unused font removal
|
|
59
|
+
- Auto quality mode — estimates existing JPEG quality and skips re-encoding when already below target
|
|
60
|
+
|
|
61
|
+
## [0.1.3] - 2026-03-30
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- Included `<cstdio>` before `<jpeglib.h>` for Linux compatibility
|
|
66
|
+
- Restored Node 20 to CI matrix (matching engines `>=20.11.0`)
|
|
67
|
+
- Used static import for `Readable` instead of dynamic `import()`
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
|
|
71
|
+
- Build provenance attestation for prebuilt binaries via `actions/attest-build-provenance`
|
|
72
|
+
|
|
73
|
+
## [0.1.2] - 2026-03-30
|
|
74
|
+
|
|
75
|
+
### Fixed
|
|
76
|
+
|
|
77
|
+
- Fixed Linux cross-build tarball structure (prebuilds now install correctly)
|
|
78
|
+
- Fixed Debian Bookworm cross-builds (use `libjpeg62-turbo-dev` package)
|
|
79
|
+
- Moved `setjmp` before `jpeg_create_*` calls to prevent UB on allocation failure
|
|
80
|
+
- Used `uint64_t` for FNV-1a image dedup hash (correct on 32-bit ARM)
|
|
81
|
+
- Added component count validation in `encodeJpeg`
|
|
82
|
+
- Wrapped web `ReadableStream` with `Readable.fromWeb()` in install script
|
|
83
|
+
- Made `strerror` calls thread-safe by copying to `std::string`
|
|
84
|
+
|
|
85
|
+
### Changed
|
|
86
|
+
|
|
87
|
+
- Bumped minimum Node.js version to 20.11.0 (`import.meta.dirname` requirement)
|
|
88
|
+
- Updated CI matrix to Node 22 and 24
|
|
89
|
+
|
|
90
|
+
## [0.1.1] - 2026-03-30
|
|
91
|
+
|
|
92
|
+
### Changed
|
|
93
|
+
|
|
94
|
+
- Replaced stb_image_write with libjpeg-turbo for lossy JPEG encoding (better quality per byte)
|
|
95
|
+
- Split monolithic `qpdf_addon.cc` into focused modules: `jpeg.cc`, `images.cc`, `qpdf_addon.cc`
|
|
96
|
+
- Extracted shared `forEachImage()` template helper
|
|
97
|
+
- Bumped minimum Node.js version to 20.11.0
|
|
98
|
+
|
|
99
|
+
### Fixed
|
|
100
|
+
|
|
101
|
+
- Removed global mutex that serialized concurrent compress() calls
|
|
102
|
+
- Isolated setjmp/longjmp in C-style functions to avoid UB with C++ destructors
|
|
103
|
+
- Fixed prebuild tarball structure so install script finds the .node file
|
|
104
|
+
- Added mode validation (reject invalid mode strings)
|
|
105
|
+
|
|
106
|
+
## [0.1.0] - 2026-03-30
|
|
107
|
+
|
|
108
|
+
### Added
|
|
109
|
+
|
|
110
|
+
- Native PDF compression via QPDF 12.3.2 with single `compress()` API
|
|
111
|
+
- Flate compression (level 9) for all streams
|
|
112
|
+
- Lossless JPEG optimization via libjpeg-turbo
|
|
113
|
+
- Image deduplication (content-hash based)
|
|
114
|
+
- PDF repair merged into compress pipeline
|
|
115
|
+
- Prebuilt binaries for macOS (arm64, x64), Linux glibc (x64, arm64, arm), Linux musl (x64, arm64), Windows (x64, arm64)
|
|
116
|
+
- Automatic prebuild download with source compilation fallback
|
|
117
|
+
- N-API addon for ABI stability across Node.js versions
|
|
118
|
+
|
|
119
|
+
### Infrastructure
|
|
120
|
+
|
|
121
|
+
- CI matrix: 3 OS × 3 Node versions (20, 22, 24)
|
|
122
|
+
- Release pipeline with prebuild generation and npm provenance
|
|
123
|
+
- QEMU-based cross-compilation for Linux arm64/arm and musl variants
|
|
124
|
+
- vcpkg integration for Windows static linking
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qpdf-compress",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Native PDF compression for Node.js, powered by QPDF",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -38,7 +38,10 @@
|
|
|
38
38
|
"src",
|
|
39
39
|
"lib",
|
|
40
40
|
"scripts",
|
|
41
|
-
"binding.gyp"
|
|
41
|
+
"binding.gyp",
|
|
42
|
+
"README.md",
|
|
43
|
+
"CHANGELOG.md",
|
|
44
|
+
"LICENSE"
|
|
42
45
|
],
|
|
43
46
|
"repository": {
|
|
44
47
|
"type": "git",
|
|
@@ -88,4 +91,4 @@
|
|
|
88
91
|
"typescript-eslint": "^8.57.2",
|
|
89
92
|
"vitest": "^4.1.2"
|
|
90
93
|
}
|
|
91
|
-
}
|
|
94
|
+
}
|