dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.86k stars 4.63k forks source link

API Proposal: Primitive Color and Color8 Types for .NET Core #32418

Closed aaronfranke closed 2 years ago

aaronfranke commented 4 years ago

As discussed in https://github.com/dotnet/runtime/issues/14825, the existing System.Drawing.Color type is not ideal for all use cases and .NET Core could benefit from new color types.

This proposal includes two new types: Color and Color8, in the System.Numerics namespace in a new folder (library? package?) called System.Numerics.Colors.

Rationale and usage

The new Color8 type uses four byte values. This is intended to be the computationally-cheap color type. It is fairly similar to System.Drawing.Color. The Color8 type is not suitable to use for HDR color math, including on high-end displays or in VR, but the Color8 type is ideal to use on computers which display 8 bits per channel, without having any unnecessary bits. A color type using bytes can also be accelerated on GPUs when used on vertices.

The new Color type uses four float values. This is intended to be the fully capable color type, even if it's slower than Color8 and takes up four times the space in memory. The reason this is called Color with no suffix is because it should be presented to users as the default choice, since it is the most capable. This type can be used for HDR color math, since it supports values outside of the normal [0, 1] range, and it supports much higher color precision than Color8. HDR implementations typically need 10, 12, or 16 bits per channel, floats have 23 bits of mantissa which is plenty. A color type using floats is also ideal when exposed to shaders (GLSL or similar).

Both of these types have properties for setting with the other's member type (R8/G8/B8/A8/Rf/Gf/Bf/Af), as well as operators and constructors to convert between them, so it is easy to interchange these types, including the ability to do high precision color math and store it in a low precision (byte) context, or vice versa.

Additionally, this proposal includes H/S/V properties for getting and setting hue, saturation, and value. This is a very common workflow for colors, especially when getting values from user input.

Finally, there are Colors and Colors8 static classes which have preset colors. The existing System.Drawing.Color places these as static members of that struct, but it is quite useful to have these separate to distinguish them from other static members (such as FromHSV and any others we wish to have).

The uses of these types are too broad to include specific code examples. See the above text for information on how these types are expected to be used.

Proposed API

None of the properties listed below are auto-properties, all non-static properties read/write from the fields.

The proposed code for this API is collapsed, just expand it to view the code.

```cs namespace System.Numerics { public partial struct Color : System.IEquatable, System.IFormattable { public float R; public float G; public float B; public float A; public byte R8 { get; set; } public byte G8 { get; set; } public byte B8 { get; set; } public byte A8 { get; set; } public float H { get; set; } public float S { get; set; } public float V { get; set; } public float this[int index] { get; set; } public System.Numerics.Color Blend(System.Numerics.Color over); public System.Numerics.Color Darkened(float amount); public System.Numerics.Color Inverted(); public System.Numerics.Color Lightened(float amount); public System.Numerics.Color Lerp(System.Numerics.Color color, float t); public uint ToArgb32(); public ulong ToArgb64(); public uint ToRgba32(); public ulong ToRgba64(); public string ToHtml(bool alpha = true); public void ToHsv(out float hue, out float saturation, out float value); public Color(uint rgba); public Color(ulong rgba); public Color(string rgba); public Color(byte v8, byte a8 = 255); public Color(float v, float a = 1.0f); public Color(byte r8, byte g8, byte b8, byte a8 = 255); public Color(float r, float g, float b, float a = 1.0f); public Color(System.Numerics.Color color, float alpha = 1.0f); public Color(System.Numerics.Color8 color, float alpha = 1.0f); public static System.Numerics.Color FromHSV(float hue, float saturation, float value, float alpha = 1.0f); public static bool operator ==(System.Numerics.Color left, System.Numerics.Color right); public static bool operator !=(System.Numerics.Color left, System.Numerics.Color right); public bool Equals(System.Numerics.Color other); public override bool Equals(object? obj); public override int GetHashCode(); public override readonly string ToString(); public readonly string ToString(string? format); public readonly string ToString(string? format, System.IFormatProvider? formatProvider); } public partial struct Color8 : System.IEquatable, System.IFormattable { public byte R; public byte G; public byte B; public byte A; public float Rf { get; set; } public float Gf { get; set; } public float Bf { get; set; } public float Af { get; set; } public float H { get; set; } public float S { get; set; } public float V { get; set; } public byte this[int index] { get; set; } public System.Numerics.Color8 Blend(System.Numerics.Color8 over); public System.Numerics.Color8 Darkened(float amount); public System.Numerics.Color8 Inverted(); public System.Numerics.Color8 Lightened(float amount); public System.Numerics.Color8 Lerp(System.Numerics.Color8 color, float t); public uint ToArgb32(); public uint ToRgba32(); public string ToHtml(bool alpha = true); public void ToHsv(out float hue, out float saturation, out float value); public Color8(uint rgba); public Color8(ulong rgba); public Color8(string rgba); public Color8(byte v, byte a = 255); public Color8(float vf, float af = 1.0f); public Color8(byte r, byte g, byte b, byte a = 255); public Color8(float rf, float gf, float bf, float af = 1.0f); public Color8(System.Numerics.Color color, byte alpha = 255); public Color8(System.Numerics.Color8 color, byte alpha = 255); public static System.Numerics.Color8 FromHSV(float hue, float saturation, float value, float alpha = 1.0f); public static implicit operator Color(Color8 color); public static explicit operator Color8(Color color); public static bool operator ==(System.Numerics.Color8 left, System.Numerics.Color8 right); public static bool operator !=(System.Numerics.Color8 left, System.Numerics.Color8 right); public bool Equals(System.Numerics.Color8 other); public override bool Equals(object? obj); public override int GetHashCode(); public override readonly string ToString(); public readonly string ToString(string? format); public readonly string ToString(string? format, System.IFormatProvider? formatProvider); } public static partial class Colors { public static System.Numerics.Color AliceBlue { get; } public static System.Numerics.Color AntiqueWhite { get; } public static System.Numerics.Color Aqua { get; } public static System.Numerics.Color Aquamarine { get; } public static System.Numerics.Color Azure { get; } public static System.Numerics.Color Beige { get; } public static System.Numerics.Color Bisque { get; } public static System.Numerics.Color Black { get; } public static System.Numerics.Color BlanchedAlmond { get; } public static System.Numerics.Color Blue { get; } public static System.Numerics.Color BlueViolet { get; } public static System.Numerics.Color Brown { get; } public static System.Numerics.Color BurlyWood { get; } public static System.Numerics.Color Burgundy { get; } public static System.Numerics.Color CadetBlue { get; } public static System.Numerics.Color Chartreuse { get; } public static System.Numerics.Color Chocolate { get; } public static System.Numerics.Color Coral { get; } public static System.Numerics.Color Cornflower { get; } public static System.Numerics.Color Cornsilk { get; } public static System.Numerics.Color Crimson { get; } public static System.Numerics.Color Cyan { get; } public static System.Numerics.Color DarkBlue { get; } public static System.Numerics.Color DarkCyan { get; } public static System.Numerics.Color DarkGoldenrod { get; } public static System.Numerics.Color DarkGray { get; } public static System.Numerics.Color DarkGreen { get; } public static System.Numerics.Color DarkKhaki { get; } public static System.Numerics.Color DarkMagenta { get; } public static System.Numerics.Color DarkOliveGreen { get; } public static System.Numerics.Color DarkOrange { get; } public static System.Numerics.Color DarkOrchid { get; } public static System.Numerics.Color DarkRed { get; } public static System.Numerics.Color DarkSalmon { get; } public static System.Numerics.Color DarkSeaGreen { get; } public static System.Numerics.Color DarkSlateBlue { get; } public static System.Numerics.Color DarkSlateGray { get; } public static System.Numerics.Color DarkTurquoise { get; } public static System.Numerics.Color DarkViolet { get; } public static System.Numerics.Color DeepPink { get; } public static System.Numerics.Color DeepSkyBlue { get; } public static System.Numerics.Color DimGray { get; } public static System.Numerics.Color DodgerBlue { get; } public static System.Numerics.Color FireBrick { get; } public static System.Numerics.Color FloralWhite { get; } public static System.Numerics.Color ForestGreen { get; } public static System.Numerics.Color Fuchsia { get; } public static System.Numerics.Color Gainsboro { get; } public static System.Numerics.Color GhostWhite { get; } public static System.Numerics.Color Gold { get; } public static System.Numerics.Color Goldenrod { get; } public static System.Numerics.Color Gray { get; } public static System.Numerics.Color Green { get; } public static System.Numerics.Color GreenYellow { get; } public static System.Numerics.Color Honeydew { get; } public static System.Numerics.Color HotPink { get; } public static System.Numerics.Color IndianRed { get; } public static System.Numerics.Color Indigo { get; } public static System.Numerics.Color Ivory { get; } public static System.Numerics.Color Khaki { get; } public static System.Numerics.Color Lavender { get; } public static System.Numerics.Color LavenderBlush { get; } public static System.Numerics.Color LawnGreen { get; } public static System.Numerics.Color LemonChiffon { get; } public static System.Numerics.Color LightBlue { get; } public static System.Numerics.Color LightCoral { get; } public static System.Numerics.Color LightCyan { get; } public static System.Numerics.Color LightGoldenrod { get; } public static System.Numerics.Color LightGray { get; } public static System.Numerics.Color LightGreen { get; } public static System.Numerics.Color LightPink { get; } public static System.Numerics.Color LightSalmon { get; } public static System.Numerics.Color LightSeaGreen { get; } public static System.Numerics.Color LightSkyBlue { get; } public static System.Numerics.Color LightSlateGray { get; } public static System.Numerics.Color LightSteelBlue { get; } public static System.Numerics.Color LightYellow { get; } public static System.Numerics.Color Lime { get; } public static System.Numerics.Color Limegreen { get; } public static System.Numerics.Color Linen { get; } public static System.Numerics.Color Magenta { get; } public static System.Numerics.Color Maroon { get; } public static System.Numerics.Color MaroonX11 { get; } public static System.Numerics.Color MediumAquamarine { get; } public static System.Numerics.Color MediumBlue { get; } public static System.Numerics.Color MediumOrchid { get; } public static System.Numerics.Color MediumPurple { get; } public static System.Numerics.Color MediumSeaGreen { get; } public static System.Numerics.Color MediumSlateBlue { get; } public static System.Numerics.Color MediumSpringGreen { get; } public static System.Numerics.Color MediumTurquoise { get; } public static System.Numerics.Color MediumVioletRed { get; } public static System.Numerics.Color MidnightBlue { get; } public static System.Numerics.Color MintCream { get; } public static System.Numerics.Color MistyRose { get; } public static System.Numerics.Color Moccasin { get; } public static System.Numerics.Color NavajoWhite { get; } public static System.Numerics.Color NavyBlue { get; } public static System.Numerics.Color OldLace { get; } public static System.Numerics.Color Olive { get; } public static System.Numerics.Color OliveDrab { get; } public static System.Numerics.Color Orange { get; } public static System.Numerics.Color OrangeRed { get; } public static System.Numerics.Color Orchid { get; } public static System.Numerics.Color PaleGoldenrod { get; } public static System.Numerics.Color PaleGreen { get; } public static System.Numerics.Color PaleTurquoise { get; } public static System.Numerics.Color PaleVioletRed { get; } public static System.Numerics.Color PapayaWhip { get; } public static System.Numerics.Color PeachPuff { get; } public static System.Numerics.Color Peru { get; } public static System.Numerics.Color Pink { get; } public static System.Numerics.Color Plum { get; } public static System.Numerics.Color PowderBlue { get; } public static System.Numerics.Color Purple { get; } public static System.Numerics.Color RebeccaPurple { get; } public static System.Numerics.Color Red { get; } public static System.Numerics.Color RosyBrown { get; } public static System.Numerics.Color RoyalBlue { get; } public static System.Numerics.Color SaddleBrown { get; } public static System.Numerics.Color Salmon { get; } public static System.Numerics.Color SandyBrown { get; } public static System.Numerics.Color SeaGreen { get; } public static System.Numerics.Color SeaShell { get; } public static System.Numerics.Color Sienna { get; } public static System.Numerics.Color Silver { get; } public static System.Numerics.Color SkyBlue { get; } public static System.Numerics.Color SlateBlue { get; } public static System.Numerics.Color SlateGray { get; } public static System.Numerics.Color Snow { get; } public static System.Numerics.Color SpringGreen { get; } public static System.Numerics.Color SteelBlue { get; } public static System.Numerics.Color Tan { get; } public static System.Numerics.Color Teal { get; } public static System.Numerics.Color Thistle { get; } public static System.Numerics.Color Tomato { get; } public static System.Numerics.Color Transparent { get; } public static System.Numerics.Color Turquoise { get; } public static System.Numerics.Color Violet { get; } public static System.Numerics.Color WebGreen { get; } public static System.Numerics.Color WebGray { get; } public static System.Numerics.Color WebMaroon { get; } public static System.Numerics.Color WebPurple { get; } public static System.Numerics.Color Wheat { get; } public static System.Numerics.Color White { get; } public static System.Numerics.Color WhiteSmoke { get; } public static System.Numerics.Color Yellow { get; } public static System.Numerics.Color YellowGreen { get; } } public static partial class Colors8 { public static System.Numerics.Color8 AliceBlue { get; } public static System.Numerics.Color8 AntiqueWhite { get; } public static System.Numerics.Color8 Aqua { get; } public static System.Numerics.Color8 Aquamarine { get; } public static System.Numerics.Color8 Azure { get; } public static System.Numerics.Color8 Beige { get; } public static System.Numerics.Color8 Bisque { get; } public static System.Numerics.Color8 Black { get; } public static System.Numerics.Color8 BlanchedAlmond { get; } public static System.Numerics.Color8 Blue { get; } public static System.Numerics.Color8 BlueViolet { get; } public static System.Numerics.Color8 Brown { get; } public static System.Numerics.Color8 BurlyWood { get; } public static System.Numerics.Color8 Burgundy { get; } public static System.Numerics.Color8 CadetBlue { get; } public static System.Numerics.Color8 Chartreuse { get; } public static System.Numerics.Color8 Chocolate { get; } public static System.Numerics.Color8 Coral { get; } public static System.Numerics.Color8 Cornflower { get; } public static System.Numerics.Color8 Cornsilk { get; } public static System.Numerics.Color8 Crimson { get; } public static System.Numerics.Color8 Cyan { get; } public static System.Numerics.Color8 DarkBlue { get; } public static System.Numerics.Color8 DarkCyan { get; } public static System.Numerics.Color8 DarkGoldenrod { get; } public static System.Numerics.Color8 DarkGray { get; } public static System.Numerics.Color8 DarkGreen { get; } public static System.Numerics.Color8 DarkKhaki { get; } public static System.Numerics.Color8 DarkMagenta { get; } public static System.Numerics.Color8 DarkOliveGreen { get; } public static System.Numerics.Color8 DarkOrange { get; } public static System.Numerics.Color8 DarkOrchid { get; } public static System.Numerics.Color8 DarkRed { get; } public static System.Numerics.Color8 DarkSalmon { get; } public static System.Numerics.Color8 DarkSeaGreen { get; } public static System.Numerics.Color8 DarkSlateBlue { get; } public static System.Numerics.Color8 DarkSlateGray { get; } public static System.Numerics.Color8 DarkTurquoise { get; } public static System.Numerics.Color8 DarkViolet { get; } public static System.Numerics.Color8 DeepPink { get; } public static System.Numerics.Color8 DeepSkyBlue { get; } public static System.Numerics.Color8 DimGray { get; } public static System.Numerics.Color8 DodgerBlue { get; } public static System.Numerics.Color8 FireBrick { get; } public static System.Numerics.Color8 FloralWhite { get; } public static System.Numerics.Color8 ForestGreen { get; } public static System.Numerics.Color8 Fuchsia { get; } public static System.Numerics.Color8 Gainsboro { get; } public static System.Numerics.Color8 GhostWhite { get; } public static System.Numerics.Color8 Gold { get; } public static System.Numerics.Color8 Goldenrod { get; } public static System.Numerics.Color8 Gray { get; } public static System.Numerics.Color8 Green { get; } public static System.Numerics.Color8 GreenYellow { get; } public static System.Numerics.Color8 Honeydew { get; } public static System.Numerics.Color8 HotPink { get; } public static System.Numerics.Color8 IndianRed { get; } public static System.Numerics.Color8 Indigo { get; } public static System.Numerics.Color8 Ivory { get; } public static System.Numerics.Color8 Khaki { get; } public static System.Numerics.Color8 Lavender { get; } public static System.Numerics.Color8 LavenderBlush { get; } public static System.Numerics.Color8 LawnGreen { get; } public static System.Numerics.Color8 LemonChiffon { get; } public static System.Numerics.Color8 LightBlue { get; } public static System.Numerics.Color8 LightCoral { get; } public static System.Numerics.Color8 LightCyan { get; } public static System.Numerics.Color8 LightGoldenrod { get; } public static System.Numerics.Color8 LightGray { get; } public static System.Numerics.Color8 LightGreen { get; } public static System.Numerics.Color8 LightPink { get; } public static System.Numerics.Color8 LightSalmon { get; } public static System.Numerics.Color8 LightSeaGreen { get; } public static System.Numerics.Color8 LightSkyBlue { get; } public static System.Numerics.Color8 LightSlateGray { get; } public static System.Numerics.Color8 LightSteelBlue { get; } public static System.Numerics.Color8 LightYellow { get; } public static System.Numerics.Color8 Lime { get; } public static System.Numerics.Color8 Limegreen { get; } public static System.Numerics.Color8 Linen { get; } public static System.Numerics.Color8 Magenta { get; } public static System.Numerics.Color8 Maroon { get; } public static System.Numerics.Color8 MaroonX11 { get; } public static System.Numerics.Color8 MediumAquamarine { get; } public static System.Numerics.Color8 MediumBlue { get; } public static System.Numerics.Color8 MediumOrchid { get; } public static System.Numerics.Color8 MediumPurple { get; } public static System.Numerics.Color8 MediumSeaGreen { get; } public static System.Numerics.Color8 MediumSlateBlue { get; } public static System.Numerics.Color8 MediumSpringGreen { get; } public static System.Numerics.Color8 MediumTurquoise { get; } public static System.Numerics.Color8 MediumVioletRed { get; } public static System.Numerics.Color8 MidnightBlue { get; } public static System.Numerics.Color8 MintCream { get; } public static System.Numerics.Color8 MistyRose { get; } public static System.Numerics.Color8 Moccasin { get; } public static System.Numerics.Color8 NavajoWhite { get; } public static System.Numerics.Color8 NavyBlue { get; } public static System.Numerics.Color8 OldLace { get; } public static System.Numerics.Color8 Olive { get; } public static System.Numerics.Color8 OliveDrab { get; } public static System.Numerics.Color8 Orange { get; } public static System.Numerics.Color8 OrangeRed { get; } public static System.Numerics.Color8 Orchid { get; } public static System.Numerics.Color8 PaleGoldenrod { get; } public static System.Numerics.Color8 PaleGreen { get; } public static System.Numerics.Color8 PaleTurquoise { get; } public static System.Numerics.Color8 PaleVioletRed { get; } public static System.Numerics.Color8 PapayaWhip { get; } public static System.Numerics.Color8 PeachPuff { get; } public static System.Numerics.Color8 Peru { get; } public static System.Numerics.Color8 Pink { get; } public static System.Numerics.Color8 Plum { get; } public static System.Numerics.Color8 PowderBlue { get; } public static System.Numerics.Color8 Purple { get; } public static System.Numerics.Color8 RebeccaPurple { get; } public static System.Numerics.Color8 Red { get; } public static System.Numerics.Color8 RosyBrown { get; } public static System.Numerics.Color8 RoyalBlue { get; } public static System.Numerics.Color8 SaddleBrown { get; } public static System.Numerics.Color8 Salmon { get; } public static System.Numerics.Color8 SandyBrown { get; } public static System.Numerics.Color8 SeaGreen { get; } public static System.Numerics.Color8 SeaShell { get; } public static System.Numerics.Color8 Sienna { get; } public static System.Numerics.Color8 Silver { get; } public static System.Numerics.Color8 SkyBlue { get; } public static System.Numerics.Color8 SlateBlue { get; } public static System.Numerics.Color8 SlateGray { get; } public static System.Numerics.Color8 Snow { get; } public static System.Numerics.Color8 SpringGreen { get; } public static System.Numerics.Color8 SteelBlue { get; } public static System.Numerics.Color8 Tan { get; } public static System.Numerics.Color8 Teal { get; } public static System.Numerics.Color8 Thistle { get; } public static System.Numerics.Color8 Tomato { get; } public static System.Numerics.Color8 Transparent { get; } public static System.Numerics.Color8 Turquoise { get; } public static System.Numerics.Color8 Violet { get; } public static System.Numerics.Color8 WebGreen { get; } public static System.Numerics.Color8 WebGray { get; } public static System.Numerics.Color8 WebMaroon { get; } public static System.Numerics.Color8 WebPurple { get; } public static System.Numerics.Color8 Wheat { get; } public static System.Numerics.Color8 White { get; } public static System.Numerics.Color8 WhiteSmoke { get; } public static System.Numerics.Color8 Yellow { get; } public static System.Numerics.Color8 YellowGreen { get; } } } ```

Details

While making this proposal, I referenced several open source color types:

The proposed Color type is also very similar to MAUI's Color type, which uses floats, has methods to convert between byte and HSV representations, and has a static class Colors with preset colors. It's also similar to Unity's Color type, though this one is closed-source.

When it comes to internal memory representation, string parsing, and importing from uint/ulong, these types use RGBA order. Traditionally, Microsoft APIs such as DirectX and System.Drawing use ARGB, but the rest of the world uses RGBA. Using RGBA order everywhere helps fit with the goal if "Semantic parity with CSS".

Open Questions

Are there any common use cases that these color types are unsuitable for?

Are there any other methods or properties which should be added?

What are some good test cases to add?

Pull Request

None so far, but see https://github.com/dotnet/corefx/pull/40733 for a closed proposed (and outdated) implementation.

Updates

None so far.

aaronfranke commented 2 years ago

@aaronfranke: By the way, even if there is no color type implemented for .NET Core, we should still deprecate System.Drawing.Color.

@tannergooding: What would be the reason for deprecating System.Drawing.Color? It is still used for its intended purpose, with System.Drawing; which itself is based on GDI+ and is actively supported on both Unix and Windows.

@nxrighthere: There's no point to deprecate it without a replacement. It makes sense to update/improve it, but not just leaving behind.

As a follow-up to this discussion, another reason for deprecating System.Drawing.Color is that it's extremely inefficient. As explained at the top of #48615, System.Drawing.Color contains extra metadata that makes it unusable in interop scenarios and inefficient in arrays. It contains a nullable string for the name (>= 64 bits on a 64-bit system), the color value is stored in a 64-bit long despite the fact that only the first 32 bits are used, and it also stores two 16-bit short values. This means that System.Drawing.Color is at a minimum 160 bits, which is more than the proposed HDR Color type (128 bits in total), and despite all 160 of those bits it can only store colors as precisely as the proposed Color8 type (32 bits in total).

namespace System.Drawing
{
    public readonly struct Color : IEquatable<Color>
    {
        private readonly string? name;
        private readonly long value;
        private readonly short knownColor;
        private readonly short state;
    }
}
aaronfranke commented 2 years ago

I still think that this proposal is the best idea, or at least something similar (names are up for debate). Lots of things need a general-purpose color type. It would make things easier both in .NET itself and in user-made .NET programs for .NET to have a general-purpose color type.

For concerns about how we can't make a solution general enough to satisfy all use cases, I still disagree that we need to do this - if it satisfies simple use cases such as the ones inside .NET itself and the ones in programs such as Unity and Godot and Stride, that's plenty good, and programs such as Paint.NET that need more specialization can continue to use their own color types.

For concerns about the details such as which color space to use, I suggest we look at color spaces that existing ones such as System.Drawing.Color and System.Windows.Media.Color use, and use that. We don't need a solution general enough that it has support for different color spaces. Even if an end-user program ends up using a different color space, it can still use the proposed Color type for interoperability with itself, since it's just writing some value defined in one space and reading it as the same space.

For concerns about the proposed Color type being inefficient since it stores 32 bits per channel, 1) there is the proposed Color8 type available (which could be renamed to Color if we decide that), and 2) per the above comment, it's more efficient than the existing System.Drawing.Color which needs to be replaced.

tannergooding commented 2 years ago

We are going with the approach described in https://github.com/dotnet/runtime/issues/48615 instead.

There will be very basic interchange types covering two of the most common formats (Argb<T> and Rgba<T>) and that are inline with the general SIMD accelerated/Graphics oriented types already exposed by System.Numerics and that are inline with what similar libraries (DX Math, GL Math, XNA, MonoGame, etc) have exposed.

At most, there may be a few simple SIMD accelerated operations in the future for the core APIs that the same similar libraries expose. This would include basic vector ops, an interpolate, adjust contrast, and adjust saturation function, plus basic conversion to/from the "core" color spaces (sRGB - IEC 61966-2-1:1999, CIE XYZ, IUT-R BT.601/CCIR 601, IUT-R BT.709, and IUT-R BT.2020)

Some of these are iffy and if you want more extensive functionality you could build it on top of these interchange types and/or use a more advanced and dedicated Image Processing library. We explicitly want to keep this scoped down and to only cover the core needs.

tannergooding commented 2 years ago

Going to close this one since #48615 is the direction we're taking.