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
2.9 KiB
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 (PNGpHYs, 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 (JPEGAPP2 ICC_PROFILE, PNGiCCP) that matches the image's colour space is kept as an/ICCBasedcolour 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, orImageResolution::Embeddedfor the same behavior asfrom_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.