Ctrl K
ComunidadGuías…

vlib/image/decoders/development.md

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# image.decoders — development guide

This document describes how the decoders are structured, how to build and
test them, and how to maintain them. It describes the V implementation
only.

## Architecture

One package per codec, one `.v` file per package. Codec packages depend
only on `image.decoders.common` (plus stdlib); the dispatcher depends on
all of them. The import graph has no cycles:

```text
decoder -> {jpeg, png, bmp, webp, tiff, gif} -> common
```

Shared types live in `common`:

- `Image`: decoded image, `width`, `height`, `rgba []u8` (top-down,
  straight alpha, 4 bytes per pixel).
- `Frame` / `Animation`: coalesced animation frames with `delay_ms`,
  `disposal`, and `loop_count`.
- `BitReader`: LSB-first and MSB-first bit reader shared by all decoders.

Conventions:

- Decoders are pure: they take `[]u8` and return `!Image` / `!Animation`.
  No global state, no file access (except `decoder.decode_file`).
- Errors are reported with V results and descriptive messages that name
  the failing structure (chunk, marker, tag, ...).
- Malformed input must produce an error, never a panic or an out-of-bounds
  read. Bounds are checked before every read.
- Large scratch buffers are reused through the per-decoder arena pattern
  (see `bmp.v`) so repeated decoding does not churn memory.
- Bit accumulation is written as `x * (1 << k)` instead of `x << k`.
  The checker warns that shifting a signed `int` can change the sign;
  multiplication by a power of two is identical in two's complement and
  keeps the build silent. Keep this style in new code.
- The JPEG arithmetic decoder keeps the full JPEG-spec parameter list
  (`ss`/`se`/`ah`/`al`/`ci`) on every variant for symmetry with the
  Huffman path. Parameters a given variant does not use are prefixed
  with `_` (for example `_se`, `_ah`, `_ci`) to silence the unused
  parameter notice; do not drop them from the signature.

## Layout

```text
vlib/image/decoders/
  README.md      module front page
  CODEC.md       supported features per codec
  development.md this file
  common/        shared types and BitReader
  decoder/       magic-byte dispatcher
  jpeg/          jpeg.v, jpeg_test.v, testdata/
  png/           png.v,  png_test.v,  testdata/
  bmp/           bmp.v,  bmp_test.v,  testdata/
  webp/          webp.v, webp_test.v, testdata/
  tiff/          tiff.v, tiff_test.v, testdata/
  gif/           gif.v,  gif_test.v,  testdata/
```

## Testing

Each codec package is fully self-contained: its tests and its test data
live in the same directory.

```sh
v test vlib/image/decoders/        # all codecs
v test vlib/image/decoders/webp/   # one codec
```

Test data conventions, per codec directory:

- `testdata/<name>.<ext>`: the encoded fixture (`jpg`, `png`, `webp`, ...).
- `testdata/<name>.rgba`: the expected raw RGBA bytes (the golden).
- `testdata/<name>.txt`: one line of metadata, at least `width height`,
  sometimes more (frame counts, geometry parameters) depending on codec.
- Animation goldens use `<name>_frame_NNN.rgba` (or `_fN.rgba` for WEBP).

Tests resolve data through `@DIR`, so they work regardless of the current
working directory.

### Removing test data

Test data is intentionally kept per codec so it can be pruned cheaply:

- Deleting a codec's `testdata/` directory and its `*_test.v` file is
  sufficient and independent of every other codec.
- Nothing outside a codec directory references its `testdata/`.
- If a codec's tests are removed, keep the decoder source: the golden
  files can be regenerated later.

## Future work

- Prune or slim down the binary testdata (it is the largest part of the
  package) once a smaller representative set is agreed on.
- Consider exposing decoded images as `image.RGBA` buffers instead of
  plain `[]u8`.
- Optional: register formats with `image.register_format` so the base
  `image` module can decode through the dispatcher.