aboutsummaryrefslogtreecommitdiff
path: root/lib/color-conversion/default.nix
diff options
context:
space:
mode:
authorCaroline Larimore <caroline@larimo.re>2025-04-14 19:01:38 -0700
committerCaroline Larimore <caroline@larimo.re>2025-04-14 19:01:38 -0700
commite8077fde966e051fc449fffcfa061c7f7edc47b0 (patch)
treea0b1ce60f2718f90c64e924ed8df8d5d4f0d2289 /lib/color-conversion/default.nix
parente486d896215e7ef04438809952bc7317512d5765 (diff)
migration: finalize
Diffstat (limited to 'lib/color-conversion/default.nix')
-rw-r--r--lib/color-conversion/default.nix175
1 files changed, 175 insertions, 0 deletions
diff --git a/lib/color-conversion/default.nix b/lib/color-conversion/default.nix
new file mode 100644
index 0000000..437b511
--- /dev/null
+++ b/lib/color-conversion/default.nix
@@ -0,0 +1,175 @@
+{ lib }:
+
+let
+ hexToDecMap = {
+ "0" = 0;
+ "1" = 1;
+ "2" = 2;
+ "3" = 3;
+ "4" = 4;
+ "5" = 5;
+ "6" = 6;
+ "7" = 7;
+ "8" = 8;
+ "9" = 9;
+ "a" = 10;
+ "b" = 11;
+ "c" = 12;
+ "d" = 13;
+ "e" = 14;
+ "f" = 15;
+ };
+
+ /* Base raised to the power of the exponent.
+
+ Type: pow :: int or float -> int -> int
+
+ Args:
+ base: The base.
+ exponent: The exponent.
+
+ Example:
+ pow 0 1000
+ => 0
+ pow 1000 0
+ => 1
+ pow 2 30
+ => 1073741824
+ pow 3 3
+ => 27
+ pow (-5) 3
+ => -125
+ */
+ pow = base: exponent:
+ if exponent > 1 then
+ let
+ x = pow base (exponent / 2);
+ odd_exp = lib.mod exponent 2 == 1;
+ in
+ x * x * (if odd_exp then base else 1)
+ else if exponent == 1 then
+ base
+ else if exponent == 0 && base == 0 then
+ throw "undefined"
+ else if exponent == 0 then
+ 1
+ else
+ throw "undefined";
+
+ /* Conversion from base 16 to base 10 with a exponent. Is of the form
+ scalar * 16 ** exponent.
+
+ Type: base16To10 :: int -> int -> int
+
+ Args:
+ exponent: The exponent for the base, 16.
+ scalar: The value to multiple to the exponentiated base.
+
+ Example:
+ base16To10 0 11
+ => 11
+ base16To10 1 3
+ => 48
+ base16To10 2 7
+ 1792
+ base16To10 3 14
+ 57344
+ */
+ base16To10 = exponent: scalar: scalar * pow 16 exponent;
+
+ /* Converts a hexadecimal character to decimal.
+ Only takes a string of length 1.
+
+ Type: hexCharToDec :: string -> int
+
+ Args:
+ hex: A hexadecimal character.
+
+ Example:
+ hexCharToDec "5"
+ => 5
+ hexCharToDec "e"
+ => 14
+ hexCharToDec "A"
+ => 10
+ */
+ hexCharToDec = hex:
+ let
+ lowerHex = lib.toLower hex;
+ in
+ if builtins.stringLength hex != 1 then
+ throw "Function only accepts a single character."
+ else if hexToDecMap ? ${lowerHex} then
+ hexToDecMap."${lowerHex}"
+ else
+ throw "Character ${hex} is not a hexadecimal value.";
+in rec {
+ /* Converts from hexadecimal to decimal.
+
+ Type: hexToDec :: string -> int
+
+ Args:
+ hex: A hexadecimal string.
+
+ Example:
+ hexadecimal "12"
+ => 18
+ hexadecimal "FF"
+ => 255
+ hexadecimal "abcdef"
+ => 11259375
+ */
+ hexToDec = hex:
+ let
+ decimals = builtins.map hexCharToDec (lib.stringToCharacters hex);
+ decimalsAscending = lib.reverseList decimals;
+ decimalsPowered = lib.imap0 base16To10 decimalsAscending;
+ in
+ lib.foldl builtins.add 0 decimalsPowered;
+
+ /* Converts a 6 character hexadecimal string to RGB values.
+
+ Type: hexToRGB :: string => [int]
+
+ Args:
+ hex: A hexadecimal string of length 6.
+
+ Example:
+ hexToRGB "012345"
+ => [ 1 35 69 ]
+ hexToRGB "abcdef"
+ => [171 205 239 ]
+ hexToRGB "000FFF"
+ => [ 0 15 255 ]
+ */
+ hexToRGB = hex:
+ let
+ rgbStartIndex = [ 0 2 4 ];
+ hexList = builtins.map (x: builtins.substring x 2 hex) rgbStartIndex;
+ hexLength = builtins.stringLength hex;
+ in
+ if hexLength != 6 then
+ throw ''
+ Unsupported hex string length of ${builtins.toString hexLength}.
+ Length must be exactly 6.
+ ''
+ else
+ builtins.map hexToDec hexList;
+
+ /* Converts a 6 character hexadecimal string to an RGB string seperated by a
+ delimiter.
+
+ Type: hexToRGBString :: string -> string
+
+ Args:
+ sep: The delimiter or seperator.
+ hex: A hexadecimal string of length 6.
+ */
+ hexToRGBString = sep: hex:
+ let
+ inherit (builtins) map toString;
+ hexInRGB = hexToRGB hex;
+ hexInRGBString = map toString hexInRGB;
+ in
+ lib.concatStringsSep sep hexInRGBString;
+}