diff --git a/xep-0392.xml b/xep-0392.xml new file mode 100644 index 00000000..56b25f99 --- /dev/null +++ b/xep-0392.xml @@ -0,0 +1,288 @@ + + +%ents; + Red/Green-Blindness"> + Blue-Blindness"> + + +]> + + +
+ Consistent Color Generation + This specification provides a set of algorithms to consistently generate colors given a string. The string can be a nickname, a JID or any other piece of information. All entities adhering to this specification generate the same color for the same string, which provides a consistent user experience across platforms. + &LEGALNOTICE; + 0392 + Experimental + Standards Track + Standards + Council + + + + colors + + Jonas + Wielicki + jonas@wielicki.name + jonas@wielicki.name + + + 0.1 + 2017-09-27 + XEP Editor: jwi +

Accepted as Experimental by Council.

+
+ + 0.0.1 + 2017-09-14 + jwi +

First draft.

+
+
+ +

Colors provide a valuable visual cue to recognize text. Recognition of colors works much faster than recognition of text. Together with the length and overall shape of a piece of text (such as a nickname), a color provides a decent amount of entropy to distinguish a reasonable amount of entities.

+
+ +

The color generation mechanism should provide the following features:

+ +
+ + +

To generate a color from a string of text, the follownig algorithms are applied in order:

+
    +
  1. Generate an angle in the CbCr plane from the text.
  2. +
  3. If enabled, apply configured corrections for &cvds;.
  4. +
  5. Convert the angle to a CbCr pair.
  6. +
  7. If the output device only supports a small palette of colors, map the CbCr value to the closest palette color.
  8. +
  9. If the output device supports RGB output, convert the CbCr pair to an RGB triple.
  10. +
+
+ +

Implementations may colorize the participants of a conversation with an individual color to make them easier to distinguish.

+

In such cases, the color SHOULD be generated as described in the Generating a color section. The input used SHOULD be, in descending order of preference, (a) the name assigned in the roster, (b) the nickname from the conversation, (c) the bare JID.

+
+ +

Implementations may want to show a picture in connection with a contact even if the contact does not have an avatar defined (e.g. via &xep0084;).

+

In such cases, auto-generating an avatar SHOULD happen as follows:

+
    +
  1. Obtain a name for the contact, in descending order of preference, (a) from the roster, (b) by using the nickname from the conversation, (c) by using the bare JID.
  2. +
  3. Generate a color as described in the Generating a color section.
  4. +
  5. Fill an implementation-defined background shape with that color.
  6. +
  7. Render the first character of the name in white or black centered on the square.
  8. +
+
+
+ + + + + +

Input: An identifier, encoded as octets of UTF-8 (&rfc3269;).

+

Output: Angle in the CbCr plane.

+

Note: The goal of this algorithm is to convert arbitrary text into a scalar value which can then be used to calculate a color. As it happens, the CbCr plane of the YCbCr space determines the color (while Y merely defines the lightness); thus, an angle in the CbCr plane serves as a good scalar value to select a color.

+
    +
  1. Run the input through CRC32 as defined by zlib (TODO: add citation).
  2. +
  3. Take the lower 16 bits and XOR them with the upper 16 bits.
  4. +
  5. Divide the value by 65535 (use float division) and multiply it by 2π (two Pi).
  6. +
+
+ +

Input: Angle in the CbCr plane.

+

Output: Angle in the CbCr plane.

+

Note: This algorithm will re-map the angle to map it away from ranges which can not be distinguished by people with the respective &cvds;.

+ +

Divide the angle by two.

+
+ +

Divide the angle by two and add π/2 (half Pi).

+
+
+ +

Input: Angle in the CbCr plane, from the previous algorithm.

+

Output: Values for Cb and Cr in the YCbCr BT.601 color space in the range from -0.5 to 0.5.

+

Form a vector from the angle and project it to edges of a quad in 2D space with edge length 1 around (0, 0). The resulting coordinates are Cb and Cr:

+ abs(cb)) { + factor = 0.5 / abs(cr); +} else { + factor = 0.5 / abs(cb); +} +cb = cb * factor; +cr = cr * factor; +]]> +
+ +

Input: Values for Cb and Cr in the YCbCr BT.601 color space in the range from -0.5 to 0.5; Value for Y.

+

Output: Values for Red (R), Green (G) and Blue (B) in the RGB color space in the range from 0 to 1.

+

Note: The recommended value for Y is 0.732. See Gamma Correction for a discussion on the choice of Y.

+
    +
  1. Calculate r, g and b according to BT.601:
  2. +
  3. Clip the values of r, g and b to the range from 0 to 1.
  4. +
+
+ +

Input: RGB values for the color to adapt (Ri, Gi, Bi) and for the background color to adapt to (Rb, Gb, Bb), in the range from 0 to 1 each.

+

Output: Values for Red (Rc), Green (Gc) and Blue (Bc) in the RGB color space in the range from 0 to 1.

+
    +
  1. Invert the background color by subtracting the individual channels from 1 each: +
  2. +
  3. Mix the inverted background with the color to adapt, using a mixing factor of 0.2: +
  4. +
+
+ +

Input: Values for Red (R), Green (G) and Blue (B) in the RGB color space in the range from 0 to 1.

+

Output: Values for Cb and Cr in the YCbCr BT.601 color space in the range from -0.5 to 0.5; Value for Y.

+

Calculate Y, Cb and Cr according to BT.601:

+ +
+ +

Input: A set of RGB colors (each component from 0 to 1).

+

Output: A mapping from CbCr pairs (each component from -0.5 to 0.5) to RGB colors.

+

Note: when the algorithm finishes, the mapping maps CbCr values (rounded to two decimal places) to the R, G, B triples which come closest to the desired color and lightness.

+
    +
  1. Create an empty mapping M which maps from pairs of CbCr values to quadruples of Y, R, G and B.
  2. +
  3. For each color R, G, B from the input palette: +
      +
    1. Calculate Y, Cb and Cr from R, G, B as described in RGB to YCbCr.
    2. +
    3. Round Cb and Cr to two decimal places as Cb' and Cr'.
    4. +
    5. If the (Cb', Cr') pair is not in the mapping M yet, or if the Y value of the existing entry is farther away from 0.732 than the new Y value, put the Y, R, G, and B values as value for the (Cb', Cr') pair into the mapping.
    6. +
    +
  4. +
  5. Strip the Y values from the values of mapping M.
  6. +
  7. Return M as the result of the algorithm.
  8. +
+
+ +

Input: A set of colors (the palette) as tuples of Cbp and Crp and a color to map to the closest palette color as Cb and Cr value.

+

Output: A palette color as Cbr and Crr values.

+
    +
  1. For each color as pair Cbp, Crp in the palette, calculate the distance metric: D = sqrt((Cbp-Cb)*(Cbp-Cb) + (Crp-Cr)*(Crp-Cr)).
  2. +
  3. Pick the palette color Cbp, Crp with the smallest distance metric D as result color Cbr, Crr.
  4. +
+

Note: the distance metric is simply the euclidian distance in the CbCr plane.

+
+ +

This section holds test vectors for the different configurations. The test vectors are provided as Comma Separated Values. Strings are enclosed by single quotes ('). The first line contains a header. Each row contains, in that order, the original text, the text encoded as UTF-8 as hexadecimal octets, and the Cb, Cr, Red, Green, and Blue values.

+ + + + + + + + + + +

The used palette can be generated by sampling the RGB cube evenly with six samples on each axis (resulting in 216 colors). The resulting palette is commonly known as the palette of so-called "Web Safe" colors.

+ + + + + + + + + +
+
+
+ + +

An implementation may choose a different value for Y depending on whether the sink for the R, G and B values expects Gamma Encoded or Gamma Decoded values. The recommended default of 0.732 is 0.5 to the power of 0.45, that is, a Gamma Encoded 0.5.

+

Modifications to Y SHOULD NOT be used to correct for bright/dark backgrounds. Implementations SHOULD instead use the algorithm described in Adapting the Color for specific Background Colors for that.

+
+
+ +

As outlined above, implementations MUST offer the &rgblind; and &bblind; corrections as defined in the Corrections for &cvds; section. Users MUST be allowed to choose between:

+ +

The last option is important for users with monochromatic view.

+

Some sources on the internet indicate that people with &cvds; may profit from having larger areas of color to be able to recognize them. This should be taken into consideration when selecting font weights and line widths for colored parts.

+
+ +

This specification extracts a bit more information from an entity and shows it alongside the existing information to the user. As the algorithm is likely to produce different colors for look-alikes (see &xep0165; for examples) in JIDs, it may add additional protection against attacks based on those.

+

Due to the limited set of distinguishable colors, possible &cvds; and/or use of palettes, entities MUST NOT rely on colors being unique in any context.

+
+ +

This section provides an overview of design considerations made while writing this specification. It shows alternatives which have been considered, and eventually rejected.

+ +

The other common YCbCr variants, BT.709 and BT.2020, do not achieve a brightness across the color space as uniform as BT.601 does. Adapting the Y value for uniform luminosity across the range for CbCr would have complicated the algorithm with little or no gain.

+
+ +

The HSV and HSL color spaces fail to provide uniform luminosity with fixed value/lightness and saturation parameters. Adapting those parameters for uniform luminosity across the hue range would have complicated the algorithm with litte to no gain.

+
+ +

Given a fixed-size and finite palette of colors, it would be possible to ensure that, until the number of entities to color exceeds the number of colors, no color collisions happen.

+

There are issues with this approach when the set of entities is dynamic. In such cases, it is possible that an entity changes its associated color (for example by re-joining a colored group chat), which defeats the original purpose.

+

In addition, more state needs to be taken into account, increasing the complexity of choosing a color.

+
+ +

This specification needs to collapse an arbitrarily long string into just a few bits (the angle in the CbCr plane). To do so, a CRC32 sum is used.

+

An alternative, which may yield better distribution of colors, would have been to use a cryptographic hash function. However, the performance and implementation cost for a cryptographic hash function is considerable compared with a simple CRC32, especially on small (less than 1 kiB) inputs.

+
+
+ +

This document requires no interaction with &IANA;.

+
+ +

This document requires no interaction with the ®ISTRAR;.

+
+ +

Thanks to Daniel Gultsch, Georg Lukas, and Tobias Markmann.

+
+
diff --git a/xep.ent b/xep.ent index e1ec9c6a..74f3b71f 100644 --- a/xep.ent +++ b/xep.ent @@ -1447,3 +1447,4 @@ IANA Service Location Protocol, Version 2 (SLPv2) Templates Extensible In-Band Registration (XEP-0389) XEP-0389: Extensible In-Band Registration <https://xmpp.org/extensions/xep-0389.html>." > Entity Capabilities 2.0 (XEP-0390) XEP-0390: Entity Capabilities 2.0 <https://xmpp.org/extensions/xep-0390.html>." > Jingle Encrypted Transports (XEP-0391) XEP-0391: Jingle Encrypted Transports <https://xmpp.org/extensions/xep-0391.html>." > +Consistent Color Generation (XEP-0392) XEP-0392: Consistent Color Generation <https://xmpp.org/extensions/xep-0392.html>." >