# image-registry _(no submodules)_ ## Purpose The `ImageRegistry` allocates and reuses PDF Image XObjects across the lifetime of a single `renderDocument` call. Each unique `ImageElement` instance maps to exactly one PDF indirect object, regardless of how many pages reference it. Per-page resource maps share the underlying object by id so a multi-page document with a repeating logo never allocates a copy per page. The module also owns the lower-level `registerImageXObject` helper that builds the canonical `/XObject /Image` dictionary, choosing `/DCTDecode` for JPEGs and `/FlateDecode` for decoded PNG RGB planes. ## Features - One PDF object per `ImageElement` (identity-keyed, not src-hash). - Per-page `pageXObjects` map populated as a side-effect of `ensure`. - JPEG passthrough via `/DCTDecode` (no recompression). - PNG RGB plane re-emission via `/FlateDecode`. - `DeviceRGB` / `DeviceGray` colour-space selection follows the decoder output. - `BitsPerComponent` carried straight from the decoded image. ## Usage: Basic ```ts import { ImageRegistry } from "@suaveplan/pdf/image-registry"; import { ImageElement, PdfWriter } from "@suaveplan/pdf"; const writer = new PdfWriter(); const registry = new ImageRegistry(writer); const pageMap = new Map(); const image = new ImageElement({ src: pngBytes, width: 100, height: 50 }); const resourceName = registry.ensure(image, pageMap); // resourceName === "Im"; pageMap now contains the entry. ``` ## Usage: Advanced ```ts import { ImageRegistry, registerImageXObject } from "@suaveplan/pdf/image-registry"; import { ImageElement, PdfWriter } from "@suaveplan/pdf"; const writer = new PdfWriter(); const registry = new ImageRegistry(writer); const logo = new ImageElement({ src: pngBytes, width: 80, height: 24 }); // Share `logo` across three pages — only one XObject is allocated. for (const pageMap of pageMaps) { registry.ensure(logo, pageMap); } // Build a JPEG XObject directly (e.g. from a pre-decoded blob). const jpegId = registerImageXObject(writer, decodedJpeg); ``` ## API Reference - `class ImageRegistry` — constructed with a `PdfWriter`. Exposes `ensure(element, pageXObjects)` which returns the `Im` resource name and side-effects the supplied per-page map. - `registerImageXObject(writer, decoded)` → `number` — low-level helper used by `ImageRegistry.ensure`. ## Implementation Notes The registry keys by `ImageElement` instance identity rather than content hash. This is intentional: callers that share the same element across pages benefit from the cache automatically, while callers that construct two `ImageElement`s with identical bytes pay for two PDF objects — the safe assumption when the bytes themselves might differ after `decodeImage` runs (e.g. PNG alpha extraction). `registerImageXObject` packs the dictionary entries in a fixed order (`/Type`, `/Subtype`, `/Width`, `/Height`, `/ColorSpace`, `/BitsPerComponent`, optional `/Filter`) so equal inputs produce byte-identical objects, preserving the writer's xref-byte-offset invariant. JPEG bytes are passed through unchanged via `"None"` because the JPEG bitstream itself is what `/DCTDecode` consumes.