PixelWeaver v0.5.0 /server.src.pixelweaver.promote
On this page

Promote and demote algorithm: a deterministic Python port of the frontend layer promotion and OKLab nearest-color logic, conformance-tested for parity.

#server.src.pixelweaver.promote

#server.src.pixelweaver.promote

Promote / demote algorithm -- pure Python port of the frontend src/lib/layers/promote-layer.ts and the OKLab nearest-color logic from src/lib/color/color-utils.ts.

Determinism across the two implementations is a hard requirement: the same sprite must classify identically whether promoted via the UI or via MCP. The cross-language conformance fixture (server/tests/fixtures/promote_vectors.json) pins this.

Binary-alpha policy: a pixel is either fully opaque or fully transparent after conversion. Sentinel role byte is 0xFF (transparent).

#_srgb_channel_to_linear

python
def _srgb_channel_to_linear(c: float) -> float

sRGB 0..1 channel to linear-light.

#_rgb_to_oklab

python
def _rgb_to_oklab(r: int, g: int, b: int) -> tuple[float, float, float]

8-bit sRGB to OKLab (L, a, b).

#_hex_to_rgb

python
def _hex_to_rgb(hex_str: str) -> tuple[int, int, int]

Parse #RRGGBB (case-insensitive) to an (r, g, b) tuple.

#_rgb_to_hex_upper

python
def _rgb_to_hex_upper(r: int, g: int, b: int) -> str

(r, g, b) to uppercase #RRGGBB.

#_nearest_ramp_index

python
def _nearest_ramp_index(r: int, g: int, b: int, ramp_oklab: list[tuple[float, float, float]]) -> int

Index of the ramp member nearest (r, g, b) in OKLab (first on ties).

#analyze_promotion

python
def analyze_promotion(rgba: bytes, width: int, height: int, ramp: list[str]) -> tuple[bytes, dict[str, int]]

Classify an RGBA buffer into a RolePlane's bytes plus per-bucket counts.

Mirrors the frontend analyzePromotion: - a == 0 -> transparent (sentinel) - 0 < a < 128 -> thresholded (dropped to transparent) - a >= 128 -> opaque; exact case-insensitive hex match else OKLab-nearest; 128 <= a < 255 also alphaFlattened

#demote_plane

python
def demote_plane(roles: bytes, width: int, height: int, ramp: list[str]) -> bytes

Convert a RolePlane's bytes back to an RGBA buffer.

Each role becomes its ramp color at full opacity; the sentinel becomes (0, 0, 0, 0). An out-of-range role byte is a hard error (corrupt plane).

#promotion_counts_camel

python
def promotion_counts_camel(counts: dict[str, int]) -> dict[str, Any]

Return counts already in the camelCase shape the MCP result uses.

Search