A => LICENSE +24 -0
@@ 1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <https://unlicense.org/>
A => go.mod +5 -0
@@ 1,5 @@
+module eliasnaur.com/colorspace
+
+go 1.17
+
+require golang.org/x/image v0.0.0-20211028202545-6944b10bf410
A => go.sum +4 -0
@@ 1,4 @@
+golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
+golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
A => srgb.go +71 -0
@@ 1,71 @@
+// SPDX-License-Identifier: Unlicense
+
+// Package colorspace implements color space conversion wrappers
+// compatible with image.Image.
+//
+// It is a proof of concept for https://github.com/golang/go/issues/11420.
+package colorspace
+
+import (
+ "image"
+ "image/color"
+ "math"
+
+ "golang.org/x/image/draw"
+)
+
+// SRGBA wraps an Image encoded in the sRGB color space.
+type SRGBA struct {
+ image.Image
+}
+
+func NewSRGBA(img image.Image) *SRGBA {
+ return &SRGBA{img}
+}
+
+// At converts an sRGB color from the underlying image to linear RGB.
+func (p *SRGBA) At(x, y int) color.Color {
+ c := p.Image.At(x, y)
+ r, g, b, a := c.RGBA()
+ ret := color.RGBA64{
+ uint16(sRGBToLinear(float32(r)/0xffff)*0xffff + .5),
+ uint16(sRGBToLinear(float32(g)/0xffff)*0xffff + .5),
+ uint16(sRGBToLinear(float32(b)/0xffff)*0xffff + .5),
+ uint16(a),
+ }
+ return ret
+}
+
+// Set converts a linear RGB color to sRGB and stores it in the underlying image.
+func (p *SRGBA) Set(x, y int, c color.Color) {
+ r, g, b, a := c.RGBA()
+ srgb := color.RGBA{
+ uint8(linearTosRGB(float32(r)/0xffff)*0xff + .5),
+ uint8(linearTosRGB(float32(g)/0xffff)*0xff + .5),
+ uint8(linearTosRGB(float32(b)/0xffff)*0xff + .5),
+ uint8(a >> 8),
+ }
+ p.Image.(draw.Image).Set(x, y, srgb)
+}
+
+func linearTosRGB(c float32) float32 {
+ // Formula from EXT_sRGB.
+ switch {
+ case c <= 0:
+ return 0
+ case 0 < c && c < 0.0031308:
+ return 12.92 * c
+ case 0.0031308 <= c && c < 1:
+ return 1.055*float32(math.Pow(float64(c), 0.41666)) - 0.055
+ }
+ return 1
+}
+
+func sRGBToLinear(c float32) float32 {
+ // Formula from EXT_sRGB.
+ if c <= 0.04045 {
+ return c / 12.92
+ } else {
+ return float32(math.Pow(float64((c+0.055)/1.055), 2.4))
+ }
+}