Skip to content

Commit

Permalink
Merge pull request #35 from treeform/guzba
Browse files Browse the repository at this point in the history
0.2.6, rounding + test rgba->rgbx, rgbx->rgba
  • Loading branch information
treeform authored Jul 22, 2022
2 parents d28608a + 9ba8d7c commit 7c9d96b
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 33 deletions.
4 changes: 1 addition & 3 deletions chroma.nimble
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# Package
version = "0.2.5"
version = "0.2.6"
author = "Andre von Houck"
description = "Everything you want to do with colors"
license = "MIT"

srcDir = "src"

# Deps
requires "nim >= 1.0.0"
28 changes: 14 additions & 14 deletions src/chroma.nim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
##

import chroma/colortypes, chroma/distance, chroma/names, chroma/temperature,
chroma/transformations, hashes, strutils, tables
chroma/transformations, std/hashes, std/math, std/strutils, std/tables

export colortypes, distance, temperature, transformations

Expand Down Expand Up @@ -197,9 +197,9 @@ proc toHtmlRgb*(c: Color): string =
## * blue -> rgb(0,0,255)
## * white -> rgb(255,255,255)
"rgb(" &
$int(c.r * 255) & ", " &
$int(c.g * 255) & ", " &
$int(c.b * 255) &
$round(c.r * 255).int & ", " &
$round(c.g * 255).int & ", " &
$round(c.b * 255).int &
")"

proc parseHtmlRgba*(text: string): Color =
Expand Down Expand Up @@ -230,9 +230,9 @@ proc toHtmlRgba*(c: Color): string =
## * blue -> rgb(0,0,255)
## * white -> rgb(255,255,255)
"rgba(" &
$int(c.r * 255) & ", " &
$int(c.g * 255) & ", " &
$int(c.b * 255) & ", " &
$round(c.r * 255).int & ", " &
$round(c.g * 255).int & ", " &
$round(c.b * 255).int & ", " &
$c.a &
")"

Expand Down Expand Up @@ -336,16 +336,16 @@ proc mixCMYK*(colorA, colorB: Color): Color =

proc mix*(a, b: ColorRGB): ColorRGB =
## Mixes two ColorRGB colors together using simple average.
result.r = a.r div 2 + b.r div 2
result.g = a.g div 2 + b.g div 2
result.b = a.b div 2 + b.b div 2
result.r = ((a.r.uint32 + b.r) div 2).uint8
result.g = ((a.g.uint32 + b.g) div 2).uint8
result.b = ((a.b.uint32 + b.b) div 2).uint8

proc mix*(a, b: ColorRGBA): ColorRGBA =
## Mixes two ColorRGBA colors together using simple average.
result.r = a.r div 2 + b.r div 2
result.g = a.g div 2 + b.g div 2
result.b = a.b div 2 + b.b div 2
result.a = a.a div 2 + b.a div 2
result.r = ((a.r.uint32 + b.r) div 2).uint8
result.g = ((a.g.uint32 + b.g) div 2).uint8
result.b = ((a.b.uint32 + b.b) div 2).uint8
result.a = ((a.a.uint32 + b.a) div 2).uint8

func distance*(c1, c2: SomeColor): float32 =
## A distance function based on CIEDE2000 color difference formula
Expand Down
30 changes: 15 additions & 15 deletions src/chroma/transformations.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
## and link to a mirror of the C file:
## - https://github.com/cran/colorspace/blob/master/src/colorspace.c

import colortypes, math
import colortypes, std/math

proc rgba*(c: ColorRGBX): ColorRGBA {.inline.} =
## Convert a premultiplied alpha RGBA to a straight alpha RGBA.
Expand All @@ -21,16 +21,16 @@ proc rgba*(c: ColorRGBX): ColorRGBA {.inline.} =
result.b = c.b
result.a = c.a
if result.a != 0 and result.a != 255:
let multiplier = ((255 / c.a.float32) * 255).uint32
result.r = ((result.r.uint32 * multiplier) div 255).uint8
result.g = ((result.g.uint32 * multiplier) div 255).uint8
result.b = ((result.b.uint32 * multiplier) div 255).uint8
let multiplier = round((255 / c.a.float32) * 255).uint32
result.r = ((result.r.uint32 * multiplier + 127) div 255).uint8
result.g = ((result.g.uint32 * multiplier + 127) div 255).uint8
result.b = ((result.b.uint32 * multiplier + 127) div 255).uint8

proc rgbx*(c: ColorRGBA): ColorRGBX {.inline.} =
## Convert a straight alpha RGBA to a premultiplied alpha RGBA.
result.r = ((c.r.uint32 * c.a.uint32) div 255).uint8
result.g = ((c.g.uint32 * c.a.uint32) div 255).uint8
result.b = ((c.b.uint32 * c.a.uint32) div 255).uint8
result.r = ((c.r.uint32 * c.a.uint32 + 127) div 255).uint8
result.g = ((c.g.uint32 * c.a.uint32 + 127) div 255).uint8
result.b = ((c.b.uint32 * c.a.uint32 + 127) div 255).uint8
result.a = c.a

proc rgbx*(c: ColorRGB): ColorRGBX {.inline.} =
Expand All @@ -42,9 +42,9 @@ proc rgbx*(c: ColorRGB): ColorRGBX {.inline.} =

proc rgb*(c: Color): ColorRGB {.inline.} =
## Convert Color to ColorRGB
result.r = uint8(c.r * 255)
result.g = uint8(c.g * 255)
result.b = uint8(c.b * 255)
result.r = round(c.r * 255).uint8
result.g = round(c.g * 255).uint8
result.b = round(c.b * 255).uint8

proc color*(c: ColorRGB): Color {.inline.} =
## Convert ColorRGB to Color
Expand All @@ -55,10 +55,10 @@ proc color*(c: ColorRGB): Color {.inline.} =

proc rgba*(c: Color): ColorRGBA {.inline.} =
## Convert Color to ColorRGBA
result.r = uint8(c.r * 255)
result.g = uint8(c.g * 255)
result.b = uint8(c.b * 255)
result.a = uint8(c.a * 255)
result.r = round(c.r * 255).uint8
result.g = round(c.g * 255).uint8
result.b = round(c.b * 255).uint8
result.a = round(c.a * 255).uint8

proc color*(c: ColorRGBA): Color {.inline.} =
## Convert ColorRGBA to Color
Expand Down
26 changes: 25 additions & 1 deletion tests/test_colors.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import chroma, chroma/transformations, macros, sequtils, strutils, unittest
import chroma, chroma/transformations, std/macros, std/sequtils, std/strutils, std/unittest, std/math

when not defined(js):
import parsecsv
Expand Down Expand Up @@ -397,6 +397,30 @@ suite "temperature":
doAssert fromTemperature(6500).almostEqual(color(1.0, 0.9753435850143433, 0.9935365319252014, 1.0)) # LCD or CRT screen
doAssert fromTemperature(15000).almostEqual(color(0.7009154558181763, 0.7981580495834351, 1.0, 1.0)) # Clear blue poleward sky

suite "premultiplied alpha":
test "rgba -> rgbx":
for a in 0.uint8 .. 255:
for r in 0.uint8 .. 255:
doAssert rgba(r, 0, 0, a).rgbx == rgbx(
round(r.float32 * a.float32 / 255).uint8,
0,
0,
a
)

test "rgbx -> rgba":
for a in 0.uint8 .. 255:
for r in 0.uint8 .. 255:
let
rgbx = rgba(r, 0, 0, a).rgbx
multiplier = round((255 / rgbx.a.float32) * 255).uint32
doAssert rgbx.rgba == rgba(
((rgbx.r * multiplier + 127) div 255).uint8,
0,
0,
rgbx.a.uint8
)

when false:
# example in readme:
import chroma
Expand Down

0 comments on commit 7c9d96b

Please sign in to comment.