Skip to content

imazen/zenblend

Repository files navigation

zenblend CI MSRV License

zenblend is a row-level pixel blending library for premultiplied linear f32 RGBA compositing pipelines.

All operations work on &mut [f32] slices -- 4 interleaved floats per pixel, alpha pre-applied, in linear light. Designed as the inner loop for zenpipe strip pipelines, not a standalone compositing engine.

Blend modes

Porter-Duff (12): Clear, Src, Dst, SrcOver, DstOver, SrcIn, DstIn, SrcOut, DstOut, SrcAtop, DstAtop, Xor

Artistic (20): Multiply, Screen, Overlay, Darken, Lighten, HardLight, SoftLight, ColorDodge, ColorBurn, Difference, Exclusion, LinearBurn, LinearDodge, VividLight, LinearLight, PinLight, HardMix, Divide, Subtract, Plus

32 modes total. Artistic modes unpremultiply per-pixel, apply the blend function, then re-premultiply. Plus operates directly on premultiplied data.

Getting started

Blending two rows

use zenblend::{BlendMode, blend_row, blend_row_solid, blend_row_solid_opaque};

// fg and bg are premultiplied linear f32, 4ch RGBA, equal length, divisible by 4.
// fg is modified in place to contain the blended result.
let mut fg = vec![0.5, 0.0, 0.0, 0.5,  0.0, 0.3, 0.0, 1.0];
let bg =     vec![0.0, 0.3, 0.0, 1.0,  0.0, 0.0, 0.5, 0.5];
blend_row(&mut fg, &bg, BlendMode::SrcOver);

// Blend against a solid color -- no row buffer needed for background.
let mut row = vec![0.5, 0.0, 0.0, 0.5,  0.0, 0.3, 0.0, 1.0];
blend_row_solid(&mut row, &[0.2, 0.0, 0.0, 0.5], BlendMode::Multiply);

// Optimized path when the background is opaque (alpha = 1.0).
let mut row2 = vec![0.5, 0.0, 0.0, 0.5,  0.0, 0.3, 0.0, 1.0];
blend_row_solid_opaque(&mut row2, &[0.2, 0.1, 0.05, 1.0], BlendMode::SrcOver);

Masking

use zenblend::mask::{RoundedRectMask, MaskSource};
use zenblend::{mask_row, mask_row_constant, mask_row_rgb, apply_mask_spans};

let mut pixels = vec![0.5, 0.0, 0.0, 0.5,  0.0, 0.3, 0.0, 1.0];

// Per-pixel mask: one f32 per pixel, broadcast to all 4 channels.
let mask_values = vec![0.8, 1.0];
mask_row(&mut pixels, &mask_values);

// Uniform opacity -- no mask buffer needed.
mask_row_constant(&mut pixels, 0.7);

// RGB-only mask: multiplies R, G, B but leaves alpha untouched.
// Use case: gain map application, vignette without opacity change.
let rgb_mask = vec![0.9, 1.0];
mask_row_rgb(&mut pixels, &rgb_mask);

// Span-optimized masking -- skips fully opaque/transparent regions.
let width = 64;
let height = 64;
let mask = RoundedRectMask::new(width, height, [10.0, 10.0, 10.0, 10.0]);
let mut row = vec![0.5f32; (width as usize) * 4];
let mut mask_buf = vec![0.0f32; width as usize];
apply_mask_spans(&mut row, &mut mask_buf, &mask, 0);

Built-in masks: RoundedRectMask, LinearGradientMask, RadialGradientMask. Implement the MaskSource trait for custom masks.

Interpolation

use zenblend::lerp_row;

// Per-pixel blend factor t in [0, 1]. One f32 per pixel.
// t=0 -> a, t=1 -> b.
let a   = vec![1.0, 0.0, 0.0, 1.0,  0.0, 0.0, 0.0, 0.0];
let b   = vec![0.0, 0.0, 1.0, 1.0,  0.0, 1.0, 0.0, 1.0];
let t   = vec![0.5, 0.5];
let mut out = vec![0.0f32; 8];
lerp_row(&a, &b, &t, &mut out);

SIMD acceleration

SrcOver, masking (mask_row, mask_row_rgb), and lerp_row are SIMD-accelerated via runtime CPU dispatch through archmage:

Platform ISA Pixels/iter
x86_64 AVX2 + FMA 2
AArch64 NEON 1
WASM simd128 1
Fallback scalar 1

Other blend modes use scalar implementations. Mask span alignment is SIMD-aware (snaps partial spans to block boundaries).

#![forbid(unsafe_code)] -- all SIMD through safe abstractions.

Limitations

  • All data must be premultiplied linear f32 RGBA. There is no format conversion; bring your own linearization.
  • No non-separable blend modes (Hue, Saturation, Color, Luminosity).
  • Only SrcOver has a dedicated SIMD fast path for blending; the other 31 modes run scalar per-pixel loops.
  • Row-level API only. There is no tile, buffer, or image-level compositing -- that belongs in zenpipe.

Features

  • default = ["std"]

Image tech I maintain

State of the art codecs* zenjpeg · zenpng · zenwebp · zengif · zenavif (rav1d-safe · zenrav1e · zenavif-parse · zenavif-serialize) · zenjxl (jxl-encoder · zenjxl-decoder) · zentiff · zenbitmaps · heic · zenraw · zenpdf · ultrahdr · mozjpeg-rs · webpx
Compression zenflate · zenzop
Processing zenresize · zenfilters · zenquant · zenblend
Metrics zensim · fast-ssim2 · butteraugli · resamplescope-rs · codec-eval · codec-corpus
Pixel types & color zenpixels · zenpixels-convert · linear-srgb · garb
Pipeline zenpipe · zencodec · zencodecs · zenlayout · zennode
ImageResizer ImageResizer (C#) — 24M+ NuGet downloads across all packages
Imageflow Image optimization engine (Rust) — .NET · node · go — 9M+ NuGet downloads across all packages
Imageflow Server The fast, safe image server (Rust+C#) — 552K+ NuGet downloads, deployed by Fortune 500s and major brands

* as of 2026

General Rust awesomeness

archmage · magetypes · enough · whereat · zenbench · cargo-copter

And other projects · GitHub @imazen · GitHub @lilith · lib.rs/~lilith · NuGet (over 30 million downloads / 87 packages)

License

Dual-licensed: AGPL-3.0 or commercial.

I've maintained and developed open-source image server software -- and the 40+ library ecosystem it depends on -- full-time since 2011. Fifteen years of continual maintenance, backwards compatibility, support, and the (very rare) security patch. That kind of stability requires sustainable funding, and dual-licensing is how I make it work without venture capital or rug-pulls. Support sustainable and secure software; swap patch tuesday for patch leap-year.

Our open-source products

Your options:

  • Startup license -- $1 if your company has under $1M revenue and fewer than 5 employees. Get a key
  • Commercial subscription -- Governed by the Imazen Site-wide Subscription License v1.1 or later. Apache 2.0-like terms, no source-sharing requirement. Sliding scale by company size. Pricing & 60-day free trial
  • AGPL v3 -- Free and open. Share your source if you distribute.

See LICENSE-COMMERCIAL for details.

About

No description, website, or topics provided.

Resources

License

AGPL-3.0, Unknown licenses found

Licenses found

AGPL-3.0
LICENSE-AGPL3
Unknown
LICENSE-COMMERCIAL

Stars

Watchers

Forks

Packages

 
 
 

Contributors