[PATCH] Parse the color management parts of the EDID

Richard Hughes hughsient at gmail.com
Thu May 2 14:07:48 PDT 2013


edid.[c|h] is actually what I had initially, want me to do something
like that? Something like a:

struct edid_info;
int edid_parse(struct edid_info *info, const uint8_t *data, size_t length);

Richard

On 2 May 2013 21:57, John Kåre Alsaker <john.kare.alsaker at gmail.com> wrote:
> EDID parsing should probably be moved out of compositor-drm since other
> backends can provide EDIDs too.
>
>
> On Thu, May 2, 2013 at 10:38 PM, Richard Hughes <hughsient at gmail.com> wrote:
>>
>> This code was originally written by Soren Sandmann <sandmann at redhat.com>
>> and was
>> found here: http://people.gnome.org/~ssp/randr/edid-parse.c
>>
>> The code has been in use in gnome-settings-daemon for a couple of years
>> now and
>> is used to generate an Auto-EDID ICC profile if the screen has not been
>> profiled
>> with a calibration device.
>>
>> This will be used by the CMS plugins in the future, and so it makes sense
>> being
>> common code in compositor-drm.
>> ---
>>  src/compositor-drm.c | 56
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 56 insertions(+)
>>
>> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
>> index f39096e..e4a1919 100644
>> --- a/src/compositor-drm.c
>> +++ b/src/compositor-drm.c
>> @@ -136,11 +136,22 @@ struct drm_fb {
>>         void *map;
>>  };
>>
>> +struct drm_color_Yxy {
>> +       double Y;
>> +       double x;
>> +       double y;
>> +};
>> +
>>  struct drm_edid {
>>         char eisa_id[13];
>>         char monitor_name[13];
>>         char pnp_id[5];
>>         char serial_number[13];
>> +       struct drm_color_Yxy whitepoint;
>> +       struct drm_color_Yxy primary_red;
>> +       struct drm_color_Yxy primary_green;
>> +       struct drm_color_Yxy primary_blue;
>> +       double gamma;
>>  };
>>
>>  struct drm_output {
>> @@ -1558,6 +1569,31 @@ edid_parse_string(const uint8_t *data, char text[])
>>  #define EDID_OFFSET_SERIAL                             0x0c
>>
>>  static int
>> +edid_get_bit(int in, int bit)
>> +{
>> +       return (in & (1 << bit)) >> bit;
>> +}
>> +
>> +static int
>> +edid_get_bits(int in, int begin, int end)
>> +{
>> +       int mask = (1 << (end - begin + 1)) - 1;
>> +       return (in >> begin) & mask;
>> +}
>> +
>> +static double
>> +edid_decode_fraction(int high, int low)
>> +{
>> +       double result = 0.0;
>> +       int i;
>> +
>> +       high = (high << 2) | low;
>> +       for (i = 0; i < 10; ++i)
>> +               result += edid_get_bit(high, i) * pow(2, i - 10);
>> +       return result;
>> +}
>> +
>> +static int
>>  edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length)
>>  {
>>         int i;
>> @@ -1579,6 +1615,26 @@ edid_parse(struct drm_edid *edid, const uint8_t
>> *data, size_t length)
>>         edid->pnp_id[2] = 'A' + (data[EDID_OFFSET_PNPID + 1] & 0x1f) - 1;
>>         edid->pnp_id[3] = '\0';
>>
>> +       /* get native gamma */
>> +       if (data[0x17] == 0xff)
>> +               edid->gamma = -1.0;
>> +       else
>> +               edid->gamma = (data[0x17] + 100.0) / 100.0;
>> +
>> +       /* get primaries and whitepoint */
>> +       edid->primary_red.Y = 1.0f;
>> +       edid->primary_red.x = edid_decode_fraction(data[0x1b],
>> edid_get_bits(data[0x19], 6, 7));
>> +       edid->primary_red.y = edid_decode_fraction(data[0x1c],
>> edid_get_bits(data[0x19], 5, 4));
>> +       edid->primary_green.Y = 1.0f;
>> +       edid->primary_green.x = edid_decode_fraction(data[0x1d],
>> edid_get_bits(data[0x19], 2, 3));
>> +       edid->primary_green.y = edid_decode_fraction(data[0x1e],
>> edid_get_bits(data[0x19], 0, 1));
>> +       edid->primary_blue.Y = 1.0f;
>> +       edid->primary_blue.x = edid_decode_fraction(data[0x1f],
>> edid_get_bits(data[0x1a], 6, 7));
>> +       edid->primary_blue.y = edid_decode_fraction(data[0x20],
>> edid_get_bits(data[0x1a], 4, 5));
>> +       edid->whitepoint.Y = 1.0f;
>> +       edid->whitepoint.x = edid_decode_fraction(data[0x21],
>> edid_get_bits(data[0x1a], 2, 3));
>> +       edid->whitepoint.y = edid_decode_fraction(data[0x22],
>> edid_get_bits(data[0x1a], 0, 1));
>> +
>>         /* maybe there isn't a ASCII serial number descriptor, so use this
>> instead */
>>         serial_number = (uint32_t) data[EDID_OFFSET_SERIAL + 0];
>>         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 1] * 0x100;
>> --
>> 1.8.2.1
>>
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
>


More information about the wayland-devel mailing list