From e3e1dd7c6e999b5ba113f4b973c7a799aebd6b10 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sat, 5 Nov 2022 19:38:31 -0700 Subject: [PATCH] whee 2.4 gamma --- dither4.js | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/dither4.js b/dither4.js index a110b70..2641aa1 100644 --- a/dither4.js +++ b/dither4.js @@ -1,20 +1,15 @@ -function sRGBToLinear(val) { +function toLinear(val) { + // use a 2.4 gamma approximation + // this is BT.1886 compatible + // and simpler than sRGB let unit = val / 255; - if (unit < 0.04045) { - unit /= 12.92; - } else { - unit = ((unit + 0.055) / 1.055) ** 2.4; - } + unit **= 2.4; return unit * 255; } -function linearTosRGB(val) { +function fromLinear(val) { let unit = val / 255; - if (unit < 0.0031308) { - unit *= 12.92; - } else { - unit = 1.055 * unit ** (1 / 2.4) - 0.055; - } + unit **= (1 / 2.4); return unit * 255; } @@ -32,19 +27,19 @@ class RGB { return new RGB(r,g,b); } - sRGBToLinear() { + toLinear() { return new RGB( - sRGBToLinear(this.r), - sRGBToLinear(this.g), - sRGBToLinear(this.b) + toLinear(this.r), + toLinear(this.g), + toLinear(this.b) ); } - linearTosRGB() { + fromLinear() { return new RGB( - linearTosRGB(this.r), - linearTosRGB(this.g), - linearTosRGB(this.b) + fromLinear(this.r), + fromLinear(this.g), + fromLinear(this.b) ); } @@ -357,7 +352,7 @@ let palette256 = [ 0xf6e46f, 0xfffa84, 0xffff99, -].map((hex) => RGB.fromHex(hex).sRGBToLinear()); +].map((hex) => RGB.fromHex(hex).toLinear()); function decimate(input, palette, n) { // to brute-force, the possible palettes are: @@ -535,7 +530,7 @@ function convert(source, sink) { (line[x * 4 + 0] + line[x * 4 + 4]) / 2, (line[x * 4 + 1] + line[x * 4 + 5]) / 2, (line[x * 4 + 2] + line[x * 4 + 6]) / 2 - ).sRGBToLinear(); + ).toLinear(); if (nextError) { rgb.r += nextError.red[i]; rgb.g += nextError.green[i]; @@ -549,7 +544,7 @@ function convert(source, sink) { nextError = error; for (let x = 0; x < width; x++) { - let rgb = palette[output[x >> 1]].linearTosRGB(); + let rgb = palette[output[x >> 1]].fromLinear(); line[x * 4 + 0] = rgb.r; line[x * 4 + 1] = rgb.g; line[x * 4 + 2] = rgb.b;