Skip to content

RGB

RGB describes a color as a triple of red, green, and blue intensities. iridis stores RGB in floating-point form on the unit interval [0, 1], in the sRGB color space.

sRGB

sRGB is the IEC 61966-2-1 standard color space used by the open web, most consumer displays, and every common image format. It defines:

  • A set of primaries (chromaticities for red, green, blue).
  • A reference white (D65).
  • A non-linear transfer function (gamma encoding) that compresses linear light for storage.

When a hex string #7c3aed is read into iridis, the bytes are interpreted as gamma-encoded sRGB. Each byte is divided by 255 to produce a value in [0, 1]. The result is a gamma-corrected sRGB triple, not linear light.

Gamma-corrected vs linear

The sRGB transfer function is piecewise. The decode (gamma-corrected → linear) is:

v_linear = v / 12.92                          if v ≤ 0.04045
         = ((v + 0.055) / 1.055) ^ 2.4         otherwise

The encode (linear → gamma-corrected) is the inverse:

v = 12.92 · v_linear                          if v_linear ≤ 0.0031308
  = 1.055 · v_linear ^ (1/2.4) − 0.055        otherwise

Linear sRGB is required whenever physical light addition matters: relative luminance for WCAG, CIE XYZ conversion en route to OKLCH, and any blending model that claims to be perceptually correct.

Gamma-corrected sRGB is what gets written to a hex string, sent to a <canvas>, or set as a CSS color.

Conversion to OKLCH

The path is sRGB → linear sRGB → CIE XYZ-like cone responses → cube-root non-linearity → Oklab → polar form (OKLCH). The matrices are encoded in ColorRecordFactory (packages/core/src/math/ColorRecordFactory.ts); see OKLCH for the full pipeline.

Math primitives

PrimitiveFileBehaviour
srgbToLinearpackages/core/src/math/SrgbToLinear.tsgamma-decodes a triple of sRGB channels into linear sRGB
linearToSrgbpackages/core/src/math/LinearToSrgb.tsgamma-encodes a triple of linear sRGB channels back to sRGB
rgbToOklchpackages/core/src/math/RgbToOklch.tsbuilds a ColorRecord from three sRGB channels via ColorRecordFactory.fromRgb
oklchToRgbpackages/core/src/math/OklchToRgb.tsbuilds a ColorRecord from L, C, h via ColorRecordFactory.fromOklch
oklchToRgbRawpackages/core/src/math/OklchToRgbRaw.tsconverts L, C, h to an sRGB triple without allocating a ColorRecord (hot-loop primitive used by EnsureContrast and the factory)
oklchToDisplayP3packages/core/src/math/OklchToDisplayP3.tsconverts L, C, h to a Display-P3 RGB triple; unclamped so out-of-sRGB inputs survive
gamutMapSrgbpackages/core/src/math/GamutMapSrgb.tsCSS Color 4 §13.2.2 chroma-reduction gamut mapping; reports inGamut flag
mixSrgbpackages/core/src/math/MixSrgb.tslinear interpolation in gamma-corrected sRGB (fast, perceptually crude)

luminance (packages/core/src/math/Luminance.ts) and the WCAG / APCA contrast primitives all depend on the sRGB → linear decode internally.

Where it appears

  • intake:rgb (packages/core/src/tasks/intake/IntakeRgb.ts) accepts {r, g, b} objects from input.colors.
  • Every ColorRecord carries an rgb field alongside oklch and hex. Consumers that need to output a CSS color or a numeric byte triple read from this field directly.
  • The contrast plugin reads rgb to compute relative luminance for both WCAG and APCA without reaching back through OKLCH.

Released under the MIT License.