Re: [w3ctag/design-reviews] Wide gamut support for Canvas/OffscreenCanvas/ImageBitmap (#315)

Here's a blub defining Extended-sRGB.

# sRGB
Let's start with the familiar definition of sRGB ([from Wikipedia](https://en.wikipedia.org/wiki/SRGB#Specification_of_the_transformation)), and then I'll introduce extended-sRGB.

And let's just look at the forward transformation (from CIE XYZ to sRGB). The reverse transformation is just the inverse.

We start with a triple of reals [X,Y,Z] in CIE XYZ space, and the output is a triple of reals [R,G,B] in sRGB space. There are two steps to the transformation. The output of the first step is a triple [Rlinear,Glinear,BLinear].

## CIE XYZ to sRGB Step 1
The first step is defined as:
```
    [ Rlinear ]   [  3.2 -1.5 -0.5 ][ X ]
    [ Glinear ] = [ -1.0  1.9  0.0 ][ Y ]
    [ Blinear ]   [  0.1 -0.2  1.1 ][ Z ]
```

## CIE XYZ to sRGB Step 2
For the second step, we define the function T (taking reals to reals) as follows:
```
           { 0               : x < 0
    T(x) = { 12.92*x         : 0 <= x <= 0.00313
           { 1.055*x^(1/2.4) : 0.00313 < x <= 1
           { 1               : x > 1
```

The second step and final step in the transformation is then
```
    [ R ]   [ T(Rlinear) ]
    [ G ] = [ T(Glinear) ]
    [ B ]   [ T(Blinear) ]
```

## Remarks
That's it. Note that the function T only outputs values in the range [0,1].

Many applications encode the range [0,1] as 8-bit fixed-point.

# Extended-sRGB
As before, we start with a triple of reals [X,Y,Z] in CIE XYZ space, and the output is a triple of reals [R,G,B] this time in Extended sRGB space. There are two steps to the transformation. The output of the first step is a triple [Rlinear,Glinear,BLinear].

## CIE XYZ to Extended-sRGB Step 1
This is idential to CIE XYZ to sRGB.

## CIE XYZ to Extended-sRGB Step 2
For the second step, we define the function U (taking reals to reals) as follows:
```
        { 1.055*(-x)^(1/2.4) : x < -0.00313
 U(x) = { 12.92*x            : -0.00313 <= x <= 0.00313
        { 1.055*x^(1/2.4)    : x > 0.00313
```
Note that in the range [-1,1], U is a point-symmetric extension of T, that is, U(x) == sign(x)*T(abs(x)).

The second step and final step in the transformation is then
```
 [ R ]   [ U(Rlinear) ]
 [ G ] = [ U(Glinear) ]
 [ B ]   [ U(Blinear) ]
```

## Remarks
Note that it is entirely possible for R, G, and B to be negative or to be arbitrarily large (greater than 1). While these values may not correspond to physically realizable light spectra, it is valid to do math on them (just like in the CIE XYZ space), and once they are to be displayed in a particular gamut, the values may be clipped to that gamut.

## Reverse transformation
The reverse transformation from Extended-sRGB to CIE XYZ is the inverse function, as with sRGB. Unlike with sRGB, the forward and reverse transformation are 1-to-1.

# Remarks about compatibility
Note that for any triple [R,G,B] with R,G,B in the interval (0,1), the transformation of [R,G,B] from sRGB to CIE XYZ is exactly the same as the transformation from Extended-sRGB to CIE XYZ. This means that any program that was written in the sRGB color space can be changed to use the Extended-sRGB color space with no extra modifications.

Note that when using Extended-sRGB it is natural to store the color values as floating-point (or half-float) triples. It is not reasonable to encode them as 8-bit fixed-point values. If a canvas that is Extended-sRGB is to be converted to an image for export, then it would be natural to
* First convert from Extended-sRGB to the desired output image gamut (in the case of sRGB, this is the identity)
* Then clamp to the range [0,1] and encode as the range [0,1] as 8-bit fixed-point.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3ctag/design-reviews/issues/315#issuecomment-442919382

Received on Thursday, 29 November 2018 17:22:17 UTC