Skip to content

Review before 0.3.0: the caller's cursor for resources, psd-tools' files in CI - #11

Merged
ShadobaDev merged 11 commits into
masterfrom
review/pre-0.3.0
Oct 23, 2026
Merged

ShadobaDev merged 11 commits into
masterfrom
review/pre-0.3.0

Conversation

@ShadobaDev

Copy link
Copy Markdown
Owner

Fixes from the review before 0.3.0 freezes the API (S4.10, now after S7.1).

Changes

  • API (breaking, before 0.3.0). minipsd_reader_next_resource(r, &pos, &res) takes the
    caller's cursor, as every other walk does: the reader is only read, so resources can be walked
    again and from several threads. minipsd_read no longer restarts the reader to copy them.
  • Header. The typed views get their own section; find_resource sits beside
    next_resource; comments the code outgrew are fixed (ZIP output, MINIPSD_ERR_ARG,
    MINIPSD_ERR_FORMAT, the mask's depth).
  • Spec. Names gain two rules: what types follow (the file's width, or int for what the
    caller asks) and who holds a walk's cursor.
  • Roadmap. S6.13's write half moves to a new S6.19 (every mode written), which the saver
    needs; S4.10 waits for S7.1.
  • CI. linux-gcc now fetches psd-tools' 315 files. Until now every comparison with
    psd-tools (every mode, ZIP, resources, layer blocks) ran only locally.
  • Docs. README lists the metadata it reads; CHEATSHEET gains linux-tsan; CODE-ARCH gains
    a typed-views row.

… 0.3.0

minipsd_reader_next_resource takes a size_t *pos, as every other walk does:
the reader is only read, a list can be walked again and from several
threads, and minipsd_read no longer restarts the reader to copy resources.
The header groups the typed views in their own section; comments the code
outgrew are fixed. S6.13's write half moves to S6.19; S4.10 waits for S7.1.
Every comparison with psd-tools (layers and composites of every mode,
Photoshop's ZIP files through zlib, resources, layer blocks, resource
names) ran only locally: MINIPSD_PSD_TOOLS_FILES was off in every job.
linux-gcc now fetches the 315 files (22 MB, pinned by hash) and runs
the round trip and the reader tests over them.
examples/vips_composite.c flattens layers with vips_composite (blend keys
mapped, opacity into alpha, hidden layers out), writes the document with
that composite and reads it back as its check. MINIPSD_VIPS_EXAMPLE builds
it: Windows fetches libvips' prebuilt build pinned to 8.18.7, elsewhere
pkg-config. CI's msvc job runs it; locally it also runs on a Photoshop
fixture. A "With libvips" chapter in the manual.
Version 0.3.0 in minipsd.h, the changelog section dated, COMPATIBILITY.md
regenerated (no change but the version). The roadmap says S6.19 is about
writing, reading every mode being done, and sets stage 7's way: a libvips
plugin in libvips-plugin/ first, a pull request to libvips at the end.
…19, 1)

MINIPSD_MODE_* names the header's colour modes for minipsd_info and the
document alike; minipsd_doc gains color_mode (0 is RGB, bitmap with depth
1) and color_mode_data, which minipsd_read fills. minipsd_layer.rgba is
pixels: the mode's channels then transparency. The writer still takes RGB
only; RGB output is byte-identical. vips_composite flushes its result
before libvips' exit, which on Windows does not always do it.
A layer's channels follow the document's mode: transparency, the mode's
colour channels, the masks; stored channels as the layer view lays them
out. A composite in another mode than RGB is the caller's, written as
given; duotone brings its colour mode data. The file size now counts the
colour mode data. roundtrip.py writes every mode at 8 and 16 bits, RLE
and ZIP, and checks every sample through psd-tools and minipsd's reader.
Samples of 1, 2 or 4 bytes go through one path; at 32 bits they are
floats, shuffled before ZIP's prediction. A 32-bit document's layers go
in an 'Lr32' block, an empty 'Mt32' before it when the composite has
transparency, the layer info empty, as Photoshop writes them; its
composite is the caller's, matted in floats in RGB. roundtrip.py checks
both modes, RLE and ZIP, through psd-tools and minipsd's reader.
…, 4)

Bitmap is the only 1-bit mode: its composite is a byte a pixel (0 white,
any other black), packed by the writer; indexed brings its 768-byte
palette in color_mode_data; multichannel's composite is only copied from
composite_stored. The flat modes take no layers and no transparency.
mpsd__mode_ok moves to samples.h for the writer's use.
minipsd_read now reads every colour mode and depth the writer takes, at
the file's mode and depth, with its colour mode data. A file the writer
could not take back (32-bit CMYK, layers in a flat mode) is refused up
front by the writer's own mode check. Flat modes get no "Background"
layer, and a multichannel composite is always copied as stored.

Two writer fixes found on psd-tools' files:
- mpsd__stored_ok counts a row's bytes by depth, so a stored 1-bit
  composite is accepted.
- At 32 bits, colour mode data is written as given: psd-tools' 32-bit
  files hold an 'hdrt' block (HDR toning).

The psd-tools round trip now reads and writes back 314 of 315 files
(was 252), with every colour mode and depth decoded, stored and
converted. Docs describe every mode written; S6.19 is ticked.
A 32-bit document's layers come back in Lr32 with the float composite
matted on the way out; a bitmap's bytes come back packed eight to a byte,
including a width that is not a multiple of eight. Written back, the same
content; a second pass changes no byte.
minipsd_doc_check refuses ZIP without opts->deflate, but the analyzer
does not connect that check to the call in mpsd__zip_channel and reports
a null function pointer (core.CallAndMessage). The check is now explicit
at the call.
@ShadobaDev
ShadobaDev merged commit 6f1d55e into master Oct 23, 2026
9 checks passed
@ShadobaDev
ShadobaDev deleted the review/pre-0.3.0 branch October 27, 2026 00:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant