Fast conversion between linear float and 8-bit sRGB

Overview

fast-srgb8

Build Status Docs Latest Version Minimum Rust Version

Small crate implementing fast conversion between linear float and 8-bit sRGB. Includes API for performing 4 simultaneous conversions, which are SIMD accelerated using SSE2 if available. Supports no_std (doesn't need libm either).

Features

  • f32_to_srgb8: converting a linear f32 to sRGB u8. Compliant with the most relevent public spec for this conversion (correct to ULP of 0.6, monotonic over range, etc)
  • f32x4_to_srgb8: Produces results identical to calling f32_to_srgb8 4 times in a row, but uses SSE2 to SIMD accelerate on x86 and x86_64 where SSE2 is known to be present. Otherwise, it just returns the results of calling f32_to_srgb8 (the scalar equivalent) 4 times.
  • srgb8_to_f32: Inverse operation of f32_to_srgb8. Uses the standard technique of a 256-item lookup table.

Benefits

  • Huge performance improvments over the naive implementation — ~5x for conversion to f32->srgb8, ~20x for srgb8->f32.
  • Supports no_std — normally this is tricky, as these operations require powf naively, which is not available to libcore.
  • No dependencies.
  • SIMD support for conversion to sRGB (conversion from sRGB is already ~20x faster than naive impl, and would probably be slower in SIMD, so for now it's not implemented).
  • Consistent and correct (according to at least one relevant spec) handling of edge cases, such as NaN/Inf/etc.
  • Exhaustive checking of all inputs for correctness (in tests).

Benchmarks

# Measures `fast_srgb8::f32_to_srgb8` vs ref impl
test tests::bench::fast_scalar       ... bench:         144 ns/iter (+/- 11)
test tests::bench::naive_scalar      ... bench:         971 ns/iter (+/- 48)

# Measures `fast_srgb8::f32x4_to_srgb8` vs calling reference impl 4 times
test tests::bench::fast_f32x4        ... bench:         440 ns/iter (+/- 29)
test tests::bench::naive_f32x4       ... bench:       3,625 ns/iter (+/- 282)
test tests::bench::fast_f32x4_nosimd ... bench:         482 ns/iter (+/- 27)

# Measures `fast_srgb8::srgb8_to_f32` vs ref impl
test tests::bench::fast_from_srgb8   ... bench:          81 ns/iter (+/- 6)
test tests::bench::naive_from_srgb8  ... bench:       4,026 ns/iter (+/- 282)

(Note that the ns/iter time is not for a single invocation of these function, it's for several)

License

Public domain, as explained here. If that's unacceptable, it's also available under either the Apache-2.0 or MIT licenses, at your option.

The float->srgb code is originally¹ based on public domain routines by Fabien "ryg" Giesen, although I'm no longer sure where these are available.

¹ (Well, specifically: The Rust code in this crate is ported from code in a C++ game engine of mine, which in turn, was based on the code from ryg. This doesn't make a difference, but increases the likelihood that any errors are solely my responsibility).

You might also like...
Advent of Code 2021, also an attempt to practice a bit of Rust.

Advent of Code 2021 Advent of Code 2021 (my first one!), also an attempt to practice a bit of Rust. Running (Assuming that the respective inputs are i

An Intel HAXM powered, protected mode, 32 bit, hypervisor addition calculator, written in Rust.

HyperCalc An Intel HAXM powered, protected mode, 32 bit, hypervisor addition calculator, written in Rust. Purpose None 😏 . Mostly just to learn Rust

CIEBII - Check if every bit is intact
CIEBII - Check if every bit is intact

CIEBII Checks If Every Byte Is Intact CIEBII is an image file format that checks if every single byte is intact. What does it do if it finds that a by

Stockbook embeds 1-bit raster images in your code at compile time

stockbook Stockbook embeds 1-bit raster images in your code at compile time. Designed primarily for #![no_std] usage, in embedded or other program-mem

A micro crate that simplifies a bit the use of the std macro thread_local!.

with-thread-local A micro crate that simplifies a bit the use of the std macro thread_local!. extern crate regex; use with_thread_local::with_thread_

Work to enable a Classic Mac (24-bit 68000) with ~16MB of RAM.

Apple SE FDHD ROM analysis In order to build a Mac clone that doesn't fully emulate the hardware (which is possible because the ROM abstracts hardware

 ⚡️ A blazing fast way of maintaining powerful notes with connections between them.
⚡️ A blazing fast way of maintaining powerful notes with connections between them.

Zettl ⚡️ A blazing fast way of maintaining powerful notes with connections between them. Installing Zettl To install Zettl, you will need the Rust too

Adds back-and-forth jumping between current and previous focused windows to Sway.

sway-focus-back-and-forth Implements back-and-forth movement between the current and the previous focused windows. It also can be seen as a fix to thi

convert nostr keys and note-ids between hex and bech32

Key-Convertr People are copy-pasting nostr private keys into webpages to convert between the original hex-encoding and bech32-encoding (specified in N

Comments
  • Fast gamma correction routines

    Fast gamma correction routines

    sRGB needs to be gamma-corrected in order to perform correct blending. Right now I'm using a home-grown implementation that has to convert to floating-point in order to do the transfer function, but I would love to have fast pure-int or SIMD routines. Is that in scope for this library?

    opened by LoganDark 6
Owner
Thom Chiovoloni
Indie gamedev, likes Rust, ex-Mozilla, ex-Cloudflare
Thom Chiovoloni
A bit like tee, a bit like script, but all with a fake tty. Lets you remote control and watch a process

teetty teetty is a wrapper binary to execute a command in a pty while providing remote control facilities. This allows logging the stdout of a process

Armin Ronacher 259 Jan 3, 2023
An abstract, safe, and concise color conversion library for rust nightly This requires the feature adt_const_params

colortypes A type safe color conversion library This crate provides many methods for converting between color types. Everything is implemented abstrac

Jacob 13 Dec 7, 2022
Fixed point to floating point (and back) conversion utility

fixed2float Simple utility for fixed point to real number conversions, using the VisSim (Fxm.b) and Q (Qm.n) notations. Usage as a dependency of your

Francesco Urbani 2 Aug 5, 2022
Core Fiberplane data models and methods for transforming them (templates, providers, markdown conversion)

fiberplane This repository is a monorepo for Rust code that is used throughout Fiberplane's product. Overview base64uuid - A utility for working with

Fiberplane 18 Feb 22, 2023
SVG to PDF file conversion based on "svg2pdf" and "resvg" Rust projects

pysvg2pdf Blazingly Fast ™️ SVG to PDF file conversion for Python. This project is based on Rust's svg2pdf and resvg projects. The project uses pyo3 a

SuffleWaffle 4 Mar 28, 2024
Sudoku Solver using bitmasks and bit-manipulation with Rust 🦀 and egui 🎨

sudoku-solver Download This Rust application implements a very memory efficent algorithm to solve sudoku and lets the user know when a unique solution

cameron 24 Apr 10, 2023
Tiny color conversion library for TUI application builders

Definition of ANSI, RGB and HSL color types and all the conversions between them. There are many other color conversion crates. This one may be useful

Canop 8 Dec 15, 2022
Rust implementation of custom numeric base conversion.

base_custom Use any characters as your own numeric base and convert to and from decimal. This can be taken advantage of in various ways: Mathematics:

Daniel P. Clark 5 Dec 28, 2021
Efficient scan conversion of a line segment with clipping to a rectangular window.

✂️ clipline ?? clipline is a Rust crate for efficient scan conversion of a line segment with clipping to a rectangular window. It is an implementation

Nurzhan Sakén 5 Oct 26, 2023
Bit fields and masks for rust!

ubits Bit fields and masks for rust! Provides a macro for generating bit field types complete with flags and some helpful trait implementations. Suppo

Adam Romano 2 Sep 16, 2022