[Webkit-unassigned] [Bug 221868] New: Reduce requirements for color types to only conversion to their reference color

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Sat Feb 13 12:04:04 PST 2021


https://bugs.webkit.org/show_bug.cgi?id=221868

            Bug ID: 221868
           Summary: Reduce requirements for color types to only conversion
                    to their reference color
           Product: WebKit
           Version: WebKit Nightly Build
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: Platform
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: sam at webkit.org

We currently require every new color type to define a conversion to/from xyz and then perhaps some more conversions to reference colors to avoid unnecessary trips through XYZ. For example, if every conversion from HSL to SRGB went through XYZ it would be very silly and inefficient, and the fact that we require the boiler plate for HSL -> XYZ, even though it's always going to convert to SRGB first seems unfortunate. We can do better.

At first I thought we could model color conversion as DAG, with XYZ at the root, and each color type declaring a "reference color" that would get them closer to XYZ. So, HSL would have a "reference color" of sRGB, sRGB would have a "reference color" of linearSRGB, and linearSRGB would have a reference color XYZ. Then, as long as there was a defined conversion to/from the "reference color", we could do a least common ancestor graph search between the two color types being converted between to find the optimal set of conversions needed.

That almost works, but the relationships between the four color types that make up each RGB type (bounded-gamma-encoded, bounded-linear-encoded, extended-gamma-encoded, extended-linear-encoded) make it not quite ideal, since a conversion from something like sRGB to extendedSRGB would wind up going through XYZ (since the reference color for sRGB is linearSRGB and the reference color for extendedSRGB is linearExtendedSRGB, and both either reference colors are XYZ). 

Ultimately, the depth of the type graph is not all that large (though the ascii art I made is quite big, though I did remove A98RGB and Rec2020 as they are same as DisplayP3 here):

                ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐
                 Matrix Conversions    ┌───────────┐│┌───────────┐
                │                      │ XYZ (D50) │││ XYZ (D65) │                                                      │
                                       └─────▲─────┘│└─────▲─────┘
                │                            │      │      │                                                            │
       ┌─────────────────────────┬───────────┘      │      └───────────┬───────────────────────────────┐
       │        │                │                  │                  │                               │                │
       │                         │                  │                  │                               │               
       │        │                │                  │                  │                               │                │
       │          ProPhotoRGB───────────────────┐   │   SRGB──────────────────────────┐ DisplayP3─────────────────────┐
       │        │ │┌────────┐ ┌────────────────┐│   │   │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│ │
       │          ││ Linear │ │ LinearExtended ││   │   ││ Linear │ │ LinearExtended ││ ││ Linear │ │ LinearExtended ││
       │        │ │└────────┘ └────────────────┘│   │   │└────────┘ └────────────────┘│ │└────────┘ └────────────────┘│ │
       │         ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─ ─│─ ─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─│─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─│─
 ┌───────────┐    │┌────────┐ ┌────────────────┐│   │   │┌────────┐ ┌────────────────┐│ │┌────────┐ ┌────────────────┐│
 │    Lab    │    ││ Gamma  │ │ GammaExtended  ││   │   ││ Gamma  │ │ GammaExtended  ││ ││ Gamma  │ │ GammaExtended  ││
 └─────▲─────┘    │└────────┘ └────────────────┘│   │   │└────▲───┘ └────────────────┘│ │└────────┘ └────────────────┘│
       │          └─────────────────────────────┘   │   └─────┼───────────────────────┘ └─────────────────────────────┘
       │                                            │      ┌──┴──────────┬─────────────┐
       │                                            │      │             │             │
 ┌───────────┐                                      │┌───────────┐ ┌───────────┐┌─────────────┐
 │    LCH    │                                      ││    HSL    │ │    HWB    ││SRGB<uint8_t>│
 └───────────┘                                      │└───────────┘ └───────────┘└─────────────┘

>From this, it turns out you can handle all the cases in about 5 steps, with most peeling off a conversion from the front or back or the path and using recursion to continue on. It ultimately leaves a final step where only matrix conversions remain, which can potentially be further optimized in another patch to concatenate the matrices at compile time.

1. Handle the special case SRGBA<uint8_t> for Input and Output, and recursively call conversion.

2. Handle all color types that are not IsRGBType<T> or IsXYZA<T> for Input and Output. For all
   these other color types, we can uncondtionally convert them to their "reference" color, as
   either they have already been handled by a ColorConversion specialization or this will
   get us closer to the final conversion, and recursively call conversion.

3. Handle conversions within a RGBFamily (e.g. all have the same descriptor). This will conclude
   the conversion.

4. Handle any gamma conversions for the Input and Output, recursively call conversion

5. At this point, Input and Output are each either Linear-RGB types (of different familes) or XYZA
   and therefore all additional conversion can happen via matrix transformation. This will conclude
   the conversion.


With these steps, we group the color types into 3 distinct groups.

1. RGB types.

These inherit from the RGBType struct and are defined in terms of their xyzToLinear / linearToXYZ matrices, their transfer function, whether they are bounded or extended and their white point. New RGB color types can be added without any new conversion code being required, as long as they specify those properties.

2. The XYZ type.

This is the root type, and only varies on its white point. If other white points beside D50 and D65 are ever needed, we will need to extend the ChromaticAdapation specializations to also have conversion matrices between those.

3. All other types.

All other types (e.g. Lab, LCHA, HSLA, HWBA are the set currently) have their conversions defined in terms of single reference color and require explicit specialization of the ColorConversion struct to work.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20210213/b85de819/attachment-0001.htm>


More information about the webkit-unassigned mailing list