Metadata-Version: 2.4
Name: pixtreme
Version: 1.0.1
Summary: GPU-first image processing library for Python, built on CUDA and CuPy
Project-URL: repository, https://github.com/sync-dev-org/pixtreme
Project-URL: issues, https://github.com/sync-dev-org/pixtreme/issues
Author-email: minamik <mia@sync.dev>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: GPU :: NVIDIA CUDA :: 12
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.12
Requires-Dist: cupy-cuda12x[ctk]>=13.4.1
Requires-Dist: freetype-py>=2.5.1
Requires-Dist: numpy
Requires-Dist: nvidia-nvimgcodec-cu12>=0.8
Requires-Dist: nvidia-nvjpeg-cu12>=12.4.0.76
Requires-Dist: nvidia-nvjpeg2k-cu12>=0.11.0.51
Requires-Dist: nvidia-nvtiff-cu12>=0.8.0.82
Requires-Dist: openexr>=3.4
Requires-Dist: pydantic>=2.9
Requires-Dist: uharfbuzz>=0.55.0
Description-Content-Type: text/markdown

# pixtreme

[![PyPI](https://img.shields.io/pypi/v/pixtreme.svg)](https://pypi.org/project/pixtreme/)
![Python](https://img.shields.io/badge/Python-%E2%89%A53.12-3776AB.svg)
![CUDA](https://img.shields.io/badge/CUDA-12.x-76B900.svg)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/sync-dev-org/pixtreme/blob/main/LICENSE)

GPU-first image processing for Python, built on CUDA and CuPy.

## Why pixtreme

pixtreme keeps image data on the NVIDIA GPU and makes a metadata-bearing `Frame` the common value passed between
operations. A `Frame` owns an HWC `cupy.ndarray` together with colorspace, transfer, channel, and YCbCr-matrix claims,
so color meaning travels with pixels instead of living in ambient configuration.

- Purpose-built `RawKernel` implementations and CuPy operations avoid unnecessary host round trips.
- Color conversion, format conversion, channel routing, and affine numeric transforms fuse work into a single pass
  where their contracts allow it.
- Floating-point working values are not clipped to `[0, 1]`: negative values, highlights above 1.0, and filter
  overshoot remain valid scene data until an explicit quantization or clipping boundary.
- Public operations live in 12 focused modules. Named tokens are case-sensitive, validated immediately, and have no
  environment-dependent defaults.
- `Frame` is the working currency; device arrays and encoded/file formats cross explicit `from_*`, `to_*`,
  `read`/`write`, and `decode`/`encode` boundaries.

## Performance

The following measurements are selected from a fresh 145-case run at commit `6ddd6f1`. Each result is the median of
1,000 consecutive FHD frames after warmup and JIT compilation. The test system used an NVIDIA RTX A6000, CUDA 12.9,
CuPy 14.1.1, and Python 3.12 under WSL2.

| Operation | Representative parameters | Median (ms) | FPS | Effective GB/s |
|---|---|---:|---:|---:|
| `resize` | 1920x1080 -> 960x540, `nearest` | 0.065 | 15301.3 | 475.9 |
| `resize` | 1920x1080 -> 3840x2160, `lanczos4` | 0.947 | 1056.0 | 131.4 |
| `from_array` | CHW uint16, 10-bit -> float32 HWC | 0.117 | 8537.4 | 318.7 |
| `Frame.to_yuva444p` | 12-bit legal, alpha full | 0.110 | 9073.3 | 451.5 |
| `rgb_to_rgb` | ACEScg linear -> sRGB srgb | 0.125 | 7990.3 | 397.7 |
| `rgb_to_hsv` | label-driven scene values | 0.112 | 8949.3 | 445.4 |
| `rgb_to_rgb` | BT.2408 direct mapping -> Rec.2020 pq | 0.132 | 7602.9 | 378.4 |
| `apply_lut` | 65^3 LUT, tetrahedral | 0.184 | 5428.4 | 270.1 |
| `text` | single-line CJK, size 64, one outline | 0.395 | 2532.6 | 126.0 |
| `color_bars` | FHD ARIB STD-B28 normalized | 0.080 | 12531.5 | 311.8 |

These figures describe this system and workload, not a hardware-independent guarantee. File and encoded-byte
boundaries have different I/O-inclusive conditions. See [the full performance report](https://github.com/sync-dev-org/pixtreme/blob/main/docs/performance.md) for every
case, distribution statistics, and the complete methodology.

## Requirements

- Python 3.12 or newer
- CUDA 12.x
- An NVIDIA GPU

WSL2 is supported with the Windows NVIDIA driver and a working CUDA device. Depending on the WSL installation,
`nvidia-smi` may be available at `/usr/lib/wsl/lib/nvidia-smi` rather than on the default `PATH`.

## Installation

With pip:

```console
python -m pip install pixtreme
```

With uv:

```console
uv add pixtreme
```

Upgrading from 0.x? 1.0.1 is a ground-up rewrite — see the [changelog](https://github.com/sync-dev-org/pixtreme/blob/main/CHANGELOG.md) for the migration summary.

## Quickstart

Read an image into GPU memory, work in scene-linear ACEScg, and quantize only at the file boundary:

```python
import pixtreme as px

frame = px.io.read_image("input.png")
working = px.color.rgb_to_rgb(frame, output_colorspace="ACEScg", output_gamma="linear")
working = px.filter.sharpen(working, amount=0.5)
output = px.color.rgb_to_rgb(working, output_colorspace="sRGB", output_gamma="srgb")
px.io.write_image("output.png", px.values.quantize(output, bit_depth=8))
```

`read_image` returns a `Frame` whose pixels already reside on the GPU. Processing remains float32 and unclipped;
`quantize` is the explicit normalized-float-to-integer boundary required by PNG.

## API tour

The top-level package exports only `Frame`, `Lut`, `ImageHeader`, and `channels`. Operations use their canonical module
paths:

| Module | Public functions | Responsibility |
|---|---|---|
| `px.io` | `read_image`, `write_image`, `read_header`, `read_lut`, `decode_image`, `encode_image`, `from_array`, `from_uyvy422`, `from_v210`, `from_nv12`, `from_p010`, `from_yuv420p`, `from_yuv422p`, `from_yuv444p`, `from_yuva444p` | File, byte, device-array, LUT, and named-format boundaries |
| `px.color` | `apply_lut`, `gamma_to_linear`, `hsv_to_rgb`, `linear_to_gamma`, `rgb_to_grayscale`, `rgb_to_hsv`, `rgb_to_rgb`, `rgb_to_ycbcr`, `ycbcr_to_rgb`, `ycbcr_to_ycbcr` | Colorimetry, transfer functions, YCbCr/HSV, LUTs, and explicit tonemapping |
| `px.blur` | `gaussian_blur`, `box_blur`, `median_blur`, `bilateral_blur`, `directional_blur`, `zoom_blur`, `spin_blur`, `vector_blur`, `lens_blur` | Neighborhood, directional, motion, and lens blur families |
| `px.filter` | `sobel`, `laplacian`, `difference_of_gaussians`, `canny`, `sharpen`, `unsharp_mask`, `convolve_box`, `equalize_histogram`, `clahe` | Derivatives, edges, sharpening, convolution, and histogram operations |
| `px.analyze` | `corner_harris`, `match_template` | Image measurements that return raw GPU response arrays |
| `px.morphology` | `erosion`, `dilation`, `opening`, `closing`, `morphological_gradient`, `white_tophat`, `black_tophat` | Morphological image operations |
| `px.transform` | `resize`, `warp_affine`, `stack` | Geometry and multi-image layout |
| `px.draw` | `line`, `polyline`, `rectangle`, `circle`, `ellipse`, `polygon`, `text` | Shape and text drawing |
| `px.generate` | `ramp`, `grid`, `checkerboard`, `color_bars`, `fractal_noise`, `turbulent_noise`, `grain` | Procedural frames, test patterns, and noise |
| `px.channel` | `shuffle` | Channel routing and assembly without implicit color meaning changes |
| `px.values` | `quantize`, `dequantize`, `full_to_legal`, `legal_to_full`, `cast_dtype`, `recode_dtype` | Range, quantization, and storage representation |
| `px.composite` | `merge` | Transform-aware multi-image compositing |

Render the Quickstart's scene-linear `working` frame through the analytic ACES 2.0 Output Transform:

```python
display = px.color.rgb_to_rgb(
    working,
    output_colorspace="sRGB",
    output_gamma="srgb",
    tonemap="aces-2.0",
)
```

The bytes boundary mirrors the file boundary without inventing a host-array API:

```python
png_bytes = px.io.encode_image(
    px.values.quantize(display, bit_depth=8),
    format="png",
    compression_level=4,
)
round_trip = px.io.decode_image(png_bytes)
```

Text shaping supports bundled CJK fonts and an opt-in 4x supersampled raster path:

```python
captioned = px.draw.text(
    display,
    text="極彩",
    position=(48, 96),
    size=64,
    color=(1.0, 0.8, 0.2),
    supersample=True,
)
```

## Full performance

[docs/performance.md](https://github.com/sync-dev-org/pixtreme/blob/main/docs/performance.md) contains all 145 measured cases, including mean, median, FPS, p5, p95,
effective bandwidth, parameters, and the 46 cases whose median exceeds 1 ms. It also separates GPU-device throughput
from temporary-file and encoded-byte I/O measurements.

## Color management

Color processing is explicit, metadata-aware, and designed to preserve scene values until a declared output boundary.

- The analytic ACES 2.0 SDR 100-nit Output Transform evaluates the complete AP1 limit, Hellwig JMh, tone, chroma,
  gamut-compression, limiting-RGB, reference-range, and display-encoding chain in one fused CUDA pass. Its 363-record
  hue table is an algorithm parameter, not an RGB-grid output approximation; runtime evaluation uses no LUT
  interpolation and matches direct OpenColorIO 2.5.2 reference evaluation with `rtol=0`, `atol=2e-4`.
- ACES 1.3 is also available as a formula-based one-pass transform. Explicit `aces-1.3-lut` and `aces-2.0-lut` tokens
  remain available when a pre-baked 65^3 LUT is the desired supply mechanism.
- BT.2408 direct mapping places SDR reference white at 203 cd/m2 for Rec.2020 HLG or PQ output.
- RGB/YCbCr conversion, legal/full-range code positions, and chroma siting follow H.273-aligned contracts, with the
  matrix basis carried in `Frame` metadata.
- Broadcast test-pattern generation covers ARIB STD-B28, SMPTE RP 219-1, and ITU-R BT.2111-2 HLG/PQ variants,
  including exact 10-bit code output.

## Status & license

Version 1.0.1 is the current release. It is a ground-up implementation and does not connect to the 0.x codebase. The
final 0.x release, 0.9.0, remains available from the [`v0.9.0` Git tag](https://github.com/sync-dev-org/pixtreme/tree/v0.9.0)
and the [PyPI release history](https://pypi.org/project/pixtreme/#history). See the [changelog](https://github.com/sync-dev-org/pixtreme/blob/main/CHANGELOG.md) for the
1.0 migration-impact summary.

pixtreme is released under the [MIT License](https://github.com/sync-dev-org/pixtreme/blob/main/LICENSE).
