From bedc44b1598a4cd26d5a729d58d53f80de25c959 Mon Sep 17 00:00:00 2001 From: Jonas Wielicki Date: Mon, 13 Nov 2017 17:30:46 +0100 Subject: [PATCH] XEP-0392: update to 0.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix angle generation algorithm which wasn’t updated to use SHA-1 after switching - Re-work palette mapping after implementation experience in poezio. --- xep-0392.xml | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/xep-0392.xml b/xep-0392.xml index 6774dc3a..27c86721 100644 --- a/xep-0392.xml +++ b/xep-0392.xml @@ -28,6 +28,15 @@ jonas@wielicki.name jonas@wielicki.name + + 0.3 + 2017-11-13 + jwi +

+ Fix wording in angle generation section which did still use CRC32. + Rework palette mapping after with implementation experience. +

+
0.2 2017-10-04 @@ -53,7 +62,7 @@ -

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.

+

Colors provide a valuable visual cue to recognize shapes. 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, without having to actually read the text.

Clients have been using randomly or deterministically chosen colors for users in multi-user situations for a long time already. However, since there has been no standard for how this is implemented, the experience differs across platforms. The goal of this XEP is to provide a uniform, platform-independent, stateless and easy-to-implement way to map arbitrary bytestrings to colors, as well as give recommendations how this is applied to color names of participants in conversations, roster entries and other pieces of text.

To allow cross-client use, it is important that the color scheme can be adapted to different environments. This specification provides means to adapt colors to different background colors as well as &cvds;.

In no way is the system presented in this specification a replacement for names. It only serves as an additional visual aid.

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

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. Run the input through SHA-1 (&rfc3174;) as defined by zlib (TODO: add citation).
  6. +
  7. Extract the first 16 bits.
  8. Divide the value by 65535 (use float division) and multiply it by 2π (two Pi).
@@ -182,29 +190,42 @@ cr = (r - y) / (1 - KR) / 2

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.

+

Output: A mapping from angles (from 0 to 2π) to RGB colors.

+

Note: when the algorithm finishes, the mapping maps angles (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. 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. +
    7. Convert Cb and Cr to an angle:

      + 0: + cr /= magn + cb /= magn +angle = atan2(cr, cb) % (2*pi) +]]> +

      Here, % is the floating point modulo operator. Since atan2 may return negative values, it is used to put the values into the range from 0 to 2π. ** is the exponentiation operator (cb**2 is thus cb squared).

      +
    8. +
    9. Round the angle to two digits behind the decimal point.
    10. +
    11. If the angle 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 angle into the mapping.
  3. Strip the Y values from the values of mapping M.
  4. Return M as the result of the algorithm.
+

Implementations are free to choose a representation for palette colors different from R, G, B triplets. The exact representation does not matter, as long as it can be converted to an angle in the CbCr plane accordingly.

-

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.

+

Input: (a) A mapping which maps angles to R, G, B triplets and (b) a color to map to the closest palette color as angle alpha.

+

Output: A palette color as R, G, B triplet.

+

Note: See Conversion of an RGB color palette to a CbCr color palette on how to convert an R, G, B triplet or a CbCr pair to an angle.

    -
  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. +
  5. First, check if alpha rounded to two places behind the decimal point has an exact match in the mapping. If so, return that match immediately.
  6. +
  7. For each angle beta in the palette, calculate the distance metric: D = min((alpha - beta) % (2*pi), (beta - alpha) % (2*pi)).
  8. +
  9. Return the R, G, B triplet associated with the angle with the smallest distance metric D.
-

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

+

Implementations are free to choose a representation for palette colors different from R, G, B triplets. The exact representation does not matter, as long as it can be converted to an angle in the CbCr plane accordingly.