Skip to main content

pypixelpack

Pixel layouts and wire encodings for video I/O, device-free.

The bytes a video frame becomes on a wire — v210, r210, the ST 2110-20 pgroup — and the encoding between a frame's RGB and those bytes: colour matrix, range, chroma subsampling. Written once against a caller-supplied array namespace, so the same source packs on numpy for a host frame and on torch for a frame that never leaves a GPU.

Extracted from pydecklink's packing module and a GPU render pipeline's colorspace node, which held the same layout twice. This repository's SPEC.md and ROADMAP.md govern the package.

Installation

uv add pypixelpack

numpy is the only dependency. torch is a namespace the caller supplies, never a dependency of this package (§spec:backend).

Usage

import numpy as np
from pypixelpack import decode, encode, pack, unpack

rgb = np.zeros((1080, 1920, 3), dtype=np.float32)  # [R, G, B] in [0, 1]
codes = encode(rgb, subsampling="422")  # (H, W, 3) uint16 [Y, Cb, Cr]
data = pack(codes, "v210", row_bytes=5120)  # 1-D uint8, DMA-ready
back = unpack(data, "v210", width=1920, height=1080, row_bytes=5120)
rgb_again = decode(back, subsampling="422")  # float32 [R, G, B] in [0, 1]

On a GPU host, pass the namespace and the arrays stay resident:

import torch

codes = encode(rgb_on_cuda, subsampling="422", xp=torch)
data = pack(codes, "v210", row_bytes=5120, xp=torch)

API

  • pack(pixels, layout, row_bytes, *, xp=numpy) — (H, W, channels) integer samples to a 1-D uint8 buffer of H × row_bytes in layout, on the input's device (§spec:layouts). RGB layouts take [R, G, B]; v210 and 2vuy take [Y, Cb, Cr] with chroma read from even columns; ay10 takes [Y, Cb, Cr, A] with a per-pixel alpha.
  • unpack(data, layout, width, height, row_bytes, *, xp=numpy) — the inverse; unpack(pack(x)) == x for every layout. Returns uint8 for 8-bit layouts and uint16 otherwise.
  • row_bytes(layout, width) — the smallest row_bytes that holds a line.
  • channels(layout) — 3, or 4 for a layout in ALPHA_LAYOUTS.
  • LAYOUTS — the layout table, name → (pixels per group, bytes per group, bit depth): argb, bgra, r210, r10b, r10l, v210, 2vuy, r12b, r12l, ay10.

pack raises ValueError for an unknown layout, a row_bytes shorter than the packed line, or a sample above the layout's bit depth; the last check is skipped under torch.compile, where a compiled caller trusts its own inputs (§spec:backend).

Encoding

  • encode(rgb, *, matrix="bt709", levels="narrow", layout=None, bits=None, subsampling=None, xp=numpy) — (H, W, 3) float RGB in [0, 1] to (H, W, 3) uint16 [Y, Cb, Cr] (§spec:encoding). matrix is bt709 or bt2020; levels is narrow (luma 16–235, chroma 16–240 at 8 bits, shifted up by bits - 8) or full. layout="v210" selects the depth and subsampling that wire format expects — 10-bit 4:2:2; 2vuy is 8-bit 4:2:2 — and a bits or subsampling that contradicts it is refused; without a layout they default to 10 and 444. 422 averages chroma over each horizontal pair and writes it to both pixels, the shape pack reads. Rounding is half to even, arithmetic is float32 on every backend, and codes clamp to the level range's span.
  • decode(ycbcr, *, matrix, levels, layout=None, bits=None, xp=numpy) — the inverse, per pixel, to within half a code per component; returns float32 RGB clamped to [0, 1].
  • encoding_for(layout) — the (bits, subsampling) a layout carries; ENCODINGS is the table behind it.
  • legal_codes(*, levels="narrow", bits=10) — the (luma, chroma) code spans as range objects; len(legal_codes().luma) is 877, the levels 10-bit narrow range can represent.
  • MATRICES — name → (KR, KB): bt709, bt2020.

encode and decode raise ValueError for an unknown matrix, levels or subsampling, a bits outside 8–16, or a layout with no component encoding.

Development

uv sync
uv run ruff format --check . && uv run ruff check . && uv run pyright && uv run pytest

uv sync installs torch (CPU) into the dev group so the parity suite runs; without it those tests skip. To prove the wheel on numpy alone:

uv build
uv run --isolated --no-project --with dist/*.whl python tools/check_core_install.py

License

BSD-3-Clause. See LICENSE.

Release files for pypixelpack 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pypixelpack 0.3.0
File Size Uploaded
pypixelpack-0.3.0.tar.gz 57.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pypixelpack 0.3.0
File Interpreter ABI Platform
pypixelpack-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 73.2 kB

Release files / pypixelpack-0.3.0.tar.gz

Download URL pypixelpack-0.3.0.tar.gz
Size 57.4 kB
Tags Source
SHA-256 checksum
How to use checksums
252a1983a32d744bca3d4e48225f6c77ad7d5e13f814d8202fc7972e25a4ca50
BLAKE2b-256 checksum
How to use checksums
4de2f371a20adce1cd1111c99220b167217f1d64a5f36a1ab3e781dd1132e2e7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pypixelpack-0.3.0-py3-none-any.whl

Download URL pypixelpack-0.3.0-py3-none-any.whl
Size 15.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
908d8110549959f33ffd6c41615a1493672f77527e381834aa77bb8580409712
BLAKE2b-256 checksum
How to use checksums
b1b4b1215ce38a5bd67a00c04304ff0ad36e3d5b63ac041a31e41ab679572c12
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page