mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-11 16:36:13 -06:00
Redaction doesn't decode CCITT yet, so a mark over part of a picture Create PDF stored as Group 4 removes the whole picture (nothing leaks); before this PR such pictures were eight-bit Flate and had only the covered pixels cleared. The create README and the image-to-PDF parity note say so; #4384 adds CCITT to redaction. The workspace's comment on hayro-ccitt says Export uses it, not only tests. From reviews with the pdfcraft-review skill. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P6yUtvWGPsJpMLyh6pxSXG
40 lines
2.9 KiB
Markdown
40 lines
2.9 KiB
Markdown
# pdfcraft-create
|
||
|
||
Layer L4. Create a PDF (Acrobat's Create a PDF tool), execution plan M10.2:
|
||
|
||
- `blank(width, height, pages)`: an empty document;
|
||
- `from_images(&[(name, bytes)])`: one page per image, sized from the image's resolution
|
||
(PNG `pHYs`, JPEG JFIF density; 72 dpi when absent). JPEG data is embedded as is
|
||
(`/DCTDecode`, grey, RGB or Adobe-inverted CMYK); PNG is decoded and stored with Flate,
|
||
with transparency as a soft mask. A picture of only pure black and white (a 1-bit PNG or TIFF,
|
||
eight-bit grey, a two-colour palette, RGB without a profile) is stored at one bit per pixel, as
|
||
CCITT Group 4 or Flate, whichever is smaller as stored (`pdfcraft_filters::encode_g4`).
|
||
Redaction doesn't decode Group 4 yet: a mark over part of such a picture removes the whole
|
||
picture (nothing leaks). An ICC profile in the file (JPEG `APP2 ICC_PROFILE`, PNG
|
||
`iCCP`) that matches the image's colour space is kept as an `/ICCBased` colour space with
|
||
the device space as `/Alternate`; images with the same profile share one profile object.
|
||
JPEG metadata scanning skips marker fill bytes and reads application segments after the
|
||
frame header, stopping at the first scan or end marker. Broken or mismatched ICC profiles
|
||
still fall back to the device colour space;
|
||
- `from_images_with_resolution(images, ImageResolution::Dpi(dpi))`: override the page
|
||
resolution (1–1200 dpi), without resampling or recompressing image pixels. Use 72 dpi
|
||
for one point per pixel, or `ImageResolution::Embedded` for the same behavior as
|
||
`from_images`. The largest page side is still capped at 14,400 points;
|
||
- `from_text(text, …)`: plain text set in Helvetica, wrapped and paginated. Text Helvetica
|
||
can't draw is refused, naming the line and the character, never set as `?`.
|
||
- `from_text_escaped(text, …)`: the same for reports PdfCraft generates from documents
|
||
(comment summaries, compare reports): such characters are written as `[U+XXXX]` and the first
|
||
line says so (`ESCAPED_NOTE`).
|
||
|
||
Every function returns a `pdfcraft_cos::Document`; the caller writes it.
|
||
|
||
Image export and Save Image As apply each lossless image's Decode pair before converting its color components.
|
||
Indexed Decode values select palette entries after rounding and clipping. Color-key masks compare the original samples.
|
||
Missing, null or malformed Decode arrays keep the default mapping.
|
||
Soft-mask Decode intervals map samples to opacity before the mask is resized, including reversed ranges and indirect entries.
|
||
The existing 16-bit path still uses each sample's high byte.
|
||
JPEG image Decode handling remains limited.
|
||
ICC transforms and calibrated color conversion remain outside this export path.
|
||
CCITT fax images (Group 3 and 4) are decoded for export through `hayro-ccitt` with their `/DecodeParms`
|
||
(`/Columns` has to be the image's width), behind other filters such as `ASCII85Decode` too; JPEG 2000 and JBIG2 images are still reported, not exported.
|