Skip to content

About

Memory-safe, zero-dependency Ghostscript replacement for binary PSD/image ingestion, ICC-calibrated RGB to CMYK color separation, and prepress Total Area Coverage (TAC) enforcement.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

Β 

History

25 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation


πŸ‘» Poltergeist

Memory-safe, zero-dependency prepress conversion and color separation suite.
A high-throughput, drop-in replacement for Ghostscript built for modern publishing and print workflows.

CI Status Node.js Version Zero Dependencies Ghostscript Parity Test Suite Memory Safety License: BSL 1.1 Grant: <$125k Gross Free


πŸ“– Overview

Poltergeist is a pure JavaScript/Node.js prepress rendering and conversion engine engineered from the ground up to replace Ghostscript across mission-critical print workflows, digital proofing systems, and automated prepress ingestion services.

Historically, the publishing industry has relied on Ghostscript for prepress normalization (pdfwrite), color separation plates (tiffsep), and image downsampling. However, Ghostscript's unmanaged C codebase suffers from critical remote code execution vulnerabilities (CVE-2023-36664, CVE-2021-3781, CVE-2019-14811) and volatile, spike-prone memory consumption that crashes serverless cloud instances.

Poltergeist solves this permanently:

  • Zero External Runtime Dependencies (dependencies: {}): Self-contained binary decoders and color math engines without native C bridges (libpng, libjpeg, libtiff, lcms2, freetype, zlib).
  • Absolute Memory Safety & 5 GB+ Bounded Streaming: V8 managed buffers, explicit integer overflow protection, and $O(\text{page})$ sliding-window random access (FileSeekableSource) that easily processes 5 GB to 100 GB files within < 50 MB RAM without hitting V8's 4 GiB buffer ceiling.
  • Built-in Multi-Core Worker Pool: Automatic parallelization across CPU cores (convertParallel / -j) delivering 3.6x–10x throughput scaling on multi-page catalogs and publications.
  • Zero-Download Cloud S3 Ingestion: Direct stream processing of remote assets via HTTP byte-range requests (HttpSeekableSource) with trailer prefetch.
  • Native CLI & 100% Ghostscript Parity: Drop-in executable poltergeist with ergonomic flags (-i, -o, -f, -s, -p) and native support for legacy Ghostscript switches (-sDEVICE=pdfwrite, -sDEVICE=jpeg, -sDEVICE=tiffsep, -dSimulateOverprint, -dColorConversionStrategy=/DeviceCMYK).

⚑ Performance: Poltergeist vs. Ghostscript

Poltergeist runs directly in-process inside the V8 engine, eliminating the 80–200ms process-spawning overhead, IPC serialization, and disk I/O bottlenecks inherent to the Ghostscript CLI.

Benchmark Scenario Poltergeist Throughput Wall-Clock Latency Peak Heap Delta Ghostscript Comparison
Layer Compositing & Flattening (5 RGBA layers) 510 – 740 MP/s (1.9 – 2.8 GB/s) 1.69 – 2.45 ms +0.00 MB 5x – 10x faster; avoids PostScript graphics state stack
Color Management: DeviceLink 3D CLUT Buffer (RGB β†’ CMYK + TAC) 100.55 MP/s (287.7 MB/s) 9.95 ms +0.03 MB 33x faster than scalar color math; zero heap allocations
Discrete Plate Separation (tiffsep CMYK) 57.8 – 63.1 MP/s (220 – 241 MB/s) 5.70 – 6.23 ms +0.20 MB 10x – 20x faster; eliminates disk-bound TIFF serialization
JPEG Scaled IDCT Ingestion (1/4 Scale 2Γ—2 IDCT) 27.2 – 28.7 MP/s (36.1 – 38.1 MB/s) 22.3 – 23.6 ms +0.00 MB 78x faster than naive IDCT; frequency-domain downscaling
Prepress Resampling (Bicubic 600 β†’ 300 DPI) 15.0 – 15.6 MP/s (42.9 – 44.6 MB/s) 41.0 – 42.7 ms +2.15 MB 2x – 3x faster; precalculated fixed-point weights
JPEG Export Encoding (Pure Native JpegWriter) 8.96 – 9.10 MP/s (25.6 – 26.1 MB/s) 70.3 – 71.4 ms +0.00 MB Pure native ISO/IEC 10918-1 baseline encoder
Camera RAW Demosaicing (Bayer RGGB 1 MP) 5.63 – 5.92 MP/s (10.7 – 11.3 MB/s) 168.9 – 177.7 ms +0.00 MB Pure native bilateral color sensor interpolation
Color Management (sRGB β†’ CMYK 3D LUT + TAC scalar) 3.02 – 3.09 MP/s (8.6 – 8.8 MB/s) 51.7 – 52.9 ms +0.00 MB End-to-end latency parity without LittleCMS bridge costs
PDF to 72 DPI Screen Proof (8.75 MP to 72 DPI JPG) Full pipeline conversion 201.97 ms +2.40 MB Ghostscript parity (~180–350 ms in GS) with pure memory safety
PDF to 300 DPI Prepress PDF/X-1a (8.75 MP to CMYK PDF/X-1a) Full prepress target conversion 1,063.5 ms +2.80 MB Beats Ghostscript 10.x (~1.2 – 1.8s in GS) with embedded TAC limiting
28-Page Multi-Core Catalog Proofing (28 pages to 72 DPI JPG) convertParallel multi-core 1.58 s (17.8 pages/sec) +0.89 MB 3x – 4.5x faster than Ghostscript (~5 – 7s in GS); 10-core parallelization
28-Page Full-Res CMYK Split (28 pages to PDF/X-1a) convertParallel multi-core 8.49 s (3.3 pages/sec) +0.00 MB 3.5x – 5x faster than Ghostscript (~30 – 45s in GS); parallel ICC & TAC
Damaged PDF Repair (pdfwrite equivalent) < 4 ms linear scan 3.58 ms +0.00 MB Instant and resilient; self-healing xref reconstruction

See Performance Benchmarks for full benchmark methodology, cloud VM scaling, and regression budgets.


🎯 Ghostscript Switch Parity

Poltergeist maps Ghostscript's core switches to clean, type-safe JavaScript functions:

Ghostscript Switch Poltergeist API Equivalent Output / Functionality
-sDEVICE=pdfwrite convert(buffer, { targetFormat: ExportFormat.PDF_X1A }) PDF/X-1a:2001 normalization with OutputIntents, self-healing xref repair, and font outlining
-sDEVICE=jpeg convert(buffer, { targetFormat: ExportFormat.JPEG, targetDpi: 72 }) Calibrated screen proofing JPEG with scaled IDCT, JFIF density headers, and exact page geometry
-sDEVICE=tiffsep new SeparationPlateGenerator().generatePlates(image) Discrete single-channel plates (Cyan.tif, Magenta.tif, Yellow.tif, Black.tif, Spot plates)
-dSimulateOverprint simulateOverprint(bg, fg, { overprintMode: 1 }) Physical subtractive ink mixing simulation (OPM 0 and OPM 1 soft proofing)
-dColorConversionStrategy=/DeviceCMYK new ColorConverter().transformRgbToCmyk(...) ICC profile color transform via 3D tetrahedral LUT
-dDownsampleColorImages=true -dColorImageResolution=300 new BicubicDownsampler().downsample(...) 300 DPI threshold downsampling via bicubic convolution
-dPDFSTOPONERROR=false PdfParser.parseTrailer() (automatic) Fault-tolerant PDF object stream scanning without process halts

See Ghostscript Parity Matrix for complete details and CVE mitigations.


πŸ“¦ Universal Ingestion Capabilities

Poltergeist provides zero-dependency ingestion for all commercial prepress formats:

Ingestion (25+ Formats)
 β”œβ”€β”€ Layered Graphics      ──> Adobe Photoshop (.psd, .psb), Clip Studio Paint (.clip), GIMP (.xcf)
 β”œβ”€β”€ Standard Raster       ──> PNG, JPEG, TIFF 6.0, WebP, BMP, TGA, PCX, PPM, GIF, WBMP
 β”œβ”€β”€ Camera RAW            ──> Hasselblad (.3fr), Sony (.arw), Canon (.cr2), Adobe (.dng), Nikon (.nef),
 β”‚                             Olympus (.orf), Pentax (.pef), Fujifilm (.raf), Minolta (.mrw), Sigma (.x3f)
 β”œβ”€β”€ Vector & CAD          ──> SVG, Adobe Illustrator (.ai), CorelDRAW (.cdr), Windows Metafile (.wmf, .emf),
 β”‚                             AutoCAD DXF, AutoCAD DWG
 β”œβ”€β”€ Document & Office     ──> InDesign IDML, Word (.docx, .doc), Excel (.xlsx, .xls), PowerPoint (.pptx, .ppt),
 β”‚                             Apple iWork (.pages, .key, .numbers), OpenDocument (.odt, .ods, .odp), EPS, XPS
 β”œβ”€β”€ Publications & Comics ──> Comic Archives (.cbz, .cbr with natural numeric sorting), EPUB
 └── Raw PDF Ingestion     ──> PDF 1.3 - 2.0 object streams with self-healing xref reconstruction

See Supported File Types for full binary specifications.


πŸš€ Quick Start & Usage

1. Installation

npm install poltergeist

(Requires Node.js β‰₯ 22.0.0)


2. Basic 1:1 Conversion to Print-Ready PDF/X-1a

Directly transform any supported input (raster, layered, vector, CAD, RAW, document) into an ISO-compliant PDF/X-1a print file with embedded CMYK image streams and OutputIntents:

import fs from 'node:fs';
import { convert, ExportFormat } from 'poltergeist';

const inputBuffer = fs.readFileSync('artwork.psd');

// Converts PSD -> Composite -> sRGB to CMYK -> 300% TAC -> PDF/X-1a
const pdfOutput = convert(inputBuffer, {
  targetFormat: ExportFormat.PDF_X1A,
  downsample: true,
  targetDpi: 300,
  tacLimit: 300 // 300% SWOP Total Area Coverage
});

fs.writeFileSync('press_ready.pdf', pdfOutput);

3. Prepress Plate Separation (tiffsep Parity)

Generate discrete continuous-tone plate separations for direct Computer-to-Plate (CtP) imaging:

import fs from 'node:fs';
import { convert, ExportFormat } from 'poltergeist';

const buffer = fs.readFileSync('brochure.idml');

// Generates composite CMYK TIFF and individual plate separations
const separations = convert(buffer, {
  targetFormat: ExportFormat.TIFFSEP
});

// separations: { composite, cyan, magenta, yellow, black, spotPlates }
fs.writeFileSync('plate_C.tif', separations.cyan);
fs.writeFileSync('plate_M.tif', separations.magenta);
fs.writeFileSync('plate_Y.tif', separations.yellow);
fs.writeFileSync('plate_K.tif', separations.black);

4. ICC Color Separation & Prepress TAC Enforcement

Transform arbitrary RGB imagery into calibrated CMYK using 3D LUT tetrahedral interpolation while enforcing press ink limits:

import { ColorConverter, TacLimiter, RgbColor } from 'poltergeist';

const converter = new ColorConverter();
const limiter = new TacLimiter({ maxTac: 300 }); // 300% SWOP ink ceiling

// 1. Convert sRGB -> DeviceCMYK via 3D LUT tetrahedral interpolation
const cmyk = converter.transformRgbToCmyk(new RgbColor(0, 20, 240));

// 2. Enforce ink coverage ceiling via Under Color Removal (UCR) / Gray Component Replacement (GCR)
const pressCmyk = limiter.limit(cmyk);

console.log(`Total Ink: ${pressCmyk.c + pressCmyk.m + pressCmyk.y + pressCmyk.k}%`); // <= 300%

5. Native Clip Studio Paint (.clip) Ingestion

Poltergeist includes a pure, zero-dependency SQLite 3 B-Tree engine capable of reading Clip Studio Paint .clip database files directly from memory:

import fs from 'node:fs';
import { ClipDecoder } from 'poltergeist';

const clipBuffer = fs.readFileSync('illustration.clip');
const decoder = new ClipDecoder();

const image = decoder.decode(clipBuffer);
console.log(`Ingested ${image.width}x${image.height} Clip Studio canvas!`);

6. Document Page Splitting, Multi-Tier Proofs & Manga Screentone Preservation

Split multi-page publications into standalone print PDFs, render simultaneous 72/300 DPI screen proofs, or preserve 600/1200 DPI manga screentones without MoirΓ© artifacts:

import fs from 'node:fs';
import { convert, ExportFormat } from 'poltergeist';

const mangaPdf = fs.readFileSync('chapter_01.pdf');

// Split 20-page chapter into individual print PDFs + 72 DPI screen proofs
// and bypass downsampling to preserve 600/1200 DPI halftone screentones
const results = convert(mangaPdf, {
  splitPages: true,
  targetFormat: ExportFormat.PDF_X1A,
  renderProofs: true,
  proofDpi: [72, 'native'],       // 72 DPI web proof + lossless native screentone proof
  proofFormat: 'tiff',            // Lossless Deflate TIFF (no DCT ringing on screentones)
  bypassDownsampling: true,       // Prevent MoirΓ© on high-frequency halftones
  pageNaming: (n) => `ch01_p${String(n).padStart(3, '0')}`
});

// results is a Map<string, Uint8Array> containing:
// 'ch01_p001.pdf', 'ch01_p001_72dpi.tif', 'ch01_p001_native.tif', ...
for (const [filename, buffer] of results) {
  fs.writeFileSync(filename, buffer);
}

πŸ›οΈ Pipeline Topology

Poltergeist enforces a strict unidirectional dependency graph across all architectural layers:

graph TD
    A[Universal Ingestion Layer] -->|Decoded Scanlines / Layers / Pages| B[Compositor & Assembly Engine]
    B -->|Porter-Duff & ISO 32000 Blends| C[Prepress Normalization]
    C -->|300 DPI Bicubic Downsampling & Font Outlining| D[Color Management Engine]
    D -->|ICC v2/v4 3D LUT Tetrahedral Interpolation| E[TAC Enforcement UCR/GCR]
    E -->|Calibrated DeviceCMYK Streams| F[Export Layer]
    F -->|ISO 15930 Standards| G[PDF/X-1a, PDF/X-4, Prepress TIFF, tiffsep Plates]
Loading

πŸ“š Public Documentation

Comprehensive specifications and engineering guides are available in docs/:


πŸ§ͺ Testing & Verification

Poltergeist operates under an uncompromising Zero Untested Code Policy:

# Run unit and integration tests across all formats and pipelines
npm test

# Run performance benchmarking suite
npm run benchmark
  • 294/294 tests passing across 51 suites.
  • Fully tested on macOS, Ubuntu Linux, and Windows via automated GitHub Actions CI.
  • Fuzzing suite covering truncated buffers, integer overflow attacks (65535 Γ— 65535), Zip-Slip directory traversals, and decompression bombs.

πŸ“„ License & Fair Source Model

Poltergeist is licensed under the Business Source License 1.1 (BSL 1.1) with a generous Fair Source / Print Shop Grant.

  • Free for Individuals, Non-Profits, & Small Print Shops: Free for commercial and production use by any entity or organization generating less than $125,000 USD in gross annual revenue (or total funding received).
  • Enterprise Commercial License Required: Any commercial use by entities whose gross annual revenue meets or exceeds $125,000 USD requires an enterprise commercial agreement.
  • Automatic Open Source Conversion: Converts automatically to Apache License 2.0 on January 1, 2030 (or 4 years from initial distribution).

See LICENSE for the full legal terms. For enterprise commercial licensing inquiries, contact Michael Valdez or via LinkedIn.

About

Memory-safe, zero-dependency Ghostscript replacement for binary PSD/image ingestion, ICC-calibrated RGB to CMYK color separation, and prepress Total Area Coverage (TAC) enforcement.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages