|
M1 (task gt0): show one image with zoom/pan.
- src/loader/detect.{c,h}: magic-byte format sniffing (JPEG/PNG/GIF/WebP/
TIFF/ICO/JXL/AVIF/HEIF) -> GgazeFormat; pure, no I/O, unit-testable.
- src/loader/loader.{c,h}: loader_load() sniffs the header and dispatches to
the first registered backend; GgazeLoaderBackend struct; pixbuf is the
fallback (last, accepts UNKNOWN). M1 ships only the pixbuf backend.
- src/loader/backends/pixbuf.c: GdkPixbufLoader decode +
gdk_pixbuf_apply_embedded_orientation (decision #26) -> GdkTexture via
gdk_memory_texture_new (avoids the deprecated gdk_texture_new_for_pixbuf).
- src/viewer.{c,h}: GgazeViewer : GtkWidget custom widget (decision #31) —
fit/100%/in/out zoom, cursor-centered zoom, drag-to-pan with clamping,
dark background, GtkSnapshot render nodes.
- src/window.c: open -> loader_load -> viewer_set_texture -> stack 'large'.
- tests: unit test_detect (13 cases) + test_loader_pixbuf (plain/rotated-EXIF
8x4 orient6->4x8/png/rgba/missing/unsupported jxl-avif-heif/corrupt),
integration test_open_and_show (fixture + rotated + ./sample-images
skip-if-absent). 6/6 green; detect 97% / loader 91% / pixbuf 87% coverage.
- fixtures: gen.py produces plain.jpg, rot6.jpg, small.png, rgba.png.
- AGENTS.md: documents the ./sample-images optional test corpus convention.
Sub-agent review fixes: use-after-free of c_name in ggaze_window_open
(BLOCKER), gtk_stack_get_pages leak in test_window (BLOCKER), coverage gap,
dead branch, viewer measure, _prefix/_cb naming, include order, extern in
header, pan clamp, stale comments — all addressed.
|
|
Phase 0 (task et0): lays the build/test/CI/convention groundwork before any
feature code.
- meson.build: project ggaze C11 -Wall -Wextra; deps gtk4/glib/gio/libadwaita;
feature options gegl/jxl/avif/heif (auto); generated ggaze-config.h with
app id, version, GGAZE_HAVE_* feature flags.
- tests: GLib g_test harness with separate unit/integration suites
(--suite unit / --suite integration); test_bootstrap sanity test proves
the harness compiles and the config header is reachable; -Db_coverage=true
coverage target wired.
- CI: .woodpecker/ci.yml three lanes (minimal, gegl, asan) with xvfb for the
integration track and a coverage lane that warns until M10.
- conventions: .clang-format (3-space, 80-col, K&R, *-on-var, return type on
its own line) + .editorconfig matching docs/coding-conventions.md; CI
clang-format --dry-run -Werror gate.
- top-level README.md (humans) and AGENTS.md (agents) pointing into docs/.
- LICENSE (GPL-3.0-or-later), .gitignore, dir placeholders.
Acceptance: meson setup build && ninja -C build && meson test -C build green;
clang-format --dry-run --Werror clean.
|